ActivityManagerService.java revision 2d7576b082b84068fb9d68419b710b9bec49139b
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33
34import android.Manifest;
35import android.app.AppOpsManager;
36import android.app.ApplicationThreadNative;
37import android.app.IActivityContainer;
38import android.app.IActivityContainerCallback;
39import android.app.IAppTask;
40import android.app.ProfilerInfo;
41import android.app.admin.DevicePolicyManager;
42import android.app.usage.UsageEvents;
43import android.app.usage.UsageStatsManagerInternal;
44import android.appwidget.AppWidgetManager;
45import android.content.res.Resources;
46import android.graphics.Bitmap;
47import android.graphics.Point;
48import android.graphics.Rect;
49import android.os.BatteryStats;
50import android.os.PersistableBundle;
51import android.os.storage.IMountService;
52import android.os.storage.StorageManager;
53import android.service.voice.IVoiceInteractionSession;
54import android.util.ArrayMap;
55import android.util.ArraySet;
56import android.util.SparseIntArray;
57
58import com.android.internal.R;
59import com.android.internal.annotations.GuardedBy;
60import com.android.internal.app.IAppOpsService;
61import com.android.internal.app.IVoiceInteractor;
62import com.android.internal.app.ProcessMap;
63import com.android.internal.app.ProcessStats;
64import com.android.internal.content.PackageMonitor;
65import com.android.internal.os.BackgroundThread;
66import com.android.internal.os.BatteryStatsImpl;
67import com.android.internal.os.ProcessCpuTracker;
68import com.android.internal.os.TransferPipe;
69import com.android.internal.os.Zygote;
70import com.android.internal.util.FastPrintWriter;
71import com.android.internal.util.FastXmlSerializer;
72import com.android.internal.util.MemInfoReader;
73import com.android.internal.util.Preconditions;
74import com.android.server.AppOpsService;
75import com.android.server.AttributeCache;
76import com.android.server.IntentResolver;
77import com.android.server.LocalServices;
78import com.android.server.ServiceThread;
79import com.android.server.SystemService;
80import com.android.server.SystemServiceManager;
81import com.android.server.Watchdog;
82import com.android.server.am.ActivityStack.ActivityState;
83import com.android.server.firewall.IntentFirewall;
84import com.android.server.pm.UserManagerService;
85import com.android.server.wm.AppTransition;
86import com.android.server.wm.WindowManagerService;
87import com.google.android.collect.Lists;
88import com.google.android.collect.Maps;
89
90import libcore.io.IoUtils;
91
92import org.xmlpull.v1.XmlPullParser;
93import org.xmlpull.v1.XmlPullParserException;
94import org.xmlpull.v1.XmlSerializer;
95
96import android.app.Activity;
97import android.app.ActivityManager;
98import android.app.ActivityManager.RunningTaskInfo;
99import android.app.ActivityManager.StackInfo;
100import android.app.ActivityManagerInternal;
101import android.app.ActivityManagerNative;
102import android.app.ActivityOptions;
103import android.app.ActivityThread;
104import android.app.AlertDialog;
105import android.app.AppGlobals;
106import android.app.ApplicationErrorReport;
107import android.app.Dialog;
108import android.app.IActivityController;
109import android.app.IApplicationThread;
110import android.app.IInstrumentationWatcher;
111import android.app.INotificationManager;
112import android.app.IProcessObserver;
113import android.app.IServiceConnection;
114import android.app.IStopUserCallback;
115import android.app.IUiAutomationConnection;
116import android.app.IUserSwitchObserver;
117import android.app.Instrumentation;
118import android.app.Notification;
119import android.app.NotificationManager;
120import android.app.PendingIntent;
121import android.app.backup.IBackupManager;
122import android.content.ActivityNotFoundException;
123import android.content.BroadcastReceiver;
124import android.content.ClipData;
125import android.content.ComponentCallbacks2;
126import android.content.ComponentName;
127import android.content.ContentProvider;
128import android.content.ContentResolver;
129import android.content.Context;
130import android.content.DialogInterface;
131import android.content.IContentProvider;
132import android.content.IIntentReceiver;
133import android.content.IIntentSender;
134import android.content.Intent;
135import android.content.IntentFilter;
136import android.content.IntentSender;
137import android.content.pm.ActivityInfo;
138import android.content.pm.ApplicationInfo;
139import android.content.pm.ConfigurationInfo;
140import android.content.pm.IPackageDataObserver;
141import android.content.pm.IPackageManager;
142import android.content.pm.InstrumentationInfo;
143import android.content.pm.PackageInfo;
144import android.content.pm.PackageManager;
145import android.content.pm.ParceledListSlice;
146import android.content.pm.UserInfo;
147import android.content.pm.PackageManager.NameNotFoundException;
148import android.content.pm.PathPermission;
149import android.content.pm.ProviderInfo;
150import android.content.pm.ResolveInfo;
151import android.content.pm.ServiceInfo;
152import android.content.res.CompatibilityInfo;
153import android.content.res.Configuration;
154import android.net.Proxy;
155import android.net.ProxyInfo;
156import android.net.Uri;
157import android.os.Binder;
158import android.os.Build;
159import android.os.Bundle;
160import android.os.Debug;
161import android.os.DropBoxManager;
162import android.os.Environment;
163import android.os.FactoryTest;
164import android.os.FileObserver;
165import android.os.FileUtils;
166import android.os.Handler;
167import android.os.IBinder;
168import android.os.IPermissionController;
169import android.os.IRemoteCallback;
170import android.os.IUserManager;
171import android.os.Looper;
172import android.os.Message;
173import android.os.Parcel;
174import android.os.ParcelFileDescriptor;
175import android.os.Process;
176import android.os.RemoteCallbackList;
177import android.os.RemoteException;
178import android.os.SELinux;
179import android.os.ServiceManager;
180import android.os.StrictMode;
181import android.os.SystemClock;
182import android.os.SystemProperties;
183import android.os.UpdateLock;
184import android.os.UserHandle;
185import android.os.UserManager;
186import android.provider.Settings;
187import android.text.format.DateUtils;
188import android.text.format.Time;
189import android.util.AtomicFile;
190import android.util.EventLog;
191import android.util.Log;
192import android.util.Pair;
193import android.util.PrintWriterPrinter;
194import android.util.Slog;
195import android.util.SparseArray;
196import android.util.TimeUtils;
197import android.util.Xml;
198import android.view.Gravity;
199import android.view.LayoutInflater;
200import android.view.View;
201import android.view.WindowManager;
202import dalvik.system.VMRuntime;
203
204import java.io.BufferedInputStream;
205import java.io.BufferedOutputStream;
206import java.io.DataInputStream;
207import java.io.DataOutputStream;
208import java.io.File;
209import java.io.FileDescriptor;
210import java.io.FileInputStream;
211import java.io.FileNotFoundException;
212import java.io.FileOutputStream;
213import java.io.IOException;
214import java.io.InputStreamReader;
215import java.io.PrintWriter;
216import java.io.StringWriter;
217import java.lang.ref.WeakReference;
218import java.util.ArrayList;
219import java.util.Arrays;
220import java.util.Collections;
221import java.util.Comparator;
222import java.util.HashMap;
223import java.util.HashSet;
224import java.util.Iterator;
225import java.util.List;
226import java.util.Locale;
227import java.util.Map;
228import java.util.Set;
229import java.util.concurrent.atomic.AtomicBoolean;
230import java.util.concurrent.atomic.AtomicLong;
231
232public final class ActivityManagerService extends ActivityManagerNative
233        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
234
235    private static final String USER_DATA_DIR = "/data/user/";
236    // File that stores last updated system version and called preboot receivers
237    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
238
239    static final String TAG = "ActivityManager";
240    static final String TAG_MU = "ActivityManagerServiceMU";
241    static final boolean DEBUG = false;
242    static final boolean localLOGV = DEBUG;
243    static final boolean DEBUG_BACKUP = localLOGV || false;
244    static final boolean DEBUG_BROADCAST = localLOGV || false;
245    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
246    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
247    static final boolean DEBUG_CLEANUP = localLOGV || false;
248    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
249    static final boolean DEBUG_FOCUS = false;
250    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
251    static final boolean DEBUG_MU = localLOGV || false;
252    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
253    static final boolean DEBUG_LRU = localLOGV || false;
254    static final boolean DEBUG_PAUSE = localLOGV || false;
255    static final boolean DEBUG_POWER = localLOGV || false;
256    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
257    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
258    static final boolean DEBUG_PROCESSES = localLOGV || false;
259    static final boolean DEBUG_PROVIDER = localLOGV || false;
260    static final boolean DEBUG_RESULTS = localLOGV || false;
261    static final boolean DEBUG_SERVICE = localLOGV || false;
262    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
263    static final boolean DEBUG_STACK = localLOGV || false;
264    static final boolean DEBUG_SWITCH = localLOGV || false;
265    static final boolean DEBUG_TASKS = localLOGV || false;
266    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
267    static final boolean DEBUG_TRANSITION = localLOGV || false;
268    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
269    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
270    static final boolean DEBUG_VISBILITY = localLOGV || false;
271    static final boolean DEBUG_PSS = localLOGV || false;
272    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
273    static final boolean DEBUG_RECENTS = localLOGV || false;
274    static final boolean VALIDATE_TOKENS = false;
275    static final boolean SHOW_ACTIVITY_START_TIME = true;
276
277    // Control over CPU and battery monitoring.
278    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
279    static final boolean MONITOR_CPU_USAGE = true;
280    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
281    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
282    static final boolean MONITOR_THREAD_CPU_USAGE = false;
283
284    // The flags that are set for all calls we make to the package manager.
285    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
286
287    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
288
289    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
290
291    // Maximum number recent bitmaps to keep in memory.
292    static final int MAX_RECENT_BITMAPS = 5;
293
294    // Amount of time after a call to stopAppSwitches() during which we will
295    // prevent further untrusted switches from happening.
296    static final long APP_SWITCH_DELAY_TIME = 5*1000;
297
298    // How long we wait for a launched process to attach to the activity manager
299    // before we decide it's never going to come up for real.
300    static final int PROC_START_TIMEOUT = 10*1000;
301
302    // How long we wait for a launched process to attach to the activity manager
303    // before we decide it's never going to come up for real, when the process was
304    // started with a wrapper for instrumentation (such as Valgrind) because it
305    // could take much longer than usual.
306    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
307
308    // How long to wait after going idle before forcing apps to GC.
309    static final int GC_TIMEOUT = 5*1000;
310
311    // The minimum amount of time between successive GC requests for a process.
312    static final int GC_MIN_INTERVAL = 60*1000;
313
314    // The minimum amount of time between successive PSS requests for a process.
315    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
316
317    // The minimum amount of time between successive PSS requests for a process
318    // when the request is due to the memory state being lowered.
319    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
320
321    // The rate at which we check for apps using excessive power -- 15 mins.
322    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
323
324    // The minimum sample duration we will allow before deciding we have
325    // enough data on wake locks to start killing things.
326    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
327
328    // The minimum sample duration we will allow before deciding we have
329    // enough data on CPU usage to start killing things.
330    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
331
332    // How long we allow a receiver to run before giving up on it.
333    static final int BROADCAST_FG_TIMEOUT = 10*1000;
334    static final int BROADCAST_BG_TIMEOUT = 60*1000;
335
336    // How long we wait until we timeout on key dispatching.
337    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
338
339    // How long we wait until we timeout on key dispatching during instrumentation.
340    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
341
342    // Amount of time we wait for observers to handle a user switch before
343    // giving up on them and unfreezing the screen.
344    static final int USER_SWITCH_TIMEOUT = 2*1000;
345
346    // Maximum number of users we allow to be running at a time.
347    static final int MAX_RUNNING_USERS = 3;
348
349    // How long to wait in getAssistContextExtras for the activity and foreground services
350    // to respond with the result.
351    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
352
353    // Maximum number of persisted Uri grants a package is allowed
354    static final int MAX_PERSISTED_URI_GRANTS = 128;
355
356    static final int MY_PID = Process.myPid();
357
358    static final String[] EMPTY_STRING_ARRAY = new String[0];
359
360    // How many bytes to write into the dropbox log before truncating
361    static final int DROPBOX_MAX_SIZE = 256 * 1024;
362
363    // Access modes for handleIncomingUser.
364    static final int ALLOW_NON_FULL = 0;
365    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
366    static final int ALLOW_FULL_ONLY = 2;
367
368    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
369
370    /** All system services */
371    SystemServiceManager mSystemServiceManager;
372
373    /** Run all ActivityStacks through this */
374    ActivityStackSupervisor mStackSupervisor;
375
376    public IntentFirewall mIntentFirewall;
377
378    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
379    // default actuion automatically.  Important for devices without direct input
380    // devices.
381    private boolean mShowDialogs = true;
382
383    BroadcastQueue mFgBroadcastQueue;
384    BroadcastQueue mBgBroadcastQueue;
385    // Convenient for easy iteration over the queues. Foreground is first
386    // so that dispatch of foreground broadcasts gets precedence.
387    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
388
389    BroadcastQueue broadcastQueueForIntent(Intent intent) {
390        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
391        if (DEBUG_BACKGROUND_BROADCAST) {
392            Slog.i(TAG, "Broadcast intent " + intent + " on "
393                    + (isFg ? "foreground" : "background")
394                    + " queue");
395        }
396        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
397    }
398
399    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
400        for (BroadcastQueue queue : mBroadcastQueues) {
401            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
402            if (r != null) {
403                return r;
404            }
405        }
406        return null;
407    }
408
409    /**
410     * Activity we have told the window manager to have key focus.
411     */
412    ActivityRecord mFocusedActivity = null;
413
414    /**
415     * List of intents that were used to start the most recent tasks.
416     */
417    ArrayList<TaskRecord> mRecentTasks;
418    ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
419
420    /**
421     * For addAppTask: cached of the last activity component that was added.
422     */
423    ComponentName mLastAddedTaskComponent;
424
425    /**
426     * For addAppTask: cached of the last activity uid that was added.
427     */
428    int mLastAddedTaskUid;
429
430    /**
431     * For addAppTask: cached of the last ActivityInfo that was added.
432     */
433    ActivityInfo mLastAddedTaskActivity;
434
435    public class PendingAssistExtras extends Binder implements Runnable {
436        public final ActivityRecord activity;
437        public boolean haveResult = false;
438        public Bundle result = null;
439        public PendingAssistExtras(ActivityRecord _activity) {
440            activity = _activity;
441        }
442        @Override
443        public void run() {
444            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
445            synchronized (this) {
446                haveResult = true;
447                notifyAll();
448            }
449        }
450    }
451
452    final ArrayList<PendingAssistExtras> mPendingAssistExtras
453            = new ArrayList<PendingAssistExtras>();
454
455    /**
456     * Process management.
457     */
458    final ProcessList mProcessList = new ProcessList();
459
460    /**
461     * All of the applications we currently have running organized by name.
462     * The keys are strings of the application package name (as
463     * returned by the package manager), and the keys are ApplicationRecord
464     * objects.
465     */
466    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
467
468    /**
469     * Tracking long-term execution of processes to look for abuse and other
470     * bad app behavior.
471     */
472    final ProcessStatsService mProcessStats;
473
474    /**
475     * The currently running isolated processes.
476     */
477    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
478
479    /**
480     * Counter for assigning isolated process uids, to avoid frequently reusing the
481     * same ones.
482     */
483    int mNextIsolatedProcessUid = 0;
484
485    /**
486     * The currently running heavy-weight process, if any.
487     */
488    ProcessRecord mHeavyWeightProcess = null;
489
490    /**
491     * The last time that various processes have crashed.
492     */
493    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
494
495    /**
496     * Information about a process that is currently marked as bad.
497     */
498    static final class BadProcessInfo {
499        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
500            this.time = time;
501            this.shortMsg = shortMsg;
502            this.longMsg = longMsg;
503            this.stack = stack;
504        }
505
506        final long time;
507        final String shortMsg;
508        final String longMsg;
509        final String stack;
510    }
511
512    /**
513     * Set of applications that we consider to be bad, and will reject
514     * incoming broadcasts from (which the user has no control over).
515     * Processes are added to this set when they have crashed twice within
516     * a minimum amount of time; they are removed from it when they are
517     * later restarted (hopefully due to some user action).  The value is the
518     * time it was added to the list.
519     */
520    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
521
522    /**
523     * All of the processes we currently have running organized by pid.
524     * The keys are the pid running the application.
525     *
526     * <p>NOTE: This object is protected by its own lock, NOT the global
527     * activity manager lock!
528     */
529    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
530
531    /**
532     * All of the processes that have been forced to be foreground.  The key
533     * is the pid of the caller who requested it (we hold a death
534     * link on it).
535     */
536    abstract class ForegroundToken implements IBinder.DeathRecipient {
537        int pid;
538        IBinder token;
539    }
540    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
541
542    /**
543     * List of records for processes that someone had tried to start before the
544     * system was ready.  We don't start them at that point, but ensure they
545     * are started by the time booting is complete.
546     */
547    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
548
549    /**
550     * List of persistent applications that are in the process
551     * of being started.
552     */
553    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
554
555    /**
556     * Processes that are being forcibly torn down.
557     */
558    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
559
560    /**
561     * List of running applications, sorted by recent usage.
562     * The first entry in the list is the least recently used.
563     */
564    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
565
566    /**
567     * Where in mLruProcesses that the processes hosting activities start.
568     */
569    int mLruProcessActivityStart = 0;
570
571    /**
572     * Where in mLruProcesses that the processes hosting services start.
573     * This is after (lower index) than mLruProcessesActivityStart.
574     */
575    int mLruProcessServiceStart = 0;
576
577    /**
578     * List of processes that should gc as soon as things are idle.
579     */
580    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
581
582    /**
583     * Processes we want to collect PSS data from.
584     */
585    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
586
587    /**
588     * Last time we requested PSS data of all processes.
589     */
590    long mLastFullPssTime = SystemClock.uptimeMillis();
591
592    /**
593     * If set, the next time we collect PSS data we should do a full collection
594     * with data from native processes and the kernel.
595     */
596    boolean mFullPssPending = false;
597
598    /**
599     * This is the process holding what we currently consider to be
600     * the "home" activity.
601     */
602    ProcessRecord mHomeProcess;
603
604    /**
605     * This is the process holding the activity the user last visited that
606     * is in a different process from the one they are currently in.
607     */
608    ProcessRecord mPreviousProcess;
609
610    /**
611     * The time at which the previous process was last visible.
612     */
613    long mPreviousProcessVisibleTime;
614
615    /**
616     * Which uses have been started, so are allowed to run code.
617     */
618    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
619
620    /**
621     * LRU list of history of current users.  Most recently current is at the end.
622     */
623    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
624
625    /**
626     * Constant array of the users that are currently started.
627     */
628    int[] mStartedUserArray = new int[] { 0 };
629
630    /**
631     * Registered observers of the user switching mechanics.
632     */
633    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
634            = new RemoteCallbackList<IUserSwitchObserver>();
635
636    /**
637     * Currently active user switch.
638     */
639    Object mCurUserSwitchCallback;
640
641    /**
642     * Packages that the user has asked to have run in screen size
643     * compatibility mode instead of filling the screen.
644     */
645    final CompatModePackages mCompatModePackages;
646
647    /**
648     * Set of IntentSenderRecord objects that are currently active.
649     */
650    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
651            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
652
653    /**
654     * Fingerprints (hashCode()) of stack traces that we've
655     * already logged DropBox entries for.  Guarded by itself.  If
656     * something (rogue user app) forces this over
657     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
658     */
659    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
660    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
661
662    /**
663     * Strict Mode background batched logging state.
664     *
665     * The string buffer is guarded by itself, and its lock is also
666     * used to determine if another batched write is already
667     * in-flight.
668     */
669    private final StringBuilder mStrictModeBuffer = new StringBuilder();
670
671    /**
672     * Keeps track of all IIntentReceivers that have been registered for
673     * broadcasts.  Hash keys are the receiver IBinder, hash value is
674     * a ReceiverList.
675     */
676    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
677            new HashMap<IBinder, ReceiverList>();
678
679    /**
680     * Resolver for broadcast intents to registered receivers.
681     * Holds BroadcastFilter (subclass of IntentFilter).
682     */
683    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
684            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
685        @Override
686        protected boolean allowFilterResult(
687                BroadcastFilter filter, List<BroadcastFilter> dest) {
688            IBinder target = filter.receiverList.receiver.asBinder();
689            for (int i=dest.size()-1; i>=0; i--) {
690                if (dest.get(i).receiverList.receiver.asBinder() == target) {
691                    return false;
692                }
693            }
694            return true;
695        }
696
697        @Override
698        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
699            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
700                    || userId == filter.owningUserId) {
701                return super.newResult(filter, match, userId);
702            }
703            return null;
704        }
705
706        @Override
707        protected BroadcastFilter[] newArray(int size) {
708            return new BroadcastFilter[size];
709        }
710
711        @Override
712        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
713            return packageName.equals(filter.packageName);
714        }
715    };
716
717    /**
718     * State of all active sticky broadcasts per user.  Keys are the action of the
719     * sticky Intent, values are an ArrayList of all broadcasted intents with
720     * that action (which should usually be one).  The SparseArray is keyed
721     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
722     * for stickies that are sent to all users.
723     */
724    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
725            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
726
727    final ActiveServices mServices;
728
729    /**
730     * Backup/restore process management
731     */
732    String mBackupAppName = null;
733    BackupRecord mBackupTarget = null;
734
735    final ProviderMap mProviderMap;
736
737    /**
738     * List of content providers who have clients waiting for them.  The
739     * application is currently being launched and the provider will be
740     * removed from this list once it is published.
741     */
742    final ArrayList<ContentProviderRecord> mLaunchingProviders
743            = new ArrayList<ContentProviderRecord>();
744
745    /**
746     * File storing persisted {@link #mGrantedUriPermissions}.
747     */
748    private final AtomicFile mGrantFile;
749
750    /** XML constants used in {@link #mGrantFile} */
751    private static final String TAG_URI_GRANTS = "uri-grants";
752    private static final String TAG_URI_GRANT = "uri-grant";
753    private static final String ATTR_USER_HANDLE = "userHandle";
754    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
755    private static final String ATTR_TARGET_USER_ID = "targetUserId";
756    private static final String ATTR_SOURCE_PKG = "sourcePkg";
757    private static final String ATTR_TARGET_PKG = "targetPkg";
758    private static final String ATTR_URI = "uri";
759    private static final String ATTR_MODE_FLAGS = "modeFlags";
760    private static final String ATTR_CREATED_TIME = "createdTime";
761    private static final String ATTR_PREFIX = "prefix";
762
763    /**
764     * Global set of specific {@link Uri} permissions that have been granted.
765     * This optimized lookup structure maps from {@link UriPermission#targetUid}
766     * to {@link UriPermission#uri} to {@link UriPermission}.
767     */
768    @GuardedBy("this")
769    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
770            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
771
772    public static class GrantUri {
773        public final int sourceUserId;
774        public final Uri uri;
775        public boolean prefix;
776
777        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
778            this.sourceUserId = sourceUserId;
779            this.uri = uri;
780            this.prefix = prefix;
781        }
782
783        @Override
784        public int hashCode() {
785            return toString().hashCode();
786        }
787
788        @Override
789        public boolean equals(Object o) {
790            if (o instanceof GrantUri) {
791                GrantUri other = (GrantUri) o;
792                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
793                        && prefix == other.prefix;
794            }
795            return false;
796        }
797
798        @Override
799        public String toString() {
800            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
801            if (prefix) result += " [prefix]";
802            return result;
803        }
804
805        public String toSafeString() {
806            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
807            if (prefix) result += " [prefix]";
808            return result;
809        }
810
811        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
812            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
813                    ContentProvider.getUriWithoutUserId(uri), false);
814        }
815    }
816
817    CoreSettingsObserver mCoreSettingsObserver;
818
819    /**
820     * Thread-local storage used to carry caller permissions over through
821     * indirect content-provider access.
822     */
823    private class Identity {
824        public int pid;
825        public int uid;
826
827        Identity(int _pid, int _uid) {
828            pid = _pid;
829            uid = _uid;
830        }
831    }
832
833    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
834
835    /**
836     * All information we have collected about the runtime performance of
837     * any user id that can impact battery performance.
838     */
839    final BatteryStatsService mBatteryStatsService;
840
841    /**
842     * Information about component usage
843     */
844    UsageStatsManagerInternal mUsageStatsService;
845
846    /**
847     * Information about and control over application operations
848     */
849    final AppOpsService mAppOpsService;
850
851    /**
852     * Save recent tasks information across reboots.
853     */
854    final TaskPersister mTaskPersister;
855
856    /**
857     * Current configuration information.  HistoryRecord objects are given
858     * a reference to this object to indicate which configuration they are
859     * currently running in, so this object must be kept immutable.
860     */
861    Configuration mConfiguration = new Configuration();
862
863    /**
864     * Current sequencing integer of the configuration, for skipping old
865     * configurations.
866     */
867    int mConfigurationSeq = 0;
868
869    /**
870     * Hardware-reported OpenGLES version.
871     */
872    final int GL_ES_VERSION;
873
874    /**
875     * List of initialization arguments to pass to all processes when binding applications to them.
876     * For example, references to the commonly used services.
877     */
878    HashMap<String, IBinder> mAppBindArgs;
879
880    /**
881     * Temporary to avoid allocations.  Protected by main lock.
882     */
883    final StringBuilder mStringBuilder = new StringBuilder(256);
884
885    /**
886     * Used to control how we initialize the service.
887     */
888    ComponentName mTopComponent;
889    String mTopAction = Intent.ACTION_MAIN;
890    String mTopData;
891    boolean mProcessesReady = false;
892    boolean mSystemReady = false;
893    boolean mBooting = false;
894    boolean mCallFinishBooting = false;
895    boolean mBootAnimationComplete = false;
896    boolean mWaitingUpdate = false;
897    boolean mDidUpdate = false;
898    boolean mOnBattery = false;
899    boolean mLaunchWarningShown = false;
900
901    Context mContext;
902
903    int mFactoryTest;
904
905    boolean mCheckedForSetup;
906
907    /**
908     * The time at which we will allow normal application switches again,
909     * after a call to {@link #stopAppSwitches()}.
910     */
911    long mAppSwitchesAllowedTime;
912
913    /**
914     * This is set to true after the first switch after mAppSwitchesAllowedTime
915     * is set; any switches after that will clear the time.
916     */
917    boolean mDidAppSwitch;
918
919    /**
920     * Last time (in realtime) at which we checked for power usage.
921     */
922    long mLastPowerCheckRealtime;
923
924    /**
925     * Last time (in uptime) at which we checked for power usage.
926     */
927    long mLastPowerCheckUptime;
928
929    /**
930     * Set while we are wanting to sleep, to prevent any
931     * activities from being started/resumed.
932     */
933    private boolean mSleeping = false;
934
935    /**
936     * Set while we are running a voice interaction.  This overrides
937     * sleeping while it is active.
938     */
939    private boolean mRunningVoice = false;
940
941    /**
942     * State of external calls telling us if the device is asleep.
943     */
944    private boolean mWentToSleep = false;
945
946    /**
947     * State of external call telling us if the lock screen is shown.
948     */
949    private boolean mLockScreenShown = false;
950
951    /**
952     * Set if we are shutting down the system, similar to sleeping.
953     */
954    boolean mShuttingDown = false;
955
956    /**
957     * Current sequence id for oom_adj computation traversal.
958     */
959    int mAdjSeq = 0;
960
961    /**
962     * Current sequence id for process LRU updating.
963     */
964    int mLruSeq = 0;
965
966    /**
967     * Keep track of the non-cached/empty process we last found, to help
968     * determine how to distribute cached/empty processes next time.
969     */
970    int mNumNonCachedProcs = 0;
971
972    /**
973     * Keep track of the number of cached hidden procs, to balance oom adj
974     * distribution between those and empty procs.
975     */
976    int mNumCachedHiddenProcs = 0;
977
978    /**
979     * Keep track of the number of service processes we last found, to
980     * determine on the next iteration which should be B services.
981     */
982    int mNumServiceProcs = 0;
983    int mNewNumAServiceProcs = 0;
984    int mNewNumServiceProcs = 0;
985
986    /**
987     * Allow the current computed overall memory level of the system to go down?
988     * This is set to false when we are killing processes for reasons other than
989     * memory management, so that the now smaller process list will not be taken as
990     * an indication that memory is tighter.
991     */
992    boolean mAllowLowerMemLevel = false;
993
994    /**
995     * The last computed memory level, for holding when we are in a state that
996     * processes are going away for other reasons.
997     */
998    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
999
1000    /**
1001     * The last total number of process we have, to determine if changes actually look
1002     * like a shrinking number of process due to lower RAM.
1003     */
1004    int mLastNumProcesses;
1005
1006    /**
1007     * The uptime of the last time we performed idle maintenance.
1008     */
1009    long mLastIdleTime = SystemClock.uptimeMillis();
1010
1011    /**
1012     * Total time spent with RAM that has been added in the past since the last idle time.
1013     */
1014    long mLowRamTimeSinceLastIdle = 0;
1015
1016    /**
1017     * If RAM is currently low, when that horrible situation started.
1018     */
1019    long mLowRamStartTime = 0;
1020
1021    /**
1022     * For reporting to battery stats the current top application.
1023     */
1024    private String mCurResumedPackage = null;
1025    private int mCurResumedUid = -1;
1026
1027    /**
1028     * For reporting to battery stats the apps currently running foreground
1029     * service.  The ProcessMap is package/uid tuples; each of these contain
1030     * an array of the currently foreground processes.
1031     */
1032    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1033            = new ProcessMap<ArrayList<ProcessRecord>>();
1034
1035    /**
1036     * This is set if we had to do a delayed dexopt of an app before launching
1037     * it, to increase the ANR timeouts in that case.
1038     */
1039    boolean mDidDexOpt;
1040
1041    /**
1042     * Set if the systemServer made a call to enterSafeMode.
1043     */
1044    boolean mSafeMode;
1045
1046    String mDebugApp = null;
1047    boolean mWaitForDebugger = false;
1048    boolean mDebugTransient = false;
1049    String mOrigDebugApp = null;
1050    boolean mOrigWaitForDebugger = false;
1051    boolean mAlwaysFinishActivities = false;
1052    IActivityController mController = null;
1053    String mProfileApp = null;
1054    ProcessRecord mProfileProc = null;
1055    String mProfileFile;
1056    ParcelFileDescriptor mProfileFd;
1057    int mSamplingInterval = 0;
1058    boolean mAutoStopProfiler = false;
1059    int mProfileType = 0;
1060    String mOpenGlTraceApp = null;
1061
1062    static class ProcessChangeItem {
1063        static final int CHANGE_ACTIVITIES = 1<<0;
1064        static final int CHANGE_PROCESS_STATE = 1<<1;
1065        int changes;
1066        int uid;
1067        int pid;
1068        int processState;
1069        boolean foregroundActivities;
1070    }
1071
1072    final RemoteCallbackList<IProcessObserver> mProcessObservers
1073            = new RemoteCallbackList<IProcessObserver>();
1074    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1075
1076    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1077            = new ArrayList<ProcessChangeItem>();
1078    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1079            = new ArrayList<ProcessChangeItem>();
1080
1081    /**
1082     * Runtime CPU use collection thread.  This object's lock is used to
1083     * perform synchronization with the thread (notifying it to run).
1084     */
1085    final Thread mProcessCpuThread;
1086
1087    /**
1088     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1089     * Must acquire this object's lock when accessing it.
1090     * NOTE: this lock will be held while doing long operations (trawling
1091     * through all processes in /proc), so it should never be acquired by
1092     * any critical paths such as when holding the main activity manager lock.
1093     */
1094    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1095            MONITOR_THREAD_CPU_USAGE);
1096    final AtomicLong mLastCpuTime = new AtomicLong(0);
1097    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1098
1099    long mLastWriteTime = 0;
1100
1101    /**
1102     * Used to retain an update lock when the foreground activity is in
1103     * immersive mode.
1104     */
1105    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1106
1107    /**
1108     * Set to true after the system has finished booting.
1109     */
1110    boolean mBooted = false;
1111
1112    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1113    int mProcessLimitOverride = -1;
1114
1115    WindowManagerService mWindowManager;
1116
1117    final ActivityThread mSystemThread;
1118
1119    // Holds the current foreground user's id
1120    int mCurrentUserId = 0;
1121    // Holds the target user's id during a user switch
1122    int mTargetUserId = UserHandle.USER_NULL;
1123    // If there are multiple profiles for the current user, their ids are here
1124    // Currently only the primary user can have managed profiles
1125    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1126
1127    /**
1128     * Mapping from each known user ID to the profile group ID it is associated with.
1129     */
1130    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1131
1132    private UserManagerService mUserManager;
1133
1134    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1135        final ProcessRecord mApp;
1136        final int mPid;
1137        final IApplicationThread mAppThread;
1138
1139        AppDeathRecipient(ProcessRecord app, int pid,
1140                IApplicationThread thread) {
1141            if (localLOGV) Slog.v(
1142                TAG, "New death recipient " + this
1143                + " for thread " + thread.asBinder());
1144            mApp = app;
1145            mPid = pid;
1146            mAppThread = thread;
1147        }
1148
1149        @Override
1150        public void binderDied() {
1151            if (localLOGV) Slog.v(
1152                TAG, "Death received in " + this
1153                + " for thread " + mAppThread.asBinder());
1154            synchronized(ActivityManagerService.this) {
1155                appDiedLocked(mApp, mPid, mAppThread);
1156            }
1157        }
1158    }
1159
1160    static final int SHOW_ERROR_MSG = 1;
1161    static final int SHOW_NOT_RESPONDING_MSG = 2;
1162    static final int SHOW_FACTORY_ERROR_MSG = 3;
1163    static final int UPDATE_CONFIGURATION_MSG = 4;
1164    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1165    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1166    static final int SERVICE_TIMEOUT_MSG = 12;
1167    static final int UPDATE_TIME_ZONE = 13;
1168    static final int SHOW_UID_ERROR_MSG = 14;
1169    static final int IM_FEELING_LUCKY_MSG = 15;
1170    static final int PROC_START_TIMEOUT_MSG = 20;
1171    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1172    static final int KILL_APPLICATION_MSG = 22;
1173    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1174    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1175    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1176    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1177    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1178    static final int CLEAR_DNS_CACHE_MSG = 28;
1179    static final int UPDATE_HTTP_PROXY_MSG = 29;
1180    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1181    static final int DISPATCH_PROCESSES_CHANGED = 31;
1182    static final int DISPATCH_PROCESS_DIED = 32;
1183    static final int REPORT_MEM_USAGE_MSG = 33;
1184    static final int REPORT_USER_SWITCH_MSG = 34;
1185    static final int CONTINUE_USER_SWITCH_MSG = 35;
1186    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1187    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1188    static final int PERSIST_URI_GRANTS_MSG = 38;
1189    static final int REQUEST_ALL_PSS_MSG = 39;
1190    static final int START_PROFILES_MSG = 40;
1191    static final int UPDATE_TIME = 41;
1192    static final int SYSTEM_USER_START_MSG = 42;
1193    static final int SYSTEM_USER_CURRENT_MSG = 43;
1194    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1195    static final int FINISH_BOOTING_MSG = 45;
1196    static final int START_USER_SWITCH_MSG = 46;
1197    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1198
1199    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1200    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1201    static final int FIRST_COMPAT_MODE_MSG = 300;
1202    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1203
1204    AlertDialog mUidAlert;
1205    CompatModeDialog mCompatModeDialog;
1206    long mLastMemUsageReportTime = 0;
1207
1208    private LockToAppRequestDialog mLockToAppRequest;
1209
1210    /**
1211     * Flag whether the current user is a "monkey", i.e. whether
1212     * the UI is driven by a UI automation tool.
1213     */
1214    private boolean mUserIsMonkey;
1215
1216    /** Flag whether the device has a Recents UI */
1217    boolean mHasRecents;
1218
1219    /** The dimensions of the thumbnails in the Recents UI. */
1220    int mThumbnailWidth;
1221    int mThumbnailHeight;
1222
1223    final ServiceThread mHandlerThread;
1224    final MainHandler mHandler;
1225
1226    final class MainHandler extends Handler {
1227        public MainHandler(Looper looper) {
1228            super(looper, null, true);
1229        }
1230
1231        @Override
1232        public void handleMessage(Message msg) {
1233            switch (msg.what) {
1234            case SHOW_ERROR_MSG: {
1235                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1236                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1237                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1238                synchronized (ActivityManagerService.this) {
1239                    ProcessRecord proc = (ProcessRecord)data.get("app");
1240                    AppErrorResult res = (AppErrorResult) data.get("result");
1241                    if (proc != null && proc.crashDialog != null) {
1242                        Slog.e(TAG, "App already has crash dialog: " + proc);
1243                        if (res != null) {
1244                            res.set(0);
1245                        }
1246                        return;
1247                    }
1248                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1249                            >= Process.FIRST_APPLICATION_UID
1250                            && proc.pid != MY_PID);
1251                    for (int userId : mCurrentProfileIds) {
1252                        isBackground &= (proc.userId != userId);
1253                    }
1254                    if (isBackground && !showBackground) {
1255                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1256                        if (res != null) {
1257                            res.set(0);
1258                        }
1259                        return;
1260                    }
1261                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1262                        Dialog d = new AppErrorDialog(mContext,
1263                                ActivityManagerService.this, res, proc);
1264                        d.show();
1265                        proc.crashDialog = d;
1266                    } else {
1267                        // The device is asleep, so just pretend that the user
1268                        // saw a crash dialog and hit "force quit".
1269                        if (res != null) {
1270                            res.set(0);
1271                        }
1272                    }
1273                }
1274
1275                ensureBootCompleted();
1276            } break;
1277            case SHOW_NOT_RESPONDING_MSG: {
1278                synchronized (ActivityManagerService.this) {
1279                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1280                    ProcessRecord proc = (ProcessRecord)data.get("app");
1281                    if (proc != null && proc.anrDialog != null) {
1282                        Slog.e(TAG, "App already has anr dialog: " + proc);
1283                        return;
1284                    }
1285
1286                    Intent intent = new Intent("android.intent.action.ANR");
1287                    if (!mProcessesReady) {
1288                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1289                                | Intent.FLAG_RECEIVER_FOREGROUND);
1290                    }
1291                    broadcastIntentLocked(null, null, intent,
1292                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1293                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1294
1295                    if (mShowDialogs) {
1296                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1297                                mContext, proc, (ActivityRecord)data.get("activity"),
1298                                msg.arg1 != 0);
1299                        d.show();
1300                        proc.anrDialog = d;
1301                    } else {
1302                        // Just kill the app if there is no dialog to be shown.
1303                        killAppAtUsersRequest(proc, null);
1304                    }
1305                }
1306
1307                ensureBootCompleted();
1308            } break;
1309            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1310                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1311                synchronized (ActivityManagerService.this) {
1312                    ProcessRecord proc = (ProcessRecord) data.get("app");
1313                    if (proc == null) {
1314                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1315                        break;
1316                    }
1317                    if (proc.crashDialog != null) {
1318                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1319                        return;
1320                    }
1321                    AppErrorResult res = (AppErrorResult) data.get("result");
1322                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1323                        Dialog d = new StrictModeViolationDialog(mContext,
1324                                ActivityManagerService.this, res, proc);
1325                        d.show();
1326                        proc.crashDialog = d;
1327                    } else {
1328                        // The device is asleep, so just pretend that the user
1329                        // saw a crash dialog and hit "force quit".
1330                        res.set(0);
1331                    }
1332                }
1333                ensureBootCompleted();
1334            } break;
1335            case SHOW_FACTORY_ERROR_MSG: {
1336                Dialog d = new FactoryErrorDialog(
1337                    mContext, msg.getData().getCharSequence("msg"));
1338                d.show();
1339                ensureBootCompleted();
1340            } break;
1341            case UPDATE_CONFIGURATION_MSG: {
1342                final ContentResolver resolver = mContext.getContentResolver();
1343                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1344            } break;
1345            case GC_BACKGROUND_PROCESSES_MSG: {
1346                synchronized (ActivityManagerService.this) {
1347                    performAppGcsIfAppropriateLocked();
1348                }
1349            } break;
1350            case WAIT_FOR_DEBUGGER_MSG: {
1351                synchronized (ActivityManagerService.this) {
1352                    ProcessRecord app = (ProcessRecord)msg.obj;
1353                    if (msg.arg1 != 0) {
1354                        if (!app.waitedForDebugger) {
1355                            Dialog d = new AppWaitingForDebuggerDialog(
1356                                    ActivityManagerService.this,
1357                                    mContext, app);
1358                            app.waitDialog = d;
1359                            app.waitedForDebugger = true;
1360                            d.show();
1361                        }
1362                    } else {
1363                        if (app.waitDialog != null) {
1364                            app.waitDialog.dismiss();
1365                            app.waitDialog = null;
1366                        }
1367                    }
1368                }
1369            } break;
1370            case SERVICE_TIMEOUT_MSG: {
1371                if (mDidDexOpt) {
1372                    mDidDexOpt = false;
1373                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1374                    nmsg.obj = msg.obj;
1375                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1376                    return;
1377                }
1378                mServices.serviceTimeout((ProcessRecord)msg.obj);
1379            } break;
1380            case UPDATE_TIME_ZONE: {
1381                synchronized (ActivityManagerService.this) {
1382                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1383                        ProcessRecord r = mLruProcesses.get(i);
1384                        if (r.thread != null) {
1385                            try {
1386                                r.thread.updateTimeZone();
1387                            } catch (RemoteException ex) {
1388                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1389                            }
1390                        }
1391                    }
1392                }
1393            } break;
1394            case CLEAR_DNS_CACHE_MSG: {
1395                synchronized (ActivityManagerService.this) {
1396                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1397                        ProcessRecord r = mLruProcesses.get(i);
1398                        if (r.thread != null) {
1399                            try {
1400                                r.thread.clearDnsCache();
1401                            } catch (RemoteException ex) {
1402                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1403                            }
1404                        }
1405                    }
1406                }
1407            } break;
1408            case UPDATE_HTTP_PROXY_MSG: {
1409                ProxyInfo proxy = (ProxyInfo)msg.obj;
1410                String host = "";
1411                String port = "";
1412                String exclList = "";
1413                Uri pacFileUrl = Uri.EMPTY;
1414                if (proxy != null) {
1415                    host = proxy.getHost();
1416                    port = Integer.toString(proxy.getPort());
1417                    exclList = proxy.getExclusionListAsString();
1418                    pacFileUrl = proxy.getPacFileUrl();
1419                }
1420                synchronized (ActivityManagerService.this) {
1421                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1422                        ProcessRecord r = mLruProcesses.get(i);
1423                        if (r.thread != null) {
1424                            try {
1425                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1426                            } catch (RemoteException ex) {
1427                                Slog.w(TAG, "Failed to update http proxy for: " +
1428                                        r.info.processName);
1429                            }
1430                        }
1431                    }
1432                }
1433            } break;
1434            case SHOW_UID_ERROR_MSG: {
1435                String title = "System UIDs Inconsistent";
1436                String text = "UIDs on the system are inconsistent, you need to wipe your"
1437                        + " data partition or your device will be unstable.";
1438                Log.e(TAG, title + ": " + text);
1439                if (mShowDialogs) {
1440                    // XXX This is a temporary dialog, no need to localize.
1441                    AlertDialog d = new BaseErrorDialog(mContext);
1442                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1443                    d.setCancelable(false);
1444                    d.setTitle(title);
1445                    d.setMessage(text);
1446                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1447                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1448                    mUidAlert = d;
1449                    d.show();
1450                }
1451            } break;
1452            case IM_FEELING_LUCKY_MSG: {
1453                if (mUidAlert != null) {
1454                    mUidAlert.dismiss();
1455                    mUidAlert = null;
1456                }
1457            } break;
1458            case PROC_START_TIMEOUT_MSG: {
1459                if (mDidDexOpt) {
1460                    mDidDexOpt = false;
1461                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1462                    nmsg.obj = msg.obj;
1463                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1464                    return;
1465                }
1466                ProcessRecord app = (ProcessRecord)msg.obj;
1467                synchronized (ActivityManagerService.this) {
1468                    processStartTimedOutLocked(app);
1469                }
1470            } break;
1471            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1472                synchronized (ActivityManagerService.this) {
1473                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1474                }
1475            } break;
1476            case KILL_APPLICATION_MSG: {
1477                synchronized (ActivityManagerService.this) {
1478                    int appid = msg.arg1;
1479                    boolean restart = (msg.arg2 == 1);
1480                    Bundle bundle = (Bundle)msg.obj;
1481                    String pkg = bundle.getString("pkg");
1482                    String reason = bundle.getString("reason");
1483                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1484                            false, UserHandle.USER_ALL, reason);
1485                }
1486            } break;
1487            case FINALIZE_PENDING_INTENT_MSG: {
1488                ((PendingIntentRecord)msg.obj).completeFinalize();
1489            } break;
1490            case POST_HEAVY_NOTIFICATION_MSG: {
1491                INotificationManager inm = NotificationManager.getService();
1492                if (inm == null) {
1493                    return;
1494                }
1495
1496                ActivityRecord root = (ActivityRecord)msg.obj;
1497                ProcessRecord process = root.app;
1498                if (process == null) {
1499                    return;
1500                }
1501
1502                try {
1503                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1504                    String text = mContext.getString(R.string.heavy_weight_notification,
1505                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1506                    Notification notification = new Notification();
1507                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1508                    notification.when = 0;
1509                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1510                    notification.tickerText = text;
1511                    notification.defaults = 0; // please be quiet
1512                    notification.sound = null;
1513                    notification.vibrate = null;
1514                    notification.color = mContext.getResources().getColor(
1515                            com.android.internal.R.color.system_notification_accent_color);
1516                    notification.setLatestEventInfo(context, text,
1517                            mContext.getText(R.string.heavy_weight_notification_detail),
1518                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1519                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1520                                    new UserHandle(root.userId)));
1521
1522                    try {
1523                        int[] outId = new int[1];
1524                        inm.enqueueNotificationWithTag("android", "android", null,
1525                                R.string.heavy_weight_notification,
1526                                notification, outId, root.userId);
1527                    } catch (RuntimeException e) {
1528                        Slog.w(ActivityManagerService.TAG,
1529                                "Error showing notification for heavy-weight app", e);
1530                    } catch (RemoteException e) {
1531                    }
1532                } catch (NameNotFoundException e) {
1533                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1534                }
1535            } break;
1536            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1537                INotificationManager inm = NotificationManager.getService();
1538                if (inm == null) {
1539                    return;
1540                }
1541                try {
1542                    inm.cancelNotificationWithTag("android", null,
1543                            R.string.heavy_weight_notification,  msg.arg1);
1544                } catch (RuntimeException e) {
1545                    Slog.w(ActivityManagerService.TAG,
1546                            "Error canceling notification for service", e);
1547                } catch (RemoteException e) {
1548                }
1549            } break;
1550            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1551                synchronized (ActivityManagerService.this) {
1552                    checkExcessivePowerUsageLocked(true);
1553                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1554                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1555                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1556                }
1557            } break;
1558            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1559                synchronized (ActivityManagerService.this) {
1560                    ActivityRecord ar = (ActivityRecord)msg.obj;
1561                    if (mCompatModeDialog != null) {
1562                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1563                                ar.info.applicationInfo.packageName)) {
1564                            return;
1565                        }
1566                        mCompatModeDialog.dismiss();
1567                        mCompatModeDialog = null;
1568                    }
1569                    if (ar != null && false) {
1570                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1571                                ar.packageName)) {
1572                            int mode = mCompatModePackages.computeCompatModeLocked(
1573                                    ar.info.applicationInfo);
1574                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1575                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1576                                mCompatModeDialog = new CompatModeDialog(
1577                                        ActivityManagerService.this, mContext,
1578                                        ar.info.applicationInfo);
1579                                mCompatModeDialog.show();
1580                            }
1581                        }
1582                    }
1583                }
1584                break;
1585            }
1586            case DISPATCH_PROCESSES_CHANGED: {
1587                dispatchProcessesChanged();
1588                break;
1589            }
1590            case DISPATCH_PROCESS_DIED: {
1591                final int pid = msg.arg1;
1592                final int uid = msg.arg2;
1593                dispatchProcessDied(pid, uid);
1594                break;
1595            }
1596            case REPORT_MEM_USAGE_MSG: {
1597                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1598                Thread thread = new Thread() {
1599                    @Override public void run() {
1600                        final SparseArray<ProcessMemInfo> infoMap
1601                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1602                        for (int i=0, N=memInfos.size(); i<N; i++) {
1603                            ProcessMemInfo mi = memInfos.get(i);
1604                            infoMap.put(mi.pid, mi);
1605                        }
1606                        updateCpuStatsNow();
1607                        synchronized (mProcessCpuTracker) {
1608                            final int N = mProcessCpuTracker.countStats();
1609                            for (int i=0; i<N; i++) {
1610                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1611                                if (st.vsize > 0) {
1612                                    long pss = Debug.getPss(st.pid, null);
1613                                    if (pss > 0) {
1614                                        if (infoMap.indexOfKey(st.pid) < 0) {
1615                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1616                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1617                                            mi.pss = pss;
1618                                            memInfos.add(mi);
1619                                        }
1620                                    }
1621                                }
1622                            }
1623                        }
1624
1625                        long totalPss = 0;
1626                        for (int i=0, N=memInfos.size(); i<N; i++) {
1627                            ProcessMemInfo mi = memInfos.get(i);
1628                            if (mi.pss == 0) {
1629                                mi.pss = Debug.getPss(mi.pid, null);
1630                            }
1631                            totalPss += mi.pss;
1632                        }
1633                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1634                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1635                                if (lhs.oomAdj != rhs.oomAdj) {
1636                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1637                                }
1638                                if (lhs.pss != rhs.pss) {
1639                                    return lhs.pss < rhs.pss ? 1 : -1;
1640                                }
1641                                return 0;
1642                            }
1643                        });
1644
1645                        StringBuilder tag = new StringBuilder(128);
1646                        StringBuilder stack = new StringBuilder(128);
1647                        tag.append("Low on memory -- ");
1648                        appendMemBucket(tag, totalPss, "total", false);
1649                        appendMemBucket(stack, totalPss, "total", true);
1650
1651                        StringBuilder logBuilder = new StringBuilder(1024);
1652                        logBuilder.append("Low on memory:\n");
1653
1654                        boolean firstLine = true;
1655                        int lastOomAdj = Integer.MIN_VALUE;
1656                        for (int i=0, N=memInfos.size(); i<N; i++) {
1657                            ProcessMemInfo mi = memInfos.get(i);
1658
1659                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1660                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1661                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1662                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1663                                if (lastOomAdj != mi.oomAdj) {
1664                                    lastOomAdj = mi.oomAdj;
1665                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1666                                        tag.append(" / ");
1667                                    }
1668                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1669                                        if (firstLine) {
1670                                            stack.append(":");
1671                                            firstLine = false;
1672                                        }
1673                                        stack.append("\n\t at ");
1674                                    } else {
1675                                        stack.append("$");
1676                                    }
1677                                } else {
1678                                    tag.append(" ");
1679                                    stack.append("$");
1680                                }
1681                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1682                                    appendMemBucket(tag, mi.pss, mi.name, false);
1683                                }
1684                                appendMemBucket(stack, mi.pss, mi.name, true);
1685                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1686                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1687                                    stack.append("(");
1688                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1689                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1690                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1691                                            stack.append(":");
1692                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1693                                        }
1694                                    }
1695                                    stack.append(")");
1696                                }
1697                            }
1698
1699                            logBuilder.append("  ");
1700                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1701                            logBuilder.append(' ');
1702                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1703                            logBuilder.append(' ');
1704                            ProcessList.appendRamKb(logBuilder, mi.pss);
1705                            logBuilder.append(" kB: ");
1706                            logBuilder.append(mi.name);
1707                            logBuilder.append(" (");
1708                            logBuilder.append(mi.pid);
1709                            logBuilder.append(") ");
1710                            logBuilder.append(mi.adjType);
1711                            logBuilder.append('\n');
1712                            if (mi.adjReason != null) {
1713                                logBuilder.append("                      ");
1714                                logBuilder.append(mi.adjReason);
1715                                logBuilder.append('\n');
1716                            }
1717                        }
1718
1719                        logBuilder.append("           ");
1720                        ProcessList.appendRamKb(logBuilder, totalPss);
1721                        logBuilder.append(" kB: TOTAL\n");
1722
1723                        long[] infos = new long[Debug.MEMINFO_COUNT];
1724                        Debug.getMemInfo(infos);
1725                        logBuilder.append("  MemInfo: ");
1726                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1727                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1728                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1729                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1730                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1731                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1732                            logBuilder.append("  ZRAM: ");
1733                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1734                            logBuilder.append(" kB RAM, ");
1735                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1736                            logBuilder.append(" kB swap total, ");
1737                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1738                            logBuilder.append(" kB swap free\n");
1739                        }
1740                        Slog.i(TAG, logBuilder.toString());
1741
1742                        StringBuilder dropBuilder = new StringBuilder(1024);
1743                        /*
1744                        StringWriter oomSw = new StringWriter();
1745                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1746                        StringWriter catSw = new StringWriter();
1747                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1748                        String[] emptyArgs = new String[] { };
1749                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1750                        oomPw.flush();
1751                        String oomString = oomSw.toString();
1752                        */
1753                        dropBuilder.append(stack);
1754                        dropBuilder.append('\n');
1755                        dropBuilder.append('\n');
1756                        dropBuilder.append(logBuilder);
1757                        dropBuilder.append('\n');
1758                        /*
1759                        dropBuilder.append(oomString);
1760                        dropBuilder.append('\n');
1761                        */
1762                        StringWriter catSw = new StringWriter();
1763                        synchronized (ActivityManagerService.this) {
1764                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1765                            String[] emptyArgs = new String[] { };
1766                            catPw.println();
1767                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1768                            catPw.println();
1769                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1770                                    false, false, null);
1771                            catPw.println();
1772                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1773                            catPw.flush();
1774                        }
1775                        dropBuilder.append(catSw.toString());
1776                        addErrorToDropBox("lowmem", null, "system_server", null,
1777                                null, tag.toString(), dropBuilder.toString(), null, null);
1778                        //Slog.i(TAG, "Sent to dropbox:");
1779                        //Slog.i(TAG, dropBuilder.toString());
1780                        synchronized (ActivityManagerService.this) {
1781                            long now = SystemClock.uptimeMillis();
1782                            if (mLastMemUsageReportTime < now) {
1783                                mLastMemUsageReportTime = now;
1784                            }
1785                        }
1786                    }
1787                };
1788                thread.start();
1789                break;
1790            }
1791            case START_USER_SWITCH_MSG: {
1792                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1793                break;
1794            }
1795            case REPORT_USER_SWITCH_MSG: {
1796                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1797                break;
1798            }
1799            case CONTINUE_USER_SWITCH_MSG: {
1800                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1801                break;
1802            }
1803            case USER_SWITCH_TIMEOUT_MSG: {
1804                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1805                break;
1806            }
1807            case IMMERSIVE_MODE_LOCK_MSG: {
1808                final boolean nextState = (msg.arg1 != 0);
1809                if (mUpdateLock.isHeld() != nextState) {
1810                    if (DEBUG_IMMERSIVE) {
1811                        final ActivityRecord r = (ActivityRecord) msg.obj;
1812                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1813                    }
1814                    if (nextState) {
1815                        mUpdateLock.acquire();
1816                    } else {
1817                        mUpdateLock.release();
1818                    }
1819                }
1820                break;
1821            }
1822            case PERSIST_URI_GRANTS_MSG: {
1823                writeGrantedUriPermissions();
1824                break;
1825            }
1826            case REQUEST_ALL_PSS_MSG: {
1827                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1828                break;
1829            }
1830            case START_PROFILES_MSG: {
1831                synchronized (ActivityManagerService.this) {
1832                    startProfilesLocked();
1833                }
1834                break;
1835            }
1836            case UPDATE_TIME: {
1837                synchronized (ActivityManagerService.this) {
1838                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1839                        ProcessRecord r = mLruProcesses.get(i);
1840                        if (r.thread != null) {
1841                            try {
1842                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1843                            } catch (RemoteException ex) {
1844                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1845                            }
1846                        }
1847                    }
1848                }
1849                break;
1850            }
1851            case SYSTEM_USER_START_MSG: {
1852                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1853                        Integer.toString(msg.arg1), msg.arg1);
1854                mSystemServiceManager.startUser(msg.arg1);
1855                break;
1856            }
1857            case SYSTEM_USER_CURRENT_MSG: {
1858                mBatteryStatsService.noteEvent(
1859                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1860                        Integer.toString(msg.arg2), msg.arg2);
1861                mBatteryStatsService.noteEvent(
1862                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1863                        Integer.toString(msg.arg1), msg.arg1);
1864                mSystemServiceManager.switchUser(msg.arg1);
1865                mLockToAppRequest.clearPrompt();
1866                break;
1867            }
1868            case ENTER_ANIMATION_COMPLETE_MSG: {
1869                synchronized (ActivityManagerService.this) {
1870                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1871                    if (r != null && r.app != null && r.app.thread != null) {
1872                        try {
1873                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1874                        } catch (RemoteException e) {
1875                        }
1876                    }
1877                }
1878                break;
1879            }
1880            case FINISH_BOOTING_MSG: {
1881                if (msg.arg1 != 0) {
1882                    finishBooting();
1883                }
1884                if (msg.arg2 != 0) {
1885                    enableScreenAfterBoot();
1886                }
1887                break;
1888            }
1889            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1890                try {
1891                    Locale l = (Locale) msg.obj;
1892                    IBinder service = ServiceManager.getService("mount");
1893                    IMountService mountService = IMountService.Stub.asInterface(service);
1894                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1895                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1896                } catch (RemoteException e) {
1897                    Log.e(TAG, "Error storing locale for decryption UI", e);
1898                }
1899                break;
1900            }
1901            }
1902        }
1903    };
1904
1905    static final int COLLECT_PSS_BG_MSG = 1;
1906
1907    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1908        @Override
1909        public void handleMessage(Message msg) {
1910            switch (msg.what) {
1911            case COLLECT_PSS_BG_MSG: {
1912                long start = SystemClock.uptimeMillis();
1913                MemInfoReader memInfo = null;
1914                synchronized (ActivityManagerService.this) {
1915                    if (mFullPssPending) {
1916                        mFullPssPending = false;
1917                        memInfo = new MemInfoReader();
1918                    }
1919                }
1920                if (memInfo != null) {
1921                    updateCpuStatsNow();
1922                    long nativeTotalPss = 0;
1923                    synchronized (mProcessCpuTracker) {
1924                        final int N = mProcessCpuTracker.countStats();
1925                        for (int j=0; j<N; j++) {
1926                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1927                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1928                                // This is definitely an application process; skip it.
1929                                continue;
1930                            }
1931                            synchronized (mPidsSelfLocked) {
1932                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1933                                    // This is one of our own processes; skip it.
1934                                    continue;
1935                                }
1936                            }
1937                            nativeTotalPss += Debug.getPss(st.pid, null);
1938                        }
1939                    }
1940                    memInfo.readMemInfo();
1941                    synchronized (ActivityManagerService.this) {
1942                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1943                                + (SystemClock.uptimeMillis()-start) + "ms");
1944                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1945                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1946                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1947                                        +memInfo.getSlabSizeKb(),
1948                                nativeTotalPss);
1949                    }
1950                }
1951
1952                int i=0, num=0;
1953                long[] tmp = new long[1];
1954                do {
1955                    ProcessRecord proc;
1956                    int procState;
1957                    int pid;
1958                    synchronized (ActivityManagerService.this) {
1959                        if (i >= mPendingPssProcesses.size()) {
1960                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1961                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1962                            mPendingPssProcesses.clear();
1963                            return;
1964                        }
1965                        proc = mPendingPssProcesses.get(i);
1966                        procState = proc.pssProcState;
1967                        if (proc.thread != null && procState == proc.setProcState) {
1968                            pid = proc.pid;
1969                        } else {
1970                            proc = null;
1971                            pid = 0;
1972                        }
1973                        i++;
1974                    }
1975                    if (proc != null) {
1976                        long pss = Debug.getPss(pid, tmp);
1977                        synchronized (ActivityManagerService.this) {
1978                            if (proc.thread != null && proc.setProcState == procState
1979                                    && proc.pid == pid) {
1980                                num++;
1981                                proc.lastPssTime = SystemClock.uptimeMillis();
1982                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1983                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1984                                        + ": " + pss + " lastPss=" + proc.lastPss
1985                                        + " state=" + ProcessList.makeProcStateString(procState));
1986                                if (proc.initialIdlePss == 0) {
1987                                    proc.initialIdlePss = pss;
1988                                }
1989                                proc.lastPss = pss;
1990                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1991                                    proc.lastCachedPss = pss;
1992                                }
1993                            }
1994                        }
1995                    }
1996                } while (true);
1997            }
1998            }
1999        }
2000    };
2001
2002    /**
2003     * Monitor for package changes and update our internal state.
2004     */
2005    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
2006        @Override
2007        public void onPackageRemoved(String packageName, int uid) {
2008            // Remove all tasks with activities in the specified package from the list of recent tasks
2009            final int eventUserId = getChangingUserId();
2010            synchronized (ActivityManagerService.this) {
2011                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2012                    TaskRecord tr = mRecentTasks.get(i);
2013                    if (tr.userId != eventUserId) continue;
2014
2015                    ComponentName cn = tr.intent.getComponent();
2016                    if (cn != null && cn.getPackageName().equals(packageName)) {
2017                        // If the package name matches, remove the task and kill the process
2018                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
2019                    }
2020                }
2021            }
2022        }
2023
2024        @Override
2025        public boolean onPackageChanged(String packageName, int uid, String[] components) {
2026            onPackageModified(packageName);
2027            return true;
2028        }
2029
2030        @Override
2031        public void onPackageModified(String packageName) {
2032            final int eventUserId = getChangingUserId();
2033            final IPackageManager pm = AppGlobals.getPackageManager();
2034            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
2035                    new ArrayList<Pair<Intent, Integer>>();
2036            final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
2037            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
2038            // Copy the list of recent tasks so that we don't hold onto the lock on
2039            // ActivityManagerService for long periods while checking if components exist.
2040            synchronized (ActivityManagerService.this) {
2041                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2042                    TaskRecord tr = mRecentTasks.get(i);
2043                    if (tr.userId != eventUserId) continue;
2044
2045                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
2046                }
2047            }
2048            // Check the recent tasks and filter out all tasks with components that no longer exist.
2049            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
2050                Pair<Intent, Integer> p = recentTaskIntents.get(i);
2051                ComponentName cn = p.first.getComponent();
2052                if (cn != null && cn.getPackageName().equals(packageName)) {
2053                    if (componentsKnownToExist.contains(cn)) {
2054                        // If we know that the component still exists in the package, then skip
2055                        continue;
2056                    }
2057                    try {
2058                        ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId);
2059                        if (info != null) {
2060                            componentsKnownToExist.add(cn);
2061                        } else {
2062                            tasksToRemove.add(p.second);
2063                        }
2064                    } catch (RemoteException e) {
2065                        Log.e(TAG, "Failed to query activity info for component: " + cn, e);
2066                    }
2067                }
2068            }
2069            // Prune all the tasks with removed components from the list of recent tasks
2070            synchronized (ActivityManagerService.this) {
2071                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
2072                    // Remove the task but don't kill the process (since other components in that
2073                    // package may still be running and in the background)
2074                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
2075                }
2076            }
2077        }
2078
2079        @Override
2080        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2081            // Force stop the specified packages
2082            int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
2083            if (packages != null) {
2084                for (String pkg : packages) {
2085                    synchronized (ActivityManagerService.this) {
2086                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
2087                                userId, "finished booting")) {
2088                            return true;
2089                        }
2090                    }
2091                }
2092            }
2093            return false;
2094        }
2095    };
2096
2097    public void setSystemProcess() {
2098        try {
2099            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2100            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2101            ServiceManager.addService("meminfo", new MemBinder(this));
2102            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2103            ServiceManager.addService("dbinfo", new DbBinder(this));
2104            if (MONITOR_CPU_USAGE) {
2105                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2106            }
2107            ServiceManager.addService("permission", new PermissionController(this));
2108
2109            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2110                    "android", STOCK_PM_FLAGS);
2111            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2112
2113            synchronized (this) {
2114                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2115                app.persistent = true;
2116                app.pid = MY_PID;
2117                app.maxAdj = ProcessList.SYSTEM_ADJ;
2118                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2119                mProcessNames.put(app.processName, app.uid, app);
2120                synchronized (mPidsSelfLocked) {
2121                    mPidsSelfLocked.put(app.pid, app);
2122                }
2123                updateLruProcessLocked(app, false, null);
2124                updateOomAdjLocked();
2125            }
2126        } catch (PackageManager.NameNotFoundException e) {
2127            throw new RuntimeException(
2128                    "Unable to find android system package", e);
2129        }
2130    }
2131
2132    public void setWindowManager(WindowManagerService wm) {
2133        mWindowManager = wm;
2134        mStackSupervisor.setWindowManager(wm);
2135    }
2136
2137    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2138        mUsageStatsService = usageStatsManager;
2139    }
2140
2141    public void startObservingNativeCrashes() {
2142        final NativeCrashListener ncl = new NativeCrashListener(this);
2143        ncl.start();
2144    }
2145
2146    public IAppOpsService getAppOpsService() {
2147        return mAppOpsService;
2148    }
2149
2150    static class MemBinder extends Binder {
2151        ActivityManagerService mActivityManagerService;
2152        MemBinder(ActivityManagerService activityManagerService) {
2153            mActivityManagerService = activityManagerService;
2154        }
2155
2156        @Override
2157        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2158            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2159                    != PackageManager.PERMISSION_GRANTED) {
2160                pw.println("Permission Denial: can't dump meminfo from from pid="
2161                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2162                        + " without permission " + android.Manifest.permission.DUMP);
2163                return;
2164            }
2165
2166            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2167        }
2168    }
2169
2170    static class GraphicsBinder extends Binder {
2171        ActivityManagerService mActivityManagerService;
2172        GraphicsBinder(ActivityManagerService activityManagerService) {
2173            mActivityManagerService = activityManagerService;
2174        }
2175
2176        @Override
2177        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2178            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2179                    != PackageManager.PERMISSION_GRANTED) {
2180                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2181                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2182                        + " without permission " + android.Manifest.permission.DUMP);
2183                return;
2184            }
2185
2186            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2187        }
2188    }
2189
2190    static class DbBinder extends Binder {
2191        ActivityManagerService mActivityManagerService;
2192        DbBinder(ActivityManagerService activityManagerService) {
2193            mActivityManagerService = activityManagerService;
2194        }
2195
2196        @Override
2197        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2198            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2199                    != PackageManager.PERMISSION_GRANTED) {
2200                pw.println("Permission Denial: can't dump dbinfo from from pid="
2201                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2202                        + " without permission " + android.Manifest.permission.DUMP);
2203                return;
2204            }
2205
2206            mActivityManagerService.dumpDbInfo(fd, pw, args);
2207        }
2208    }
2209
2210    static class CpuBinder extends Binder {
2211        ActivityManagerService mActivityManagerService;
2212        CpuBinder(ActivityManagerService activityManagerService) {
2213            mActivityManagerService = activityManagerService;
2214        }
2215
2216        @Override
2217        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2218            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2219                    != PackageManager.PERMISSION_GRANTED) {
2220                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2221                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2222                        + " without permission " + android.Manifest.permission.DUMP);
2223                return;
2224            }
2225
2226            synchronized (mActivityManagerService.mProcessCpuTracker) {
2227                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2228                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2229                        SystemClock.uptimeMillis()));
2230            }
2231        }
2232    }
2233
2234    public static final class Lifecycle extends SystemService {
2235        private final ActivityManagerService mService;
2236
2237        public Lifecycle(Context context) {
2238            super(context);
2239            mService = new ActivityManagerService(context);
2240        }
2241
2242        @Override
2243        public void onStart() {
2244            mService.start();
2245        }
2246
2247        public ActivityManagerService getService() {
2248            return mService;
2249        }
2250    }
2251
2252    // Note: This method is invoked on the main thread but may need to attach various
2253    // handlers to other threads.  So take care to be explicit about the looper.
2254    public ActivityManagerService(Context systemContext) {
2255        mContext = systemContext;
2256        mFactoryTest = FactoryTest.getMode();
2257        mSystemThread = ActivityThread.currentActivityThread();
2258
2259        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2260
2261        mHandlerThread = new ServiceThread(TAG,
2262                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2263        mHandlerThread.start();
2264        mHandler = new MainHandler(mHandlerThread.getLooper());
2265
2266        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2267                "foreground", BROADCAST_FG_TIMEOUT, false);
2268        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2269                "background", BROADCAST_BG_TIMEOUT, true);
2270        mBroadcastQueues[0] = mFgBroadcastQueue;
2271        mBroadcastQueues[1] = mBgBroadcastQueue;
2272
2273        mServices = new ActiveServices(this);
2274        mProviderMap = new ProviderMap(this);
2275
2276        // TODO: Move creation of battery stats service outside of activity manager service.
2277        File dataDir = Environment.getDataDirectory();
2278        File systemDir = new File(dataDir, "system");
2279        systemDir.mkdirs();
2280        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2281        mBatteryStatsService.getActiveStatistics().readLocked();
2282        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2283        mOnBattery = DEBUG_POWER ? true
2284                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2285        mBatteryStatsService.getActiveStatistics().setCallback(this);
2286
2287        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2288
2289        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2290
2291        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2292
2293        // User 0 is the first and only user that runs at boot.
2294        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2295        mUserLru.add(Integer.valueOf(0));
2296        updateStartedUserArrayLocked();
2297
2298        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2299            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2300
2301        mConfiguration.setToDefaults();
2302        mConfiguration.setLocale(Locale.getDefault());
2303
2304        mConfigurationSeq = mConfiguration.seq = 1;
2305        mProcessCpuTracker.init();
2306
2307        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2308        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2309        mStackSupervisor = new ActivityStackSupervisor(this);
2310        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2311
2312        mProcessCpuThread = new Thread("CpuTracker") {
2313            @Override
2314            public void run() {
2315                while (true) {
2316                    try {
2317                        try {
2318                            synchronized(this) {
2319                                final long now = SystemClock.uptimeMillis();
2320                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2321                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2322                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2323                                //        + ", write delay=" + nextWriteDelay);
2324                                if (nextWriteDelay < nextCpuDelay) {
2325                                    nextCpuDelay = nextWriteDelay;
2326                                }
2327                                if (nextCpuDelay > 0) {
2328                                    mProcessCpuMutexFree.set(true);
2329                                    this.wait(nextCpuDelay);
2330                                }
2331                            }
2332                        } catch (InterruptedException e) {
2333                        }
2334                        updateCpuStatsNow();
2335                    } catch (Exception e) {
2336                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2337                    }
2338                }
2339            }
2340        };
2341
2342        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2343
2344        Watchdog.getInstance().addMonitor(this);
2345        Watchdog.getInstance().addThread(mHandler);
2346    }
2347
2348    public void setSystemServiceManager(SystemServiceManager mgr) {
2349        mSystemServiceManager = mgr;
2350    }
2351
2352    private void start() {
2353        Process.removeAllProcessGroups();
2354        mProcessCpuThread.start();
2355
2356        mBatteryStatsService.publish(mContext);
2357        mAppOpsService.publish(mContext);
2358        Slog.d("AppOps", "AppOpsService published");
2359        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2360    }
2361
2362    public void initPowerManagement() {
2363        mStackSupervisor.initPowerManagement();
2364        mBatteryStatsService.initPowerManagement();
2365    }
2366
2367    @Override
2368    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2369            throws RemoteException {
2370        if (code == SYSPROPS_TRANSACTION) {
2371            // We need to tell all apps about the system property change.
2372            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2373            synchronized(this) {
2374                final int NP = mProcessNames.getMap().size();
2375                for (int ip=0; ip<NP; ip++) {
2376                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2377                    final int NA = apps.size();
2378                    for (int ia=0; ia<NA; ia++) {
2379                        ProcessRecord app = apps.valueAt(ia);
2380                        if (app.thread != null) {
2381                            procs.add(app.thread.asBinder());
2382                        }
2383                    }
2384                }
2385            }
2386
2387            int N = procs.size();
2388            for (int i=0; i<N; i++) {
2389                Parcel data2 = Parcel.obtain();
2390                try {
2391                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2392                } catch (RemoteException e) {
2393                }
2394                data2.recycle();
2395            }
2396        }
2397        try {
2398            return super.onTransact(code, data, reply, flags);
2399        } catch (RuntimeException e) {
2400            // The activity manager only throws security exceptions, so let's
2401            // log all others.
2402            if (!(e instanceof SecurityException)) {
2403                Slog.wtf(TAG, "Activity Manager Crash", e);
2404            }
2405            throw e;
2406        }
2407    }
2408
2409    void updateCpuStats() {
2410        final long now = SystemClock.uptimeMillis();
2411        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2412            return;
2413        }
2414        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2415            synchronized (mProcessCpuThread) {
2416                mProcessCpuThread.notify();
2417            }
2418        }
2419    }
2420
2421    void updateCpuStatsNow() {
2422        synchronized (mProcessCpuTracker) {
2423            mProcessCpuMutexFree.set(false);
2424            final long now = SystemClock.uptimeMillis();
2425            boolean haveNewCpuStats = false;
2426
2427            if (MONITOR_CPU_USAGE &&
2428                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2429                mLastCpuTime.set(now);
2430                haveNewCpuStats = true;
2431                mProcessCpuTracker.update();
2432                //Slog.i(TAG, mProcessCpu.printCurrentState());
2433                //Slog.i(TAG, "Total CPU usage: "
2434                //        + mProcessCpu.getTotalCpuPercent() + "%");
2435
2436                // Slog the cpu usage if the property is set.
2437                if ("true".equals(SystemProperties.get("events.cpu"))) {
2438                    int user = mProcessCpuTracker.getLastUserTime();
2439                    int system = mProcessCpuTracker.getLastSystemTime();
2440                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2441                    int irq = mProcessCpuTracker.getLastIrqTime();
2442                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2443                    int idle = mProcessCpuTracker.getLastIdleTime();
2444
2445                    int total = user + system + iowait + irq + softIrq + idle;
2446                    if (total == 0) total = 1;
2447
2448                    EventLog.writeEvent(EventLogTags.CPU,
2449                            ((user+system+iowait+irq+softIrq) * 100) / total,
2450                            (user * 100) / total,
2451                            (system * 100) / total,
2452                            (iowait * 100) / total,
2453                            (irq * 100) / total,
2454                            (softIrq * 100) / total);
2455                }
2456            }
2457
2458            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2459            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2460            synchronized(bstats) {
2461                synchronized(mPidsSelfLocked) {
2462                    if (haveNewCpuStats) {
2463                        if (mOnBattery) {
2464                            int perc = bstats.startAddingCpuLocked();
2465                            int totalUTime = 0;
2466                            int totalSTime = 0;
2467                            final int N = mProcessCpuTracker.countStats();
2468                            for (int i=0; i<N; i++) {
2469                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2470                                if (!st.working) {
2471                                    continue;
2472                                }
2473                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2474                                int otherUTime = (st.rel_utime*perc)/100;
2475                                int otherSTime = (st.rel_stime*perc)/100;
2476                                totalUTime += otherUTime;
2477                                totalSTime += otherSTime;
2478                                if (pr != null) {
2479                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2480                                    if (ps == null || !ps.isActive()) {
2481                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2482                                                pr.info.uid, pr.processName);
2483                                    }
2484                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2485                                            st.rel_stime-otherSTime);
2486                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2487                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2488                                } else {
2489                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2490                                    if (ps == null || !ps.isActive()) {
2491                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2492                                                bstats.mapUid(st.uid), st.name);
2493                                    }
2494                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2495                                            st.rel_stime-otherSTime);
2496                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2497                                }
2498                            }
2499                            bstats.finishAddingCpuLocked(perc, totalUTime,
2500                                    totalSTime, cpuSpeedTimes);
2501                        }
2502                    }
2503                }
2504
2505                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2506                    mLastWriteTime = now;
2507                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2508                }
2509            }
2510        }
2511    }
2512
2513    @Override
2514    public void batteryNeedsCpuUpdate() {
2515        updateCpuStatsNow();
2516    }
2517
2518    @Override
2519    public void batteryPowerChanged(boolean onBattery) {
2520        // When plugging in, update the CPU stats first before changing
2521        // the plug state.
2522        updateCpuStatsNow();
2523        synchronized (this) {
2524            synchronized(mPidsSelfLocked) {
2525                mOnBattery = DEBUG_POWER ? true : onBattery;
2526            }
2527        }
2528    }
2529
2530    /**
2531     * Initialize the application bind args. These are passed to each
2532     * process when the bindApplication() IPC is sent to the process. They're
2533     * lazily setup to make sure the services are running when they're asked for.
2534     */
2535    private HashMap<String, IBinder> getCommonServicesLocked() {
2536        if (mAppBindArgs == null) {
2537            mAppBindArgs = new HashMap<String, IBinder>();
2538
2539            // Setup the application init args
2540            mAppBindArgs.put("package", ServiceManager.getService("package"));
2541            mAppBindArgs.put("window", ServiceManager.getService("window"));
2542            mAppBindArgs.put(Context.ALARM_SERVICE,
2543                    ServiceManager.getService(Context.ALARM_SERVICE));
2544        }
2545        return mAppBindArgs;
2546    }
2547
2548    final void setFocusedActivityLocked(ActivityRecord r) {
2549        if (mFocusedActivity != r) {
2550            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2551            mFocusedActivity = r;
2552            if (r.task != null && r.task.voiceInteractor != null) {
2553                startRunningVoiceLocked();
2554            } else {
2555                finishRunningVoiceLocked();
2556            }
2557            mStackSupervisor.setFocusedStack(r);
2558            if (r != null) {
2559                mWindowManager.setFocusedApp(r.appToken, true);
2560            }
2561            applyUpdateLockStateLocked(r);
2562        }
2563    }
2564
2565    final void clearFocusedActivity(ActivityRecord r) {
2566        if (mFocusedActivity == r) {
2567            mFocusedActivity = null;
2568        }
2569    }
2570
2571    @Override
2572    public void setFocusedStack(int stackId) {
2573        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2574        synchronized (ActivityManagerService.this) {
2575            ActivityStack stack = mStackSupervisor.getStack(stackId);
2576            if (stack != null) {
2577                ActivityRecord r = stack.topRunningActivityLocked(null);
2578                if (r != null) {
2579                    setFocusedActivityLocked(r);
2580                }
2581            }
2582        }
2583    }
2584
2585    @Override
2586    public void notifyActivityDrawn(IBinder token) {
2587        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2588        synchronized (this) {
2589            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2590            if (r != null) {
2591                r.task.stack.notifyActivityDrawnLocked(r);
2592            }
2593        }
2594    }
2595
2596    final void applyUpdateLockStateLocked(ActivityRecord r) {
2597        // Modifications to the UpdateLock state are done on our handler, outside
2598        // the activity manager's locks.  The new state is determined based on the
2599        // state *now* of the relevant activity record.  The object is passed to
2600        // the handler solely for logging detail, not to be consulted/modified.
2601        final boolean nextState = r != null && r.immersive;
2602        mHandler.sendMessage(
2603                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2604    }
2605
2606    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2607        Message msg = Message.obtain();
2608        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2609        msg.obj = r.task.askedCompatMode ? null : r;
2610        mHandler.sendMessage(msg);
2611    }
2612
2613    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2614            String what, Object obj, ProcessRecord srcApp) {
2615        app.lastActivityTime = now;
2616
2617        if (app.activities.size() > 0) {
2618            // Don't want to touch dependent processes that are hosting activities.
2619            return index;
2620        }
2621
2622        int lrui = mLruProcesses.lastIndexOf(app);
2623        if (lrui < 0) {
2624            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2625                    + what + " " + obj + " from " + srcApp);
2626            return index;
2627        }
2628
2629        if (lrui >= index) {
2630            // Don't want to cause this to move dependent processes *back* in the
2631            // list as if they were less frequently used.
2632            return index;
2633        }
2634
2635        if (lrui >= mLruProcessActivityStart) {
2636            // Don't want to touch dependent processes that are hosting activities.
2637            return index;
2638        }
2639
2640        mLruProcesses.remove(lrui);
2641        if (index > 0) {
2642            index--;
2643        }
2644        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2645                + " in LRU list: " + app);
2646        mLruProcesses.add(index, app);
2647        return index;
2648    }
2649
2650    final void removeLruProcessLocked(ProcessRecord app) {
2651        int lrui = mLruProcesses.lastIndexOf(app);
2652        if (lrui >= 0) {
2653            if (!app.killed) {
2654                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2655                Process.killProcessQuiet(app.pid);
2656                Process.killProcessGroup(app.info.uid, app.pid);
2657            }
2658            if (lrui <= mLruProcessActivityStart) {
2659                mLruProcessActivityStart--;
2660            }
2661            if (lrui <= mLruProcessServiceStart) {
2662                mLruProcessServiceStart--;
2663            }
2664            mLruProcesses.remove(lrui);
2665        }
2666    }
2667
2668    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2669            ProcessRecord client) {
2670        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2671                || app.treatLikeActivity;
2672        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2673        if (!activityChange && hasActivity) {
2674            // The process has activities, so we are only allowing activity-based adjustments
2675            // to move it.  It should be kept in the front of the list with other
2676            // processes that have activities, and we don't want those to change their
2677            // order except due to activity operations.
2678            return;
2679        }
2680
2681        mLruSeq++;
2682        final long now = SystemClock.uptimeMillis();
2683        app.lastActivityTime = now;
2684
2685        // First a quick reject: if the app is already at the position we will
2686        // put it, then there is nothing to do.
2687        if (hasActivity) {
2688            final int N = mLruProcesses.size();
2689            if (N > 0 && mLruProcesses.get(N-1) == app) {
2690                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2691                return;
2692            }
2693        } else {
2694            if (mLruProcessServiceStart > 0
2695                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2696                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2697                return;
2698            }
2699        }
2700
2701        int lrui = mLruProcesses.lastIndexOf(app);
2702
2703        if (app.persistent && lrui >= 0) {
2704            // We don't care about the position of persistent processes, as long as
2705            // they are in the list.
2706            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2707            return;
2708        }
2709
2710        /* In progress: compute new position first, so we can avoid doing work
2711           if the process is not actually going to move.  Not yet working.
2712        int addIndex;
2713        int nextIndex;
2714        boolean inActivity = false, inService = false;
2715        if (hasActivity) {
2716            // Process has activities, put it at the very tipsy-top.
2717            addIndex = mLruProcesses.size();
2718            nextIndex = mLruProcessServiceStart;
2719            inActivity = true;
2720        } else if (hasService) {
2721            // Process has services, put it at the top of the service list.
2722            addIndex = mLruProcessActivityStart;
2723            nextIndex = mLruProcessServiceStart;
2724            inActivity = true;
2725            inService = true;
2726        } else  {
2727            // Process not otherwise of interest, it goes to the top of the non-service area.
2728            addIndex = mLruProcessServiceStart;
2729            if (client != null) {
2730                int clientIndex = mLruProcesses.lastIndexOf(client);
2731                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2732                        + app);
2733                if (clientIndex >= 0 && addIndex > clientIndex) {
2734                    addIndex = clientIndex;
2735                }
2736            }
2737            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2738        }
2739
2740        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2741                + mLruProcessActivityStart + "): " + app);
2742        */
2743
2744        if (lrui >= 0) {
2745            if (lrui < mLruProcessActivityStart) {
2746                mLruProcessActivityStart--;
2747            }
2748            if (lrui < mLruProcessServiceStart) {
2749                mLruProcessServiceStart--;
2750            }
2751            /*
2752            if (addIndex > lrui) {
2753                addIndex--;
2754            }
2755            if (nextIndex > lrui) {
2756                nextIndex--;
2757            }
2758            */
2759            mLruProcesses.remove(lrui);
2760        }
2761
2762        /*
2763        mLruProcesses.add(addIndex, app);
2764        if (inActivity) {
2765            mLruProcessActivityStart++;
2766        }
2767        if (inService) {
2768            mLruProcessActivityStart++;
2769        }
2770        */
2771
2772        int nextIndex;
2773        if (hasActivity) {
2774            final int N = mLruProcesses.size();
2775            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2776                // Process doesn't have activities, but has clients with
2777                // activities...  move it up, but one below the top (the top
2778                // should always have a real activity).
2779                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2780                mLruProcesses.add(N-1, app);
2781                // To keep it from spamming the LRU list (by making a bunch of clients),
2782                // we will push down any other entries owned by the app.
2783                final int uid = app.info.uid;
2784                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2785                    ProcessRecord subProc = mLruProcesses.get(i);
2786                    if (subProc.info.uid == uid) {
2787                        // We want to push this one down the list.  If the process after
2788                        // it is for the same uid, however, don't do so, because we don't
2789                        // want them internally to be re-ordered.
2790                        if (mLruProcesses.get(i-1).info.uid != uid) {
2791                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2792                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2793                            ProcessRecord tmp = mLruProcesses.get(i);
2794                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2795                            mLruProcesses.set(i-1, tmp);
2796                            i--;
2797                        }
2798                    } else {
2799                        // A gap, we can stop here.
2800                        break;
2801                    }
2802                }
2803            } else {
2804                // Process has activities, put it at the very tipsy-top.
2805                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2806                mLruProcesses.add(app);
2807            }
2808            nextIndex = mLruProcessServiceStart;
2809        } else if (hasService) {
2810            // Process has services, put it at the top of the service list.
2811            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2812            mLruProcesses.add(mLruProcessActivityStart, app);
2813            nextIndex = mLruProcessServiceStart;
2814            mLruProcessActivityStart++;
2815        } else  {
2816            // Process not otherwise of interest, it goes to the top of the non-service area.
2817            int index = mLruProcessServiceStart;
2818            if (client != null) {
2819                // If there is a client, don't allow the process to be moved up higher
2820                // in the list than that client.
2821                int clientIndex = mLruProcesses.lastIndexOf(client);
2822                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2823                        + " when updating " + app);
2824                if (clientIndex <= lrui) {
2825                    // Don't allow the client index restriction to push it down farther in the
2826                    // list than it already is.
2827                    clientIndex = lrui;
2828                }
2829                if (clientIndex >= 0 && index > clientIndex) {
2830                    index = clientIndex;
2831                }
2832            }
2833            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2834            mLruProcesses.add(index, app);
2835            nextIndex = index-1;
2836            mLruProcessActivityStart++;
2837            mLruProcessServiceStart++;
2838        }
2839
2840        // If the app is currently using a content provider or service,
2841        // bump those processes as well.
2842        for (int j=app.connections.size()-1; j>=0; j--) {
2843            ConnectionRecord cr = app.connections.valueAt(j);
2844            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2845                    && cr.binding.service.app != null
2846                    && cr.binding.service.app.lruSeq != mLruSeq
2847                    && !cr.binding.service.app.persistent) {
2848                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2849                        "service connection", cr, app);
2850            }
2851        }
2852        for (int j=app.conProviders.size()-1; j>=0; j--) {
2853            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2854            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2855                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2856                        "provider reference", cpr, app);
2857            }
2858        }
2859    }
2860
2861    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2862        if (uid == Process.SYSTEM_UID) {
2863            // The system gets to run in any process.  If there are multiple
2864            // processes with the same uid, just pick the first (this
2865            // should never happen).
2866            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2867            if (procs == null) return null;
2868            final int N = procs.size();
2869            for (int i = 0; i < N; i++) {
2870                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2871            }
2872        }
2873        ProcessRecord proc = mProcessNames.get(processName, uid);
2874        if (false && proc != null && !keepIfLarge
2875                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2876                && proc.lastCachedPss >= 4000) {
2877            // Turn this condition on to cause killing to happen regularly, for testing.
2878            if (proc.baseProcessTracker != null) {
2879                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2880            }
2881            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2882        } else if (proc != null && !keepIfLarge
2883                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2884                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2885            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2886            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2887                if (proc.baseProcessTracker != null) {
2888                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2889                }
2890                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2891            }
2892        }
2893        return proc;
2894    }
2895
2896    void ensurePackageDexOpt(String packageName) {
2897        IPackageManager pm = AppGlobals.getPackageManager();
2898        try {
2899            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2900                mDidDexOpt = true;
2901            }
2902        } catch (RemoteException e) {
2903        }
2904    }
2905
2906    boolean isNextTransitionForward() {
2907        int transit = mWindowManager.getPendingAppTransition();
2908        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2909                || transit == AppTransition.TRANSIT_TASK_OPEN
2910                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2911    }
2912
2913    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2914            String processName, String abiOverride, int uid, Runnable crashHandler) {
2915        synchronized(this) {
2916            ApplicationInfo info = new ApplicationInfo();
2917            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2918            // For isolated processes, the former contains the parent's uid and the latter the
2919            // actual uid of the isolated process.
2920            // In the special case introduced by this method (which is, starting an isolated
2921            // process directly from the SystemServer without an actual parent app process) the
2922            // closest thing to a parent's uid is SYSTEM_UID.
2923            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2924            // the |isolated| logic in the ProcessRecord constructor.
2925            info.uid = Process.SYSTEM_UID;
2926            info.processName = processName;
2927            info.className = entryPoint;
2928            info.packageName = "android";
2929            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2930                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2931                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2932                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2933                    crashHandler);
2934            return proc != null ? proc.pid : 0;
2935        }
2936    }
2937
2938    final ProcessRecord startProcessLocked(String processName,
2939            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2940            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2941            boolean isolated, boolean keepIfLarge) {
2942        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2943                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2944                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2945                null /* crashHandler */);
2946    }
2947
2948    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2949            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2950            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2951            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2952        long startTime = SystemClock.elapsedRealtime();
2953        ProcessRecord app;
2954        if (!isolated) {
2955            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2956            checkTime(startTime, "startProcess: after getProcessRecord");
2957        } else {
2958            // If this is an isolated process, it can't re-use an existing process.
2959            app = null;
2960        }
2961        // We don't have to do anything more if:
2962        // (1) There is an existing application record; and
2963        // (2) The caller doesn't think it is dead, OR there is no thread
2964        //     object attached to it so we know it couldn't have crashed; and
2965        // (3) There is a pid assigned to it, so it is either starting or
2966        //     already running.
2967        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2968                + " app=" + app + " knownToBeDead=" + knownToBeDead
2969                + " thread=" + (app != null ? app.thread : null)
2970                + " pid=" + (app != null ? app.pid : -1));
2971        if (app != null && app.pid > 0) {
2972            if (!knownToBeDead || app.thread == null) {
2973                // We already have the app running, or are waiting for it to
2974                // come up (we have a pid but not yet its thread), so keep it.
2975                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2976                // If this is a new package in the process, add the package to the list
2977                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2978                checkTime(startTime, "startProcess: done, added package to proc");
2979                return app;
2980            }
2981
2982            // An application record is attached to a previous process,
2983            // clean it up now.
2984            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2985            checkTime(startTime, "startProcess: bad proc running, killing");
2986            Process.killProcessGroup(app.info.uid, app.pid);
2987            handleAppDiedLocked(app, true, true);
2988            checkTime(startTime, "startProcess: done killing old proc");
2989        }
2990
2991        String hostingNameStr = hostingName != null
2992                ? hostingName.flattenToShortString() : null;
2993
2994        if (!isolated) {
2995            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2996                // If we are in the background, then check to see if this process
2997                // is bad.  If so, we will just silently fail.
2998                if (mBadProcesses.get(info.processName, info.uid) != null) {
2999                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3000                            + "/" + info.processName);
3001                    return null;
3002                }
3003            } else {
3004                // When the user is explicitly starting a process, then clear its
3005                // crash count so that we won't make it bad until they see at
3006                // least one crash dialog again, and make the process good again
3007                // if it had been bad.
3008                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3009                        + "/" + info.processName);
3010                mProcessCrashTimes.remove(info.processName, info.uid);
3011                if (mBadProcesses.get(info.processName, info.uid) != null) {
3012                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3013                            UserHandle.getUserId(info.uid), info.uid,
3014                            info.processName);
3015                    mBadProcesses.remove(info.processName, info.uid);
3016                    if (app != null) {
3017                        app.bad = false;
3018                    }
3019                }
3020            }
3021        }
3022
3023        if (app == null) {
3024            checkTime(startTime, "startProcess: creating new process record");
3025            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3026            app.crashHandler = crashHandler;
3027            if (app == null) {
3028                Slog.w(TAG, "Failed making new process record for "
3029                        + processName + "/" + info.uid + " isolated=" + isolated);
3030                return null;
3031            }
3032            mProcessNames.put(processName, app.uid, app);
3033            if (isolated) {
3034                mIsolatedProcesses.put(app.uid, app);
3035            }
3036            checkTime(startTime, "startProcess: done creating new process record");
3037        } else {
3038            // If this is a new package in the process, add the package to the list
3039            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3040            checkTime(startTime, "startProcess: added package to existing proc");
3041        }
3042
3043        // If the system is not ready yet, then hold off on starting this
3044        // process until it is.
3045        if (!mProcessesReady
3046                && !isAllowedWhileBooting(info)
3047                && !allowWhileBooting) {
3048            if (!mProcessesOnHold.contains(app)) {
3049                mProcessesOnHold.add(app);
3050            }
3051            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
3052            checkTime(startTime, "startProcess: returning with proc on hold");
3053            return app;
3054        }
3055
3056        checkTime(startTime, "startProcess: stepping in to startProcess");
3057        startProcessLocked(
3058                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3059        checkTime(startTime, "startProcess: done starting proc!");
3060        return (app.pid != 0) ? app : null;
3061    }
3062
3063    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3064        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3065    }
3066
3067    private final void startProcessLocked(ProcessRecord app,
3068            String hostingType, String hostingNameStr) {
3069        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3070                null /* entryPoint */, null /* entryPointArgs */);
3071    }
3072
3073    private final void startProcessLocked(ProcessRecord app, String hostingType,
3074            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3075        long startTime = SystemClock.elapsedRealtime();
3076        if (app.pid > 0 && app.pid != MY_PID) {
3077            checkTime(startTime, "startProcess: removing from pids map");
3078            synchronized (mPidsSelfLocked) {
3079                mPidsSelfLocked.remove(app.pid);
3080                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3081            }
3082            checkTime(startTime, "startProcess: done removing from pids map");
3083            app.setPid(0);
3084        }
3085
3086        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3087                "startProcessLocked removing on hold: " + app);
3088        mProcessesOnHold.remove(app);
3089
3090        checkTime(startTime, "startProcess: starting to update cpu stats");
3091        updateCpuStats();
3092        checkTime(startTime, "startProcess: done updating cpu stats");
3093
3094        try {
3095            int uid = app.uid;
3096
3097            int[] gids = null;
3098            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3099            if (!app.isolated) {
3100                int[] permGids = null;
3101                try {
3102                    checkTime(startTime, "startProcess: getting gids from package manager");
3103                    final PackageManager pm = mContext.getPackageManager();
3104                    permGids = pm.getPackageGids(app.info.packageName);
3105
3106                    if (Environment.isExternalStorageEmulated()) {
3107                        checkTime(startTime, "startProcess: checking external storage perm");
3108                        if (pm.checkPermission(
3109                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3110                                app.info.packageName) == PERMISSION_GRANTED) {
3111                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3112                        } else {
3113                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3114                        }
3115                    }
3116                } catch (PackageManager.NameNotFoundException e) {
3117                    Slog.w(TAG, "Unable to retrieve gids", e);
3118                }
3119
3120                /*
3121                 * Add shared application and profile GIDs so applications can share some
3122                 * resources like shared libraries and access user-wide resources
3123                 */
3124                if (permGids == null) {
3125                    gids = new int[2];
3126                } else {
3127                    gids = new int[permGids.length + 2];
3128                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3129                }
3130                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3131                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3132            }
3133            checkTime(startTime, "startProcess: building args");
3134            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3135                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3136                        && mTopComponent != null
3137                        && app.processName.equals(mTopComponent.getPackageName())) {
3138                    uid = 0;
3139                }
3140                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3141                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3142                    uid = 0;
3143                }
3144            }
3145            int debugFlags = 0;
3146            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3147                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3148                // Also turn on CheckJNI for debuggable apps. It's quite
3149                // awkward to turn on otherwise.
3150                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3151            }
3152            // Run the app in safe mode if its manifest requests so or the
3153            // system is booted in safe mode.
3154            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3155                mSafeMode == true) {
3156                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3157            }
3158            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3159                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3160            }
3161            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3162                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3163            }
3164            if ("1".equals(SystemProperties.get("debug.assert"))) {
3165                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3166            }
3167
3168            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3169            if (requiredAbi == null) {
3170                requiredAbi = Build.SUPPORTED_ABIS[0];
3171            }
3172
3173            String instructionSet = null;
3174            if (app.info.primaryCpuAbi != null) {
3175                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3176            }
3177
3178            // Start the process.  It will either succeed and return a result containing
3179            // the PID of the new process, or else throw a RuntimeException.
3180            boolean isActivityProcess = (entryPoint == null);
3181            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3182            checkTime(startTime, "startProcess: asking zygote to start proc");
3183            Process.ProcessStartResult startResult = Process.start(entryPoint,
3184                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3185                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3186                    app.info.dataDir, entryPointArgs);
3187            checkTime(startTime, "startProcess: returned from zygote!");
3188
3189            if (app.isolated) {
3190                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3191            }
3192            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3193            checkTime(startTime, "startProcess: done updating battery stats");
3194
3195            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3196                    UserHandle.getUserId(uid), startResult.pid, uid,
3197                    app.processName, hostingType,
3198                    hostingNameStr != null ? hostingNameStr : "");
3199
3200            if (app.persistent) {
3201                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3202            }
3203
3204            checkTime(startTime, "startProcess: building log message");
3205            StringBuilder buf = mStringBuilder;
3206            buf.setLength(0);
3207            buf.append("Start proc ");
3208            buf.append(app.processName);
3209            if (!isActivityProcess) {
3210                buf.append(" [");
3211                buf.append(entryPoint);
3212                buf.append("]");
3213            }
3214            buf.append(" for ");
3215            buf.append(hostingType);
3216            if (hostingNameStr != null) {
3217                buf.append(" ");
3218                buf.append(hostingNameStr);
3219            }
3220            buf.append(": pid=");
3221            buf.append(startResult.pid);
3222            buf.append(" uid=");
3223            buf.append(uid);
3224            buf.append(" gids={");
3225            if (gids != null) {
3226                for (int gi=0; gi<gids.length; gi++) {
3227                    if (gi != 0) buf.append(", ");
3228                    buf.append(gids[gi]);
3229
3230                }
3231            }
3232            buf.append("}");
3233            if (requiredAbi != null) {
3234                buf.append(" abi=");
3235                buf.append(requiredAbi);
3236            }
3237            Slog.i(TAG, buf.toString());
3238            app.setPid(startResult.pid);
3239            app.usingWrapper = startResult.usingWrapper;
3240            app.removed = false;
3241            app.killed = false;
3242            app.killedByAm = false;
3243            checkTime(startTime, "startProcess: starting to update pids map");
3244            synchronized (mPidsSelfLocked) {
3245                this.mPidsSelfLocked.put(startResult.pid, app);
3246                if (isActivityProcess) {
3247                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3248                    msg.obj = app;
3249                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3250                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3251                }
3252            }
3253            checkTime(startTime, "startProcess: done updating pids map");
3254        } catch (RuntimeException e) {
3255            // XXX do better error recovery.
3256            app.setPid(0);
3257            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3258            if (app.isolated) {
3259                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3260            }
3261            Slog.e(TAG, "Failure starting process " + app.processName, e);
3262        }
3263    }
3264
3265    void updateUsageStats(ActivityRecord component, boolean resumed) {
3266        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3267        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3268        if (resumed) {
3269            if (mUsageStatsService != null) {
3270                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3271                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3272            }
3273            synchronized (stats) {
3274                stats.noteActivityResumedLocked(component.app.uid);
3275            }
3276        } else {
3277            if (mUsageStatsService != null) {
3278                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3279                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3280            }
3281            synchronized (stats) {
3282                stats.noteActivityPausedLocked(component.app.uid);
3283            }
3284        }
3285    }
3286
3287    Intent getHomeIntent() {
3288        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3289        intent.setComponent(mTopComponent);
3290        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3291            intent.addCategory(Intent.CATEGORY_HOME);
3292        }
3293        return intent;
3294    }
3295
3296    boolean startHomeActivityLocked(int userId) {
3297        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3298                && mTopAction == null) {
3299            // We are running in factory test mode, but unable to find
3300            // the factory test app, so just sit around displaying the
3301            // error message and don't try to start anything.
3302            return false;
3303        }
3304        Intent intent = getHomeIntent();
3305        ActivityInfo aInfo =
3306            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3307        if (aInfo != null) {
3308            intent.setComponent(new ComponentName(
3309                    aInfo.applicationInfo.packageName, aInfo.name));
3310            // Don't do this if the home app is currently being
3311            // instrumented.
3312            aInfo = new ActivityInfo(aInfo);
3313            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3314            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3315                    aInfo.applicationInfo.uid, true);
3316            if (app == null || app.instrumentationClass == null) {
3317                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3318                mStackSupervisor.startHomeActivity(intent, aInfo);
3319            }
3320        }
3321
3322        return true;
3323    }
3324
3325    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3326        ActivityInfo ai = null;
3327        ComponentName comp = intent.getComponent();
3328        try {
3329            if (comp != null) {
3330                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3331            } else {
3332                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3333                        intent,
3334                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3335                            flags, userId);
3336
3337                if (info != null) {
3338                    ai = info.activityInfo;
3339                }
3340            }
3341        } catch (RemoteException e) {
3342            // ignore
3343        }
3344
3345        return ai;
3346    }
3347
3348    /**
3349     * Starts the "new version setup screen" if appropriate.
3350     */
3351    void startSetupActivityLocked() {
3352        // Only do this once per boot.
3353        if (mCheckedForSetup) {
3354            return;
3355        }
3356
3357        // We will show this screen if the current one is a different
3358        // version than the last one shown, and we are not running in
3359        // low-level factory test mode.
3360        final ContentResolver resolver = mContext.getContentResolver();
3361        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3362                Settings.Global.getInt(resolver,
3363                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3364            mCheckedForSetup = true;
3365
3366            // See if we should be showing the platform update setup UI.
3367            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3368            List<ResolveInfo> ris = mContext.getPackageManager()
3369                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3370
3371            // We don't allow third party apps to replace this.
3372            ResolveInfo ri = null;
3373            for (int i=0; ris != null && i<ris.size(); i++) {
3374                if ((ris.get(i).activityInfo.applicationInfo.flags
3375                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3376                    ri = ris.get(i);
3377                    break;
3378                }
3379            }
3380
3381            if (ri != null) {
3382                String vers = ri.activityInfo.metaData != null
3383                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3384                        : null;
3385                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3386                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3387                            Intent.METADATA_SETUP_VERSION);
3388                }
3389                String lastVers = Settings.Secure.getString(
3390                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3391                if (vers != null && !vers.equals(lastVers)) {
3392                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3393                    intent.setComponent(new ComponentName(
3394                            ri.activityInfo.packageName, ri.activityInfo.name));
3395                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3396                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3397                            null);
3398                }
3399            }
3400        }
3401    }
3402
3403    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3404        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3405    }
3406
3407    void enforceNotIsolatedCaller(String caller) {
3408        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3409            throw new SecurityException("Isolated process not allowed to call " + caller);
3410        }
3411    }
3412
3413    void enforceShellRestriction(String restriction, int userHandle) {
3414        if (Binder.getCallingUid() == Process.SHELL_UID) {
3415            if (userHandle < 0
3416                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3417                throw new SecurityException("Shell does not have permission to access user "
3418                        + userHandle);
3419            }
3420        }
3421    }
3422
3423    @Override
3424    public int getFrontActivityScreenCompatMode() {
3425        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3426        synchronized (this) {
3427            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3428        }
3429    }
3430
3431    @Override
3432    public void setFrontActivityScreenCompatMode(int mode) {
3433        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3434                "setFrontActivityScreenCompatMode");
3435        synchronized (this) {
3436            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3437        }
3438    }
3439
3440    @Override
3441    public int getPackageScreenCompatMode(String packageName) {
3442        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3443        synchronized (this) {
3444            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3445        }
3446    }
3447
3448    @Override
3449    public void setPackageScreenCompatMode(String packageName, int mode) {
3450        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3451                "setPackageScreenCompatMode");
3452        synchronized (this) {
3453            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3454        }
3455    }
3456
3457    @Override
3458    public boolean getPackageAskScreenCompat(String packageName) {
3459        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3460        synchronized (this) {
3461            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3462        }
3463    }
3464
3465    @Override
3466    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3467        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3468                "setPackageAskScreenCompat");
3469        synchronized (this) {
3470            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3471        }
3472    }
3473
3474    private void dispatchProcessesChanged() {
3475        int N;
3476        synchronized (this) {
3477            N = mPendingProcessChanges.size();
3478            if (mActiveProcessChanges.length < N) {
3479                mActiveProcessChanges = new ProcessChangeItem[N];
3480            }
3481            mPendingProcessChanges.toArray(mActiveProcessChanges);
3482            mAvailProcessChanges.addAll(mPendingProcessChanges);
3483            mPendingProcessChanges.clear();
3484            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3485        }
3486
3487        int i = mProcessObservers.beginBroadcast();
3488        while (i > 0) {
3489            i--;
3490            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3491            if (observer != null) {
3492                try {
3493                    for (int j=0; j<N; j++) {
3494                        ProcessChangeItem item = mActiveProcessChanges[j];
3495                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3496                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3497                                    + item.pid + " uid=" + item.uid + ": "
3498                                    + item.foregroundActivities);
3499                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3500                                    item.foregroundActivities);
3501                        }
3502                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3503                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3504                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3505                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3506                        }
3507                    }
3508                } catch (RemoteException e) {
3509                }
3510            }
3511        }
3512        mProcessObservers.finishBroadcast();
3513    }
3514
3515    private void dispatchProcessDied(int pid, int uid) {
3516        int i = mProcessObservers.beginBroadcast();
3517        while (i > 0) {
3518            i--;
3519            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3520            if (observer != null) {
3521                try {
3522                    observer.onProcessDied(pid, uid);
3523                } catch (RemoteException e) {
3524                }
3525            }
3526        }
3527        mProcessObservers.finishBroadcast();
3528    }
3529
3530    @Override
3531    public final int startActivity(IApplicationThread caller, String callingPackage,
3532            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3533            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3534        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3535            resultWho, requestCode, startFlags, profilerInfo, options,
3536            UserHandle.getCallingUserId());
3537    }
3538
3539    @Override
3540    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3541            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3542            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3543        enforceNotIsolatedCaller("startActivity");
3544        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3545                false, ALLOW_FULL_ONLY, "startActivity", null);
3546        // TODO: Switch to user app stacks here.
3547        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3548                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3549                profilerInfo, null, null, options, userId, null, null);
3550    }
3551
3552    @Override
3553    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3554            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3555            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3556
3557        // This is very dangerous -- it allows you to perform a start activity (including
3558        // permission grants) as any app that may launch one of your own activities.  So
3559        // we will only allow this to be done from activities that are part of the core framework,
3560        // and then only when they are running as the system.
3561        final ActivityRecord sourceRecord;
3562        final int targetUid;
3563        final String targetPackage;
3564        synchronized (this) {
3565            if (resultTo == null) {
3566                throw new SecurityException("Must be called from an activity");
3567            }
3568            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3569            if (sourceRecord == null) {
3570                throw new SecurityException("Called with bad activity token: " + resultTo);
3571            }
3572            if (!sourceRecord.info.packageName.equals("android")) {
3573                throw new SecurityException(
3574                        "Must be called from an activity that is declared in the android package");
3575            }
3576            if (sourceRecord.app == null) {
3577                throw new SecurityException("Called without a process attached to activity");
3578            }
3579            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3580                // This is still okay, as long as this activity is running under the
3581                // uid of the original calling activity.
3582                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3583                    throw new SecurityException(
3584                            "Calling activity in uid " + sourceRecord.app.uid
3585                                    + " must be system uid or original calling uid "
3586                                    + sourceRecord.launchedFromUid);
3587                }
3588            }
3589            targetUid = sourceRecord.launchedFromUid;
3590            targetPackage = sourceRecord.launchedFromPackage;
3591        }
3592
3593        // TODO: Switch to user app stacks here.
3594        try {
3595            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3596                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3597                    null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null);
3598            return ret;
3599        } catch (SecurityException e) {
3600            // XXX need to figure out how to propagate to original app.
3601            // A SecurityException here is generally actually a fault of the original
3602            // calling activity (such as a fairly granting permissions), so propagate it
3603            // back to them.
3604            /*
3605            StringBuilder msg = new StringBuilder();
3606            msg.append("While launching");
3607            msg.append(intent.toString());
3608            msg.append(": ");
3609            msg.append(e.getMessage());
3610            */
3611            throw e;
3612        }
3613    }
3614
3615    @Override
3616    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3617            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3618            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3619        enforceNotIsolatedCaller("startActivityAndWait");
3620        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3621                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3622        WaitResult res = new WaitResult();
3623        // TODO: Switch to user app stacks here.
3624        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3625                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3626                options, userId, null, null);
3627        return res;
3628    }
3629
3630    @Override
3631    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3632            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3633            int startFlags, Configuration config, Bundle options, int userId) {
3634        enforceNotIsolatedCaller("startActivityWithConfig");
3635        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3636                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3637        // TODO: Switch to user app stacks here.
3638        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3639                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3640                null, null, config, options, userId, null, null);
3641        return ret;
3642    }
3643
3644    @Override
3645    public int startActivityIntentSender(IApplicationThread caller,
3646            IntentSender intent, Intent fillInIntent, String resolvedType,
3647            IBinder resultTo, String resultWho, int requestCode,
3648            int flagsMask, int flagsValues, Bundle options) {
3649        enforceNotIsolatedCaller("startActivityIntentSender");
3650        // Refuse possible leaked file descriptors
3651        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3652            throw new IllegalArgumentException("File descriptors passed in Intent");
3653        }
3654
3655        IIntentSender sender = intent.getTarget();
3656        if (!(sender instanceof PendingIntentRecord)) {
3657            throw new IllegalArgumentException("Bad PendingIntent object");
3658        }
3659
3660        PendingIntentRecord pir = (PendingIntentRecord)sender;
3661
3662        synchronized (this) {
3663            // If this is coming from the currently resumed activity, it is
3664            // effectively saying that app switches are allowed at this point.
3665            final ActivityStack stack = getFocusedStack();
3666            if (stack.mResumedActivity != null &&
3667                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3668                mAppSwitchesAllowedTime = 0;
3669            }
3670        }
3671        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3672                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3673        return ret;
3674    }
3675
3676    @Override
3677    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3678            Intent intent, String resolvedType, IVoiceInteractionSession session,
3679            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3680            Bundle options, int userId) {
3681        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3682                != PackageManager.PERMISSION_GRANTED) {
3683            String msg = "Permission Denial: startVoiceActivity() from pid="
3684                    + Binder.getCallingPid()
3685                    + ", uid=" + Binder.getCallingUid()
3686                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3687            Slog.w(TAG, msg);
3688            throw new SecurityException(msg);
3689        }
3690        if (session == null || interactor == null) {
3691            throw new NullPointerException("null session or interactor");
3692        }
3693        userId = handleIncomingUser(callingPid, callingUid, userId,
3694                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3695        // TODO: Switch to user app stacks here.
3696        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3697                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3698                null, options, userId, null, null);
3699    }
3700
3701    @Override
3702    public boolean startNextMatchingActivity(IBinder callingActivity,
3703            Intent intent, Bundle options) {
3704        // Refuse possible leaked file descriptors
3705        if (intent != null && intent.hasFileDescriptors() == true) {
3706            throw new IllegalArgumentException("File descriptors passed in Intent");
3707        }
3708
3709        synchronized (this) {
3710            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3711            if (r == null) {
3712                ActivityOptions.abort(options);
3713                return false;
3714            }
3715            if (r.app == null || r.app.thread == null) {
3716                // The caller is not running...  d'oh!
3717                ActivityOptions.abort(options);
3718                return false;
3719            }
3720            intent = new Intent(intent);
3721            // The caller is not allowed to change the data.
3722            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3723            // And we are resetting to find the next component...
3724            intent.setComponent(null);
3725
3726            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3727
3728            ActivityInfo aInfo = null;
3729            try {
3730                List<ResolveInfo> resolves =
3731                    AppGlobals.getPackageManager().queryIntentActivities(
3732                            intent, r.resolvedType,
3733                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3734                            UserHandle.getCallingUserId());
3735
3736                // Look for the original activity in the list...
3737                final int N = resolves != null ? resolves.size() : 0;
3738                for (int i=0; i<N; i++) {
3739                    ResolveInfo rInfo = resolves.get(i);
3740                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3741                            && rInfo.activityInfo.name.equals(r.info.name)) {
3742                        // We found the current one...  the next matching is
3743                        // after it.
3744                        i++;
3745                        if (i<N) {
3746                            aInfo = resolves.get(i).activityInfo;
3747                        }
3748                        if (debug) {
3749                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3750                                    + "/" + r.info.name);
3751                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3752                                    + "/" + aInfo.name);
3753                        }
3754                        break;
3755                    }
3756                }
3757            } catch (RemoteException e) {
3758            }
3759
3760            if (aInfo == null) {
3761                // Nobody who is next!
3762                ActivityOptions.abort(options);
3763                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3764                return false;
3765            }
3766
3767            intent.setComponent(new ComponentName(
3768                    aInfo.applicationInfo.packageName, aInfo.name));
3769            intent.setFlags(intent.getFlags()&~(
3770                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3771                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3772                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3773                    Intent.FLAG_ACTIVITY_NEW_TASK));
3774
3775            // Okay now we need to start the new activity, replacing the
3776            // currently running activity.  This is a little tricky because
3777            // we want to start the new one as if the current one is finished,
3778            // but not finish the current one first so that there is no flicker.
3779            // And thus...
3780            final boolean wasFinishing = r.finishing;
3781            r.finishing = true;
3782
3783            // Propagate reply information over to the new activity.
3784            final ActivityRecord resultTo = r.resultTo;
3785            final String resultWho = r.resultWho;
3786            final int requestCode = r.requestCode;
3787            r.resultTo = null;
3788            if (resultTo != null) {
3789                resultTo.removeResultsLocked(r, resultWho, requestCode);
3790            }
3791
3792            final long origId = Binder.clearCallingIdentity();
3793            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3794                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3795                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3796                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3797            Binder.restoreCallingIdentity(origId);
3798
3799            r.finishing = wasFinishing;
3800            if (res != ActivityManager.START_SUCCESS) {
3801                return false;
3802            }
3803            return true;
3804        }
3805    }
3806
3807    @Override
3808    public final int startActivityFromRecents(int taskId, Bundle options) {
3809        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3810            String msg = "Permission Denial: startActivityFromRecents called without " +
3811                    START_TASKS_FROM_RECENTS;
3812            Slog.w(TAG, msg);
3813            throw new SecurityException(msg);
3814        }
3815        return startActivityFromRecentsInner(taskId, options);
3816    }
3817
3818    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3819        final TaskRecord task;
3820        final int callingUid;
3821        final String callingPackage;
3822        final Intent intent;
3823        final int userId;
3824        synchronized (this) {
3825            task = recentTaskForIdLocked(taskId);
3826            if (task == null) {
3827                throw new IllegalArgumentException("Task " + taskId + " not found.");
3828            }
3829            callingUid = task.mCallingUid;
3830            callingPackage = task.mCallingPackage;
3831            intent = task.intent;
3832            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3833            userId = task.userId;
3834        }
3835        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3836                options, userId, null, task);
3837    }
3838
3839    final int startActivityInPackage(int uid, String callingPackage,
3840            Intent intent, String resolvedType, IBinder resultTo,
3841            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3842            IActivityContainer container, TaskRecord inTask) {
3843
3844        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3845                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3846
3847        // TODO: Switch to user app stacks here.
3848        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3849                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3850                null, null, null, options, userId, container, inTask);
3851        return ret;
3852    }
3853
3854    @Override
3855    public final int startActivities(IApplicationThread caller, String callingPackage,
3856            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3857            int userId) {
3858        enforceNotIsolatedCaller("startActivities");
3859        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3860                false, ALLOW_FULL_ONLY, "startActivity", null);
3861        // TODO: Switch to user app stacks here.
3862        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3863                resolvedTypes, resultTo, options, userId);
3864        return ret;
3865    }
3866
3867    final int startActivitiesInPackage(int uid, String callingPackage,
3868            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3869            Bundle options, int userId) {
3870
3871        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3872                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3873        // TODO: Switch to user app stacks here.
3874        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3875                resultTo, options, userId);
3876        return ret;
3877    }
3878
3879    //explicitly remove thd old information in mRecentTasks when removing existing user.
3880    private void removeRecentTasksForUserLocked(int userId) {
3881        if(userId <= 0) {
3882            Slog.i(TAG, "Can't remove recent task on user " + userId);
3883            return;
3884        }
3885
3886        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3887            TaskRecord tr = mRecentTasks.get(i);
3888            if (tr.userId == userId) {
3889                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3890                        + " when finishing user" + userId);
3891                mRecentTasks.remove(i);
3892                tr.removedFromRecents(mTaskPersister);
3893            }
3894        }
3895
3896        // Remove tasks from persistent storage.
3897        mTaskPersister.wakeup(null, true);
3898    }
3899
3900    // Sort by taskId
3901    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3902        @Override
3903        public int compare(TaskRecord lhs, TaskRecord rhs) {
3904            return rhs.taskId - lhs.taskId;
3905        }
3906    };
3907
3908    // Extract the affiliates of the chain containing mRecentTasks[start].
3909    private int processNextAffiliateChain(int start) {
3910        final TaskRecord startTask = mRecentTasks.get(start);
3911        final int affiliateId = startTask.mAffiliatedTaskId;
3912
3913        // Quick identification of isolated tasks. I.e. those not launched behind.
3914        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3915                startTask.mNextAffiliate == null) {
3916            // There is still a slim chance that there are other tasks that point to this task
3917            // and that the chain is so messed up that this task no longer points to them but
3918            // the gain of this optimization outweighs the risk.
3919            startTask.inRecents = true;
3920            return start + 1;
3921        }
3922
3923        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3924        mTmpRecents.clear();
3925        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3926            final TaskRecord task = mRecentTasks.get(i);
3927            if (task.mAffiliatedTaskId == affiliateId) {
3928                mRecentTasks.remove(i);
3929                mTmpRecents.add(task);
3930            }
3931        }
3932
3933        // Sort them all by taskId. That is the order they were create in and that order will
3934        // always be correct.
3935        Collections.sort(mTmpRecents, mTaskRecordComparator);
3936
3937        // Go through and fix up the linked list.
3938        // The first one is the end of the chain and has no next.
3939        final TaskRecord first = mTmpRecents.get(0);
3940        first.inRecents = true;
3941        if (first.mNextAffiliate != null) {
3942            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3943            first.setNextAffiliate(null);
3944            mTaskPersister.wakeup(first, false);
3945        }
3946        // Everything in the middle is doubly linked from next to prev.
3947        final int tmpSize = mTmpRecents.size();
3948        for (int i = 0; i < tmpSize - 1; ++i) {
3949            final TaskRecord next = mTmpRecents.get(i);
3950            final TaskRecord prev = mTmpRecents.get(i + 1);
3951            if (next.mPrevAffiliate != prev) {
3952                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3953                        " setting prev=" + prev);
3954                next.setPrevAffiliate(prev);
3955                mTaskPersister.wakeup(next, false);
3956            }
3957            if (prev.mNextAffiliate != next) {
3958                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3959                        " setting next=" + next);
3960                prev.setNextAffiliate(next);
3961                mTaskPersister.wakeup(prev, false);
3962            }
3963            prev.inRecents = true;
3964        }
3965        // The last one is the beginning of the list and has no prev.
3966        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3967        if (last.mPrevAffiliate != null) {
3968            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3969            last.setPrevAffiliate(null);
3970            mTaskPersister.wakeup(last, false);
3971        }
3972
3973        // Insert the group back into mRecentTasks at start.
3974        mRecentTasks.addAll(start, mTmpRecents);
3975
3976        // Let the caller know where we left off.
3977        return start + tmpSize;
3978    }
3979
3980    /**
3981     * Update the recent tasks lists: make sure tasks should still be here (their
3982     * applications / activities still exist), update their availability, fixup ordering
3983     * of affiliations.
3984     */
3985    void cleanupRecentTasksLocked(int userId) {
3986        if (mRecentTasks == null) {
3987            // Happens when called from the packagemanager broadcast before boot.
3988            return;
3989        }
3990
3991        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3992        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3993        final IPackageManager pm = AppGlobals.getPackageManager();
3994        final ActivityInfo dummyAct = new ActivityInfo();
3995        final ApplicationInfo dummyApp = new ApplicationInfo();
3996
3997        int N = mRecentTasks.size();
3998
3999        int[] users = userId == UserHandle.USER_ALL
4000                ? getUsersLocked() : new int[] { userId };
4001        for (int user : users) {
4002            for (int i = 0; i < N; i++) {
4003                TaskRecord task = mRecentTasks.get(i);
4004                if (task.userId != user) {
4005                    // Only look at tasks for the user ID of interest.
4006                    continue;
4007                }
4008                if (task.autoRemoveRecents && task.getTopActivity() == null) {
4009                    // This situation is broken, and we should just get rid of it now.
4010                    mRecentTasks.remove(i);
4011                    task.removedFromRecents(mTaskPersister);
4012                    i--;
4013                    N--;
4014                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
4015                    continue;
4016                }
4017                // Check whether this activity is currently available.
4018                if (task.realActivity != null) {
4019                    ActivityInfo ai = availActCache.get(task.realActivity);
4020                    if (ai == null) {
4021                        try {
4022                            ai = pm.getActivityInfo(task.realActivity,
4023                                    PackageManager.GET_UNINSTALLED_PACKAGES
4024                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
4025                        } catch (RemoteException e) {
4026                            // Will never happen.
4027                            continue;
4028                        }
4029                        if (ai == null) {
4030                            ai = dummyAct;
4031                        }
4032                        availActCache.put(task.realActivity, ai);
4033                    }
4034                    if (ai == dummyAct) {
4035                        // This could be either because the activity no longer exists, or the
4036                        // app is temporarily gone.  For the former we want to remove the recents
4037                        // entry; for the latter we want to mark it as unavailable.
4038                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
4039                        if (app == null) {
4040                            try {
4041                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
4042                                        PackageManager.GET_UNINSTALLED_PACKAGES
4043                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
4044                            } catch (RemoteException e) {
4045                                // Will never happen.
4046                                continue;
4047                            }
4048                            if (app == null) {
4049                                app = dummyApp;
4050                            }
4051                            availAppCache.put(task.realActivity.getPackageName(), app);
4052                        }
4053                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4054                            // Doesn't exist any more!  Good-bye.
4055                            mRecentTasks.remove(i);
4056                            task.removedFromRecents(mTaskPersister);
4057                            i--;
4058                            N--;
4059                            Slog.w(TAG, "Removing no longer valid recent: " + task);
4060                            continue;
4061                        } else {
4062                            // Otherwise just not available for now.
4063                            if (task.isAvailable) {
4064                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4065                                        + task);
4066                            }
4067                            task.isAvailable = false;
4068                        }
4069                    } else {
4070                        if (!ai.enabled || !ai.applicationInfo.enabled
4071                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4072                            if (task.isAvailable) {
4073                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4074                                        + task + " (enabled=" + ai.enabled + "/"
4075                                        + ai.applicationInfo.enabled +  " flags="
4076                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
4077                            }
4078                            task.isAvailable = false;
4079                        } else {
4080                            if (!task.isAvailable) {
4081                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
4082                                        + task);
4083                            }
4084                            task.isAvailable = true;
4085                        }
4086                    }
4087                }
4088            }
4089        }
4090
4091        // Verify the affiliate chain for each task.
4092        for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
4093        }
4094
4095        mTmpRecents.clear();
4096        // mRecentTasks is now in sorted, affiliated order.
4097    }
4098
4099    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
4100        int N = mRecentTasks.size();
4101        TaskRecord top = task;
4102        int topIndex = taskIndex;
4103        while (top.mNextAffiliate != null && topIndex > 0) {
4104            top = top.mNextAffiliate;
4105            topIndex--;
4106        }
4107        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
4108                + topIndex + " from intial " + taskIndex);
4109        // Find the end of the chain, doing a sanity check along the way.
4110        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
4111        int endIndex = topIndex;
4112        TaskRecord prev = top;
4113        while (endIndex < N) {
4114            TaskRecord cur = mRecentTasks.get(endIndex);
4115            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
4116                    + endIndex + " " + cur);
4117            if (cur == top) {
4118                // Verify start of the chain.
4119                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
4120                    Slog.wtf(TAG, "Bad chain @" + endIndex
4121                            + ": first task has next affiliate: " + prev);
4122                    sane = false;
4123                    break;
4124                }
4125            } else {
4126                // Verify middle of the chain's next points back to the one before.
4127                if (cur.mNextAffiliate != prev
4128                        || cur.mNextAffiliateTaskId != prev.taskId) {
4129                    Slog.wtf(TAG, "Bad chain @" + endIndex
4130                            + ": middle task " + cur + " @" + endIndex
4131                            + " has bad next affiliate "
4132                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4133                            + ", expected " + prev);
4134                    sane = false;
4135                    break;
4136                }
4137            }
4138            if (cur.mPrevAffiliateTaskId == -1) {
4139                // Chain ends here.
4140                if (cur.mPrevAffiliate != null) {
4141                    Slog.wtf(TAG, "Bad chain @" + endIndex
4142                            + ": last task " + cur + " has previous affiliate "
4143                            + cur.mPrevAffiliate);
4144                    sane = false;
4145                }
4146                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4147                break;
4148            } else {
4149                // Verify middle of the chain's prev points to a valid item.
4150                if (cur.mPrevAffiliate == null) {
4151                    Slog.wtf(TAG, "Bad chain @" + endIndex
4152                            + ": task " + cur + " has previous affiliate "
4153                            + cur.mPrevAffiliate + " but should be id "
4154                            + cur.mPrevAffiliate);
4155                    sane = false;
4156                    break;
4157                }
4158            }
4159            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4160                Slog.wtf(TAG, "Bad chain @" + endIndex
4161                        + ": task " + cur + " has affiliated id "
4162                        + cur.mAffiliatedTaskId + " but should be "
4163                        + task.mAffiliatedTaskId);
4164                sane = false;
4165                break;
4166            }
4167            prev = cur;
4168            endIndex++;
4169            if (endIndex >= N) {
4170                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4171                        + ": last task " + prev);
4172                sane = false;
4173                break;
4174            }
4175        }
4176        if (sane) {
4177            if (endIndex < taskIndex) {
4178                Slog.wtf(TAG, "Bad chain @" + endIndex
4179                        + ": did not extend to task " + task + " @" + taskIndex);
4180                sane = false;
4181            }
4182        }
4183        if (sane) {
4184            // All looks good, we can just move all of the affiliated tasks
4185            // to the top.
4186            for (int i=topIndex; i<=endIndex; i++) {
4187                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4188                        + " from " + i + " to " + (i-topIndex));
4189                TaskRecord cur = mRecentTasks.remove(i);
4190                mRecentTasks.add(i-topIndex, cur);
4191            }
4192            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4193                    + " to " + endIndex);
4194            return true;
4195        }
4196
4197        // Whoops, couldn't do it.
4198        return false;
4199    }
4200
4201    final void addRecentTaskLocked(TaskRecord task) {
4202        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4203                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4204
4205        int N = mRecentTasks.size();
4206        // Quick case: check if the top-most recent task is the same.
4207        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4208            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4209            return;
4210        }
4211        // Another quick case: check if this is part of a set of affiliated
4212        // tasks that are at the top.
4213        if (isAffiliated && N > 0 && task.inRecents
4214                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4215            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4216                    + " at top when adding " + task);
4217            return;
4218        }
4219        // Another quick case: never add voice sessions.
4220        if (task.voiceSession != null) {
4221            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4222            return;
4223        }
4224
4225        boolean needAffiliationFix = false;
4226
4227        // Slightly less quick case: the task is already in recents, so all we need
4228        // to do is move it.
4229        if (task.inRecents) {
4230            int taskIndex = mRecentTasks.indexOf(task);
4231            if (taskIndex >= 0) {
4232                if (!isAffiliated) {
4233                    // Simple case: this is not an affiliated task, so we just move it to the front.
4234                    mRecentTasks.remove(taskIndex);
4235                    mRecentTasks.add(0, task);
4236                    notifyTaskPersisterLocked(task, false);
4237                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4238                            + " from " + taskIndex);
4239                    return;
4240                } else {
4241                    // More complicated: need to keep all affiliated tasks together.
4242                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4243                        // All went well.
4244                        return;
4245                    }
4246
4247                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4248                    // everything and then go through our general path of adding a new task.
4249                    needAffiliationFix = true;
4250                }
4251            } else {
4252                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4253                needAffiliationFix = true;
4254            }
4255        }
4256
4257        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4258        trimRecentsForTask(task, true);
4259
4260        N = mRecentTasks.size();
4261        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4262            final TaskRecord tr = mRecentTasks.remove(N - 1);
4263            tr.removedFromRecents(mTaskPersister);
4264            N--;
4265        }
4266        task.inRecents = true;
4267        if (!isAffiliated || needAffiliationFix) {
4268            // If this is a simple non-affiliated task, or we had some failure trying to
4269            // handle it as part of an affilated task, then just place it at the top.
4270            mRecentTasks.add(0, task);
4271        } else if (isAffiliated) {
4272            // If this is a new affiliated task, then move all of the affiliated tasks
4273            // to the front and insert this new one.
4274            TaskRecord other = task.mNextAffiliate;
4275            if (other == null) {
4276                other = task.mPrevAffiliate;
4277            }
4278            if (other != null) {
4279                int otherIndex = mRecentTasks.indexOf(other);
4280                if (otherIndex >= 0) {
4281                    // Insert new task at appropriate location.
4282                    int taskIndex;
4283                    if (other == task.mNextAffiliate) {
4284                        // We found the index of our next affiliation, which is who is
4285                        // before us in the list, so add after that point.
4286                        taskIndex = otherIndex+1;
4287                    } else {
4288                        // We found the index of our previous affiliation, which is who is
4289                        // after us in the list, so add at their position.
4290                        taskIndex = otherIndex;
4291                    }
4292                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4293                            + taskIndex + ": " + task);
4294                    mRecentTasks.add(taskIndex, task);
4295
4296                    // Now move everything to the front.
4297                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4298                        // All went well.
4299                        return;
4300                    }
4301
4302                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4303                    // everything and then go through our general path of adding a new task.
4304                    needAffiliationFix = true;
4305                } else {
4306                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4307                            + other);
4308                    needAffiliationFix = true;
4309                }
4310            } else {
4311                if (DEBUG_RECENTS) Slog.d(TAG,
4312                        "addRecent: adding affiliated task without next/prev:" + task);
4313                needAffiliationFix = true;
4314            }
4315        }
4316        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4317
4318        if (needAffiliationFix) {
4319            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4320            cleanupRecentTasksLocked(task.userId);
4321        }
4322    }
4323
4324    /**
4325     * If needed, remove oldest existing entries in recents that are for the same kind
4326     * of task as the given one.
4327     */
4328    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4329        int N = mRecentTasks.size();
4330        final Intent intent = task.intent;
4331        final boolean document = intent != null && intent.isDocument();
4332
4333        int maxRecents = task.maxRecents - 1;
4334        for (int i=0; i<N; i++) {
4335            final TaskRecord tr = mRecentTasks.get(i);
4336            if (task != tr) {
4337                if (task.userId != tr.userId) {
4338                    continue;
4339                }
4340                if (i > MAX_RECENT_BITMAPS) {
4341                    tr.freeLastThumbnail();
4342                }
4343                final Intent trIntent = tr.intent;
4344                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4345                    (intent == null || !intent.filterEquals(trIntent))) {
4346                    continue;
4347                }
4348                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4349                if (document && trIsDocument) {
4350                    // These are the same document activity (not necessarily the same doc).
4351                    if (maxRecents > 0) {
4352                        --maxRecents;
4353                        continue;
4354                    }
4355                    // Hit the maximum number of documents for this task. Fall through
4356                    // and remove this document from recents.
4357                } else if (document || trIsDocument) {
4358                    // Only one of these is a document. Not the droid we're looking for.
4359                    continue;
4360                }
4361            }
4362
4363            if (!doTrim) {
4364                // If the caller is not actually asking for a trim, just tell them we reached
4365                // a point where the trim would happen.
4366                return i;
4367            }
4368
4369            // Either task and tr are the same or, their affinities match or their intents match
4370            // and neither of them is a document, or they are documents using the same activity
4371            // and their maxRecents has been reached.
4372            tr.disposeThumbnail();
4373            mRecentTasks.remove(i);
4374            if (task != tr) {
4375                tr.removedFromRecents(mTaskPersister);
4376            }
4377            i--;
4378            N--;
4379            if (task.intent == null) {
4380                // If the new recent task we are adding is not fully
4381                // specified, then replace it with the existing recent task.
4382                task = tr;
4383            }
4384            notifyTaskPersisterLocked(tr, false);
4385        }
4386
4387        return -1;
4388    }
4389
4390    @Override
4391    public void reportActivityFullyDrawn(IBinder token) {
4392        synchronized (this) {
4393            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4394            if (r == null) {
4395                return;
4396            }
4397            r.reportFullyDrawnLocked();
4398        }
4399    }
4400
4401    @Override
4402    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4403        synchronized (this) {
4404            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4405            if (r == null) {
4406                return;
4407            }
4408            final long origId = Binder.clearCallingIdentity();
4409            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4410            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4411                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4412            if (config != null) {
4413                r.frozenBeforeDestroy = true;
4414                if (!updateConfigurationLocked(config, r, false, false)) {
4415                    mStackSupervisor.resumeTopActivitiesLocked();
4416                }
4417            }
4418            Binder.restoreCallingIdentity(origId);
4419        }
4420    }
4421
4422    @Override
4423    public int getRequestedOrientation(IBinder token) {
4424        synchronized (this) {
4425            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4426            if (r == null) {
4427                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4428            }
4429            return mWindowManager.getAppOrientation(r.appToken);
4430        }
4431    }
4432
4433    /**
4434     * This is the internal entry point for handling Activity.finish().
4435     *
4436     * @param token The Binder token referencing the Activity we want to finish.
4437     * @param resultCode Result code, if any, from this Activity.
4438     * @param resultData Result data (Intent), if any, from this Activity.
4439     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4440     *            the root Activity in the task.
4441     *
4442     * @return Returns true if the activity successfully finished, or false if it is still running.
4443     */
4444    @Override
4445    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4446            boolean finishTask) {
4447        // Refuse possible leaked file descriptors
4448        if (resultData != null && resultData.hasFileDescriptors() == true) {
4449            throw new IllegalArgumentException("File descriptors passed in Intent");
4450        }
4451
4452        synchronized(this) {
4453            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4454            if (r == null) {
4455                return true;
4456            }
4457            // Keep track of the root activity of the task before we finish it
4458            TaskRecord tr = r.task;
4459            ActivityRecord rootR = tr.getRootActivity();
4460            // Do not allow task to finish in Lock Task mode.
4461            if (tr == mStackSupervisor.mLockTaskModeTask) {
4462                if (rootR == r) {
4463                    mStackSupervisor.showLockTaskToast();
4464                    return false;
4465                }
4466            }
4467            if (mController != null) {
4468                // Find the first activity that is not finishing.
4469                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4470                if (next != null) {
4471                    // ask watcher if this is allowed
4472                    boolean resumeOK = true;
4473                    try {
4474                        resumeOK = mController.activityResuming(next.packageName);
4475                    } catch (RemoteException e) {
4476                        mController = null;
4477                        Watchdog.getInstance().setActivityController(null);
4478                    }
4479
4480                    if (!resumeOK) {
4481                        return false;
4482                    }
4483                }
4484            }
4485            final long origId = Binder.clearCallingIdentity();
4486            try {
4487                boolean res;
4488                if (finishTask && r == rootR) {
4489                    // If requested, remove the task that is associated to this activity only if it
4490                    // was the root activity in the task.  The result code and data is ignored because
4491                    // we don't support returning them across task boundaries.
4492                    res = removeTaskByIdLocked(tr.taskId, 0);
4493                } else {
4494                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4495                            resultData, "app-request", true);
4496                }
4497                return res;
4498            } finally {
4499                Binder.restoreCallingIdentity(origId);
4500            }
4501        }
4502    }
4503
4504    @Override
4505    public final void finishHeavyWeightApp() {
4506        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4507                != PackageManager.PERMISSION_GRANTED) {
4508            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4509                    + Binder.getCallingPid()
4510                    + ", uid=" + Binder.getCallingUid()
4511                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4512            Slog.w(TAG, msg);
4513            throw new SecurityException(msg);
4514        }
4515
4516        synchronized(this) {
4517            if (mHeavyWeightProcess == null) {
4518                return;
4519            }
4520
4521            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4522                    mHeavyWeightProcess.activities);
4523            for (int i=0; i<activities.size(); i++) {
4524                ActivityRecord r = activities.get(i);
4525                if (!r.finishing) {
4526                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4527                            null, "finish-heavy", true);
4528                }
4529            }
4530
4531            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4532                    mHeavyWeightProcess.userId, 0));
4533            mHeavyWeightProcess = null;
4534        }
4535    }
4536
4537    @Override
4538    public void crashApplication(int uid, int initialPid, String packageName,
4539            String message) {
4540        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4541                != PackageManager.PERMISSION_GRANTED) {
4542            String msg = "Permission Denial: crashApplication() from pid="
4543                    + Binder.getCallingPid()
4544                    + ", uid=" + Binder.getCallingUid()
4545                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4546            Slog.w(TAG, msg);
4547            throw new SecurityException(msg);
4548        }
4549
4550        synchronized(this) {
4551            ProcessRecord proc = null;
4552
4553            // Figure out which process to kill.  We don't trust that initialPid
4554            // still has any relation to current pids, so must scan through the
4555            // list.
4556            synchronized (mPidsSelfLocked) {
4557                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4558                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4559                    if (p.uid != uid) {
4560                        continue;
4561                    }
4562                    if (p.pid == initialPid) {
4563                        proc = p;
4564                        break;
4565                    }
4566                    if (p.pkgList.containsKey(packageName)) {
4567                        proc = p;
4568                    }
4569                }
4570            }
4571
4572            if (proc == null) {
4573                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4574                        + " initialPid=" + initialPid
4575                        + " packageName=" + packageName);
4576                return;
4577            }
4578
4579            if (proc.thread != null) {
4580                if (proc.pid == Process.myPid()) {
4581                    Log.w(TAG, "crashApplication: trying to crash self!");
4582                    return;
4583                }
4584                long ident = Binder.clearCallingIdentity();
4585                try {
4586                    proc.thread.scheduleCrash(message);
4587                } catch (RemoteException e) {
4588                }
4589                Binder.restoreCallingIdentity(ident);
4590            }
4591        }
4592    }
4593
4594    @Override
4595    public final void finishSubActivity(IBinder token, String resultWho,
4596            int requestCode) {
4597        synchronized(this) {
4598            final long origId = Binder.clearCallingIdentity();
4599            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4600            if (r != null) {
4601                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4602            }
4603            Binder.restoreCallingIdentity(origId);
4604        }
4605    }
4606
4607    @Override
4608    public boolean finishActivityAffinity(IBinder token) {
4609        synchronized(this) {
4610            final long origId = Binder.clearCallingIdentity();
4611            try {
4612                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4613
4614                ActivityRecord rootR = r.task.getRootActivity();
4615                // Do not allow task to finish in Lock Task mode.
4616                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4617                    if (rootR == r) {
4618                        mStackSupervisor.showLockTaskToast();
4619                        return false;
4620                    }
4621                }
4622                boolean res = false;
4623                if (r != null) {
4624                    res = r.task.stack.finishActivityAffinityLocked(r);
4625                }
4626                return res;
4627            } finally {
4628                Binder.restoreCallingIdentity(origId);
4629            }
4630        }
4631    }
4632
4633    @Override
4634    public void finishVoiceTask(IVoiceInteractionSession session) {
4635        synchronized(this) {
4636            final long origId = Binder.clearCallingIdentity();
4637            try {
4638                mStackSupervisor.finishVoiceTask(session);
4639            } finally {
4640                Binder.restoreCallingIdentity(origId);
4641            }
4642        }
4643
4644    }
4645
4646    @Override
4647    public boolean releaseActivityInstance(IBinder token) {
4648        synchronized(this) {
4649            final long origId = Binder.clearCallingIdentity();
4650            try {
4651                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4652                if (r.task == null || r.task.stack == null) {
4653                    return false;
4654                }
4655                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4656            } finally {
4657                Binder.restoreCallingIdentity(origId);
4658            }
4659        }
4660    }
4661
4662    @Override
4663    public void releaseSomeActivities(IApplicationThread appInt) {
4664        synchronized(this) {
4665            final long origId = Binder.clearCallingIdentity();
4666            try {
4667                ProcessRecord app = getRecordForAppLocked(appInt);
4668                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4669            } finally {
4670                Binder.restoreCallingIdentity(origId);
4671            }
4672        }
4673    }
4674
4675    @Override
4676    public boolean willActivityBeVisible(IBinder token) {
4677        synchronized(this) {
4678            ActivityStack stack = ActivityRecord.getStackLocked(token);
4679            if (stack != null) {
4680                return stack.willActivityBeVisibleLocked(token);
4681            }
4682            return false;
4683        }
4684    }
4685
4686    @Override
4687    public void overridePendingTransition(IBinder token, String packageName,
4688            int enterAnim, int exitAnim) {
4689        synchronized(this) {
4690            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4691            if (self == null) {
4692                return;
4693            }
4694
4695            final long origId = Binder.clearCallingIdentity();
4696
4697            if (self.state == ActivityState.RESUMED
4698                    || self.state == ActivityState.PAUSING) {
4699                mWindowManager.overridePendingAppTransition(packageName,
4700                        enterAnim, exitAnim, null);
4701            }
4702
4703            Binder.restoreCallingIdentity(origId);
4704        }
4705    }
4706
4707    /**
4708     * Main function for removing an existing process from the activity manager
4709     * as a result of that process going away.  Clears out all connections
4710     * to the process.
4711     */
4712    private final void handleAppDiedLocked(ProcessRecord app,
4713            boolean restarting, boolean allowRestart) {
4714        int pid = app.pid;
4715        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4716        if (!kept && !restarting) {
4717            removeLruProcessLocked(app);
4718            if (pid > 0) {
4719                ProcessList.remove(pid);
4720            }
4721        }
4722
4723        if (mProfileProc == app) {
4724            clearProfilerLocked();
4725        }
4726
4727        // Remove this application's activities from active lists.
4728        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4729
4730        app.activities.clear();
4731
4732        if (app.instrumentationClass != null) {
4733            Slog.w(TAG, "Crash of app " + app.processName
4734                  + " running instrumentation " + app.instrumentationClass);
4735            Bundle info = new Bundle();
4736            info.putString("shortMsg", "Process crashed.");
4737            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4738        }
4739
4740        if (!restarting) {
4741            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4742                // If there was nothing to resume, and we are not already
4743                // restarting this process, but there is a visible activity that
4744                // is hosted by the process...  then make sure all visible
4745                // activities are running, taking care of restarting this
4746                // process.
4747                if (hasVisibleActivities) {
4748                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4749                }
4750            }
4751        }
4752    }
4753
4754    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4755        IBinder threadBinder = thread.asBinder();
4756        // Find the application record.
4757        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4758            ProcessRecord rec = mLruProcesses.get(i);
4759            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4760                return i;
4761            }
4762        }
4763        return -1;
4764    }
4765
4766    final ProcessRecord getRecordForAppLocked(
4767            IApplicationThread thread) {
4768        if (thread == null) {
4769            return null;
4770        }
4771
4772        int appIndex = getLRURecordIndexForAppLocked(thread);
4773        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4774    }
4775
4776    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4777        // If there are no longer any background processes running,
4778        // and the app that died was not running instrumentation,
4779        // then tell everyone we are now low on memory.
4780        boolean haveBg = false;
4781        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4782            ProcessRecord rec = mLruProcesses.get(i);
4783            if (rec.thread != null
4784                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4785                haveBg = true;
4786                break;
4787            }
4788        }
4789
4790        if (!haveBg) {
4791            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4792            if (doReport) {
4793                long now = SystemClock.uptimeMillis();
4794                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4795                    doReport = false;
4796                } else {
4797                    mLastMemUsageReportTime = now;
4798                }
4799            }
4800            final ArrayList<ProcessMemInfo> memInfos
4801                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4802            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4803            long now = SystemClock.uptimeMillis();
4804            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4805                ProcessRecord rec = mLruProcesses.get(i);
4806                if (rec == dyingProc || rec.thread == null) {
4807                    continue;
4808                }
4809                if (doReport) {
4810                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4811                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4812                }
4813                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4814                    // The low memory report is overriding any current
4815                    // state for a GC request.  Make sure to do
4816                    // heavy/important/visible/foreground processes first.
4817                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4818                        rec.lastRequestedGc = 0;
4819                    } else {
4820                        rec.lastRequestedGc = rec.lastLowMemory;
4821                    }
4822                    rec.reportLowMemory = true;
4823                    rec.lastLowMemory = now;
4824                    mProcessesToGc.remove(rec);
4825                    addProcessToGcListLocked(rec);
4826                }
4827            }
4828            if (doReport) {
4829                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4830                mHandler.sendMessage(msg);
4831            }
4832            scheduleAppGcsLocked();
4833        }
4834    }
4835
4836    final void appDiedLocked(ProcessRecord app) {
4837       appDiedLocked(app, app.pid, app.thread);
4838    }
4839
4840    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4841        // First check if this ProcessRecord is actually active for the pid.
4842        synchronized (mPidsSelfLocked) {
4843            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4844            if (curProc != app) {
4845                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4846                return;
4847            }
4848        }
4849
4850        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4851        synchronized (stats) {
4852            stats.noteProcessDiedLocked(app.info.uid, pid);
4853        }
4854
4855        Process.killProcessQuiet(pid);
4856        Process.killProcessGroup(app.info.uid, pid);
4857        app.killed = true;
4858
4859        // Clean up already done if the process has been re-started.
4860        if (app.pid == pid && app.thread != null &&
4861                app.thread.asBinder() == thread.asBinder()) {
4862            boolean doLowMem = app.instrumentationClass == null;
4863            boolean doOomAdj = doLowMem;
4864            if (!app.killedByAm) {
4865                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4866                        + ") has died");
4867                mAllowLowerMemLevel = true;
4868            } else {
4869                // Note that we always want to do oom adj to update our state with the
4870                // new number of procs.
4871                mAllowLowerMemLevel = false;
4872                doLowMem = false;
4873            }
4874            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4875            if (DEBUG_CLEANUP) Slog.v(
4876                TAG, "Dying app: " + app + ", pid: " + pid
4877                + ", thread: " + thread.asBinder());
4878            handleAppDiedLocked(app, false, true);
4879
4880            if (doOomAdj) {
4881                updateOomAdjLocked();
4882            }
4883            if (doLowMem) {
4884                doLowMemReportIfNeededLocked(app);
4885            }
4886        } else if (app.pid != pid) {
4887            // A new process has already been started.
4888            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4889                    + ") has died and restarted (pid " + app.pid + ").");
4890            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4891        } else if (DEBUG_PROCESSES) {
4892            Slog.d(TAG, "Received spurious death notification for thread "
4893                    + thread.asBinder());
4894        }
4895    }
4896
4897    /**
4898     * If a stack trace dump file is configured, dump process stack traces.
4899     * @param clearTraces causes the dump file to be erased prior to the new
4900     *    traces being written, if true; when false, the new traces will be
4901     *    appended to any existing file content.
4902     * @param firstPids of dalvik VM processes to dump stack traces for first
4903     * @param lastPids of dalvik VM processes to dump stack traces for last
4904     * @param nativeProcs optional list of native process names to dump stack crawls
4905     * @return file containing stack traces, or null if no dump file is configured
4906     */
4907    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4908            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4909        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4910        if (tracesPath == null || tracesPath.length() == 0) {
4911            return null;
4912        }
4913
4914        File tracesFile = new File(tracesPath);
4915        try {
4916            File tracesDir = tracesFile.getParentFile();
4917            if (!tracesDir.exists()) {
4918                tracesDir.mkdirs();
4919                if (!SELinux.restorecon(tracesDir)) {
4920                    return null;
4921                }
4922            }
4923            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4924
4925            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4926            tracesFile.createNewFile();
4927            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4928        } catch (IOException e) {
4929            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4930            return null;
4931        }
4932
4933        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4934        return tracesFile;
4935    }
4936
4937    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4938            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4939        // Use a FileObserver to detect when traces finish writing.
4940        // The order of traces is considered important to maintain for legibility.
4941        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4942            @Override
4943            public synchronized void onEvent(int event, String path) { notify(); }
4944        };
4945
4946        try {
4947            observer.startWatching();
4948
4949            // First collect all of the stacks of the most important pids.
4950            if (firstPids != null) {
4951                try {
4952                    int num = firstPids.size();
4953                    for (int i = 0; i < num; i++) {
4954                        synchronized (observer) {
4955                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4956                            observer.wait(200);  // Wait for write-close, give up after 200msec
4957                        }
4958                    }
4959                } catch (InterruptedException e) {
4960                    Slog.wtf(TAG, e);
4961                }
4962            }
4963
4964            // Next collect the stacks of the native pids
4965            if (nativeProcs != null) {
4966                int[] pids = Process.getPidsForCommands(nativeProcs);
4967                if (pids != null) {
4968                    for (int pid : pids) {
4969                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4970                    }
4971                }
4972            }
4973
4974            // Lastly, measure CPU usage.
4975            if (processCpuTracker != null) {
4976                processCpuTracker.init();
4977                System.gc();
4978                processCpuTracker.update();
4979                try {
4980                    synchronized (processCpuTracker) {
4981                        processCpuTracker.wait(500); // measure over 1/2 second.
4982                    }
4983                } catch (InterruptedException e) {
4984                }
4985                processCpuTracker.update();
4986
4987                // We'll take the stack crawls of just the top apps using CPU.
4988                final int N = processCpuTracker.countWorkingStats();
4989                int numProcs = 0;
4990                for (int i=0; i<N && numProcs<5; i++) {
4991                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4992                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4993                        numProcs++;
4994                        try {
4995                            synchronized (observer) {
4996                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4997                                observer.wait(200);  // Wait for write-close, give up after 200msec
4998                            }
4999                        } catch (InterruptedException e) {
5000                            Slog.wtf(TAG, e);
5001                        }
5002
5003                    }
5004                }
5005            }
5006        } finally {
5007            observer.stopWatching();
5008        }
5009    }
5010
5011    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5012        if (true || IS_USER_BUILD) {
5013            return;
5014        }
5015        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5016        if (tracesPath == null || tracesPath.length() == 0) {
5017            return;
5018        }
5019
5020        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5021        StrictMode.allowThreadDiskWrites();
5022        try {
5023            final File tracesFile = new File(tracesPath);
5024            final File tracesDir = tracesFile.getParentFile();
5025            final File tracesTmp = new File(tracesDir, "__tmp__");
5026            try {
5027                if (!tracesDir.exists()) {
5028                    tracesDir.mkdirs();
5029                    if (!SELinux.restorecon(tracesDir.getPath())) {
5030                        return;
5031                    }
5032                }
5033                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
5034
5035                if (tracesFile.exists()) {
5036                    tracesTmp.delete();
5037                    tracesFile.renameTo(tracesTmp);
5038                }
5039                StringBuilder sb = new StringBuilder();
5040                Time tobj = new Time();
5041                tobj.set(System.currentTimeMillis());
5042                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5043                sb.append(": ");
5044                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5045                sb.append(" since ");
5046                sb.append(msg);
5047                FileOutputStream fos = new FileOutputStream(tracesFile);
5048                fos.write(sb.toString().getBytes());
5049                if (app == null) {
5050                    fos.write("\n*** No application process!".getBytes());
5051                }
5052                fos.close();
5053                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5054            } catch (IOException e) {
5055                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5056                return;
5057            }
5058
5059            if (app != null) {
5060                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5061                firstPids.add(app.pid);
5062                dumpStackTraces(tracesPath, firstPids, null, null, null);
5063            }
5064
5065            File lastTracesFile = null;
5066            File curTracesFile = null;
5067            for (int i=9; i>=0; i--) {
5068                String name = String.format(Locale.US, "slow%02d.txt", i);
5069                curTracesFile = new File(tracesDir, name);
5070                if (curTracesFile.exists()) {
5071                    if (lastTracesFile != null) {
5072                        curTracesFile.renameTo(lastTracesFile);
5073                    } else {
5074                        curTracesFile.delete();
5075                    }
5076                }
5077                lastTracesFile = curTracesFile;
5078            }
5079            tracesFile.renameTo(curTracesFile);
5080            if (tracesTmp.exists()) {
5081                tracesTmp.renameTo(tracesFile);
5082            }
5083        } finally {
5084            StrictMode.setThreadPolicy(oldPolicy);
5085        }
5086    }
5087
5088    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
5089            ActivityRecord parent, boolean aboveSystem, final String annotation) {
5090        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
5091        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
5092
5093        if (mController != null) {
5094            try {
5095                // 0 == continue, -1 = kill process immediately
5096                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
5097                if (res < 0 && app.pid != MY_PID) {
5098                    app.kill("anr", true);
5099                }
5100            } catch (RemoteException e) {
5101                mController = null;
5102                Watchdog.getInstance().setActivityController(null);
5103            }
5104        }
5105
5106        long anrTime = SystemClock.uptimeMillis();
5107        if (MONITOR_CPU_USAGE) {
5108            updateCpuStatsNow();
5109        }
5110
5111        synchronized (this) {
5112            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5113            if (mShuttingDown) {
5114                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5115                return;
5116            } else if (app.notResponding) {
5117                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5118                return;
5119            } else if (app.crashing) {
5120                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5121                return;
5122            }
5123
5124            // In case we come through here for the same app before completing
5125            // this one, mark as anring now so we will bail out.
5126            app.notResponding = true;
5127
5128            // Log the ANR to the event log.
5129            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5130                    app.processName, app.info.flags, annotation);
5131
5132            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5133            firstPids.add(app.pid);
5134
5135            int parentPid = app.pid;
5136            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5137            if (parentPid != app.pid) firstPids.add(parentPid);
5138
5139            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5140
5141            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5142                ProcessRecord r = mLruProcesses.get(i);
5143                if (r != null && r.thread != null) {
5144                    int pid = r.pid;
5145                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5146                        if (r.persistent) {
5147                            firstPids.add(pid);
5148                        } else {
5149                            lastPids.put(pid, Boolean.TRUE);
5150                        }
5151                    }
5152                }
5153            }
5154        }
5155
5156        // Log the ANR to the main log.
5157        StringBuilder info = new StringBuilder();
5158        info.setLength(0);
5159        info.append("ANR in ").append(app.processName);
5160        if (activity != null && activity.shortComponentName != null) {
5161            info.append(" (").append(activity.shortComponentName).append(")");
5162        }
5163        info.append("\n");
5164        info.append("PID: ").append(app.pid).append("\n");
5165        if (annotation != null) {
5166            info.append("Reason: ").append(annotation).append("\n");
5167        }
5168        if (parent != null && parent != activity) {
5169            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5170        }
5171
5172        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5173
5174        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5175                NATIVE_STACKS_OF_INTEREST);
5176
5177        String cpuInfo = null;
5178        if (MONITOR_CPU_USAGE) {
5179            updateCpuStatsNow();
5180            synchronized (mProcessCpuTracker) {
5181                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5182            }
5183            info.append(processCpuTracker.printCurrentLoad());
5184            info.append(cpuInfo);
5185        }
5186
5187        info.append(processCpuTracker.printCurrentState(anrTime));
5188
5189        Slog.e(TAG, info.toString());
5190        if (tracesFile == null) {
5191            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5192            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5193        }
5194
5195        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5196                cpuInfo, tracesFile, null);
5197
5198        if (mController != null) {
5199            try {
5200                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5201                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5202                if (res != 0) {
5203                    if (res < 0 && app.pid != MY_PID) {
5204                        app.kill("anr", true);
5205                    } else {
5206                        synchronized (this) {
5207                            mServices.scheduleServiceTimeoutLocked(app);
5208                        }
5209                    }
5210                    return;
5211                }
5212            } catch (RemoteException e) {
5213                mController = null;
5214                Watchdog.getInstance().setActivityController(null);
5215            }
5216        }
5217
5218        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5219        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5220                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5221
5222        synchronized (this) {
5223            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5224                app.kill("bg anr", true);
5225                return;
5226            }
5227
5228            // Set the app's notResponding state, and look up the errorReportReceiver
5229            makeAppNotRespondingLocked(app,
5230                    activity != null ? activity.shortComponentName : null,
5231                    annotation != null ? "ANR " + annotation : "ANR",
5232                    info.toString());
5233
5234            // Bring up the infamous App Not Responding dialog
5235            Message msg = Message.obtain();
5236            HashMap<String, Object> map = new HashMap<String, Object>();
5237            msg.what = SHOW_NOT_RESPONDING_MSG;
5238            msg.obj = map;
5239            msg.arg1 = aboveSystem ? 1 : 0;
5240            map.put("app", app);
5241            if (activity != null) {
5242                map.put("activity", activity);
5243            }
5244
5245            mHandler.sendMessage(msg);
5246        }
5247    }
5248
5249    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5250        if (!mLaunchWarningShown) {
5251            mLaunchWarningShown = true;
5252            mHandler.post(new Runnable() {
5253                @Override
5254                public void run() {
5255                    synchronized (ActivityManagerService.this) {
5256                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5257                        d.show();
5258                        mHandler.postDelayed(new Runnable() {
5259                            @Override
5260                            public void run() {
5261                                synchronized (ActivityManagerService.this) {
5262                                    d.dismiss();
5263                                    mLaunchWarningShown = false;
5264                                }
5265                            }
5266                        }, 4000);
5267                    }
5268                }
5269            });
5270        }
5271    }
5272
5273    @Override
5274    public boolean clearApplicationUserData(final String packageName,
5275            final IPackageDataObserver observer, int userId) {
5276        enforceNotIsolatedCaller("clearApplicationUserData");
5277        int uid = Binder.getCallingUid();
5278        int pid = Binder.getCallingPid();
5279        userId = handleIncomingUser(pid, uid,
5280                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5281        long callingId = Binder.clearCallingIdentity();
5282        try {
5283            IPackageManager pm = AppGlobals.getPackageManager();
5284            int pkgUid = -1;
5285            synchronized(this) {
5286                try {
5287                    pkgUid = pm.getPackageUid(packageName, userId);
5288                } catch (RemoteException e) {
5289                }
5290                if (pkgUid == -1) {
5291                    Slog.w(TAG, "Invalid packageName: " + packageName);
5292                    if (observer != null) {
5293                        try {
5294                            observer.onRemoveCompleted(packageName, false);
5295                        } catch (RemoteException e) {
5296                            Slog.i(TAG, "Observer no longer exists.");
5297                        }
5298                    }
5299                    return false;
5300                }
5301                if (uid == pkgUid || checkComponentPermission(
5302                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5303                        pid, uid, -1, true)
5304                        == PackageManager.PERMISSION_GRANTED) {
5305                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5306                } else {
5307                    throw new SecurityException("PID " + pid + " does not have permission "
5308                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5309                                    + " of package " + packageName);
5310                }
5311
5312                // Remove all tasks match the cleared application package and user
5313                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5314                    final TaskRecord tr = mRecentTasks.get(i);
5315                    final String taskPackageName =
5316                            tr.getBaseIntent().getComponent().getPackageName();
5317                    if (tr.userId != userId) continue;
5318                    if (!taskPackageName.equals(packageName)) continue;
5319                    removeTaskByIdLocked(tr.taskId, 0);
5320                }
5321            }
5322
5323            try {
5324                // Clear application user data
5325                pm.clearApplicationUserData(packageName, observer, userId);
5326
5327                synchronized(this) {
5328                    // Remove all permissions granted from/to this package
5329                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5330                }
5331
5332                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5333                        Uri.fromParts("package", packageName, null));
5334                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5335                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5336                        null, null, 0, null, null, null, false, false, userId);
5337            } catch (RemoteException e) {
5338            }
5339        } finally {
5340            Binder.restoreCallingIdentity(callingId);
5341        }
5342        return true;
5343    }
5344
5345    @Override
5346    public void killBackgroundProcesses(final String packageName, int userId) {
5347        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5348                != PackageManager.PERMISSION_GRANTED &&
5349                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5350                        != PackageManager.PERMISSION_GRANTED) {
5351            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5352                    + Binder.getCallingPid()
5353                    + ", uid=" + Binder.getCallingUid()
5354                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5355            Slog.w(TAG, msg);
5356            throw new SecurityException(msg);
5357        }
5358
5359        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5360                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5361        long callingId = Binder.clearCallingIdentity();
5362        try {
5363            IPackageManager pm = AppGlobals.getPackageManager();
5364            synchronized(this) {
5365                int appId = -1;
5366                try {
5367                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5368                } catch (RemoteException e) {
5369                }
5370                if (appId == -1) {
5371                    Slog.w(TAG, "Invalid packageName: " + packageName);
5372                    return;
5373                }
5374                killPackageProcessesLocked(packageName, appId, userId,
5375                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5376            }
5377        } finally {
5378            Binder.restoreCallingIdentity(callingId);
5379        }
5380    }
5381
5382    @Override
5383    public void killAllBackgroundProcesses() {
5384        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5385                != PackageManager.PERMISSION_GRANTED) {
5386            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5387                    + Binder.getCallingPid()
5388                    + ", uid=" + Binder.getCallingUid()
5389                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5390            Slog.w(TAG, msg);
5391            throw new SecurityException(msg);
5392        }
5393
5394        long callingId = Binder.clearCallingIdentity();
5395        try {
5396            synchronized(this) {
5397                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5398                final int NP = mProcessNames.getMap().size();
5399                for (int ip=0; ip<NP; ip++) {
5400                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5401                    final int NA = apps.size();
5402                    for (int ia=0; ia<NA; ia++) {
5403                        ProcessRecord app = apps.valueAt(ia);
5404                        if (app.persistent) {
5405                            // we don't kill persistent processes
5406                            continue;
5407                        }
5408                        if (app.removed) {
5409                            procs.add(app);
5410                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5411                            app.removed = true;
5412                            procs.add(app);
5413                        }
5414                    }
5415                }
5416
5417                int N = procs.size();
5418                for (int i=0; i<N; i++) {
5419                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5420                }
5421                mAllowLowerMemLevel = true;
5422                updateOomAdjLocked();
5423                doLowMemReportIfNeededLocked(null);
5424            }
5425        } finally {
5426            Binder.restoreCallingIdentity(callingId);
5427        }
5428    }
5429
5430    @Override
5431    public void forceStopPackage(final String packageName, int userId) {
5432        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5433                != PackageManager.PERMISSION_GRANTED) {
5434            String msg = "Permission Denial: forceStopPackage() from pid="
5435                    + Binder.getCallingPid()
5436                    + ", uid=" + Binder.getCallingUid()
5437                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5438            Slog.w(TAG, msg);
5439            throw new SecurityException(msg);
5440        }
5441        final int callingPid = Binder.getCallingPid();
5442        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5443                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5444        long callingId = Binder.clearCallingIdentity();
5445        try {
5446            IPackageManager pm = AppGlobals.getPackageManager();
5447            synchronized(this) {
5448                int[] users = userId == UserHandle.USER_ALL
5449                        ? getUsersLocked() : new int[] { userId };
5450                for (int user : users) {
5451                    int pkgUid = -1;
5452                    try {
5453                        pkgUid = pm.getPackageUid(packageName, user);
5454                    } catch (RemoteException e) {
5455                    }
5456                    if (pkgUid == -1) {
5457                        Slog.w(TAG, "Invalid packageName: " + packageName);
5458                        continue;
5459                    }
5460                    try {
5461                        pm.setPackageStoppedState(packageName, true, user);
5462                    } catch (RemoteException e) {
5463                    } catch (IllegalArgumentException e) {
5464                        Slog.w(TAG, "Failed trying to unstop package "
5465                                + packageName + ": " + e);
5466                    }
5467                    if (isUserRunningLocked(user, false)) {
5468                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5469                    }
5470                }
5471            }
5472        } finally {
5473            Binder.restoreCallingIdentity(callingId);
5474        }
5475    }
5476
5477    @Override
5478    public void addPackageDependency(String packageName) {
5479        synchronized (this) {
5480            int callingPid = Binder.getCallingPid();
5481            if (callingPid == Process.myPid()) {
5482                //  Yeah, um, no.
5483                Slog.w(TAG, "Can't addPackageDependency on system process");
5484                return;
5485            }
5486            ProcessRecord proc;
5487            synchronized (mPidsSelfLocked) {
5488                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5489            }
5490            if (proc != null) {
5491                if (proc.pkgDeps == null) {
5492                    proc.pkgDeps = new ArraySet<String>(1);
5493                }
5494                proc.pkgDeps.add(packageName);
5495            }
5496        }
5497    }
5498
5499    /*
5500     * The pkg name and app id have to be specified.
5501     */
5502    @Override
5503    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5504        if (pkg == null) {
5505            return;
5506        }
5507        // Make sure the uid is valid.
5508        if (appid < 0) {
5509            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5510            return;
5511        }
5512        int callerUid = Binder.getCallingUid();
5513        // Only the system server can kill an application
5514        if (callerUid == Process.SYSTEM_UID) {
5515            // Post an aysnc message to kill the application
5516            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5517            msg.arg1 = appid;
5518            msg.arg2 = 0;
5519            Bundle bundle = new Bundle();
5520            bundle.putString("pkg", pkg);
5521            bundle.putString("reason", reason);
5522            msg.obj = bundle;
5523            mHandler.sendMessage(msg);
5524        } else {
5525            throw new SecurityException(callerUid + " cannot kill pkg: " +
5526                    pkg);
5527        }
5528    }
5529
5530    @Override
5531    public void closeSystemDialogs(String reason) {
5532        enforceNotIsolatedCaller("closeSystemDialogs");
5533
5534        final int pid = Binder.getCallingPid();
5535        final int uid = Binder.getCallingUid();
5536        final long origId = Binder.clearCallingIdentity();
5537        try {
5538            synchronized (this) {
5539                // Only allow this from foreground processes, so that background
5540                // applications can't abuse it to prevent system UI from being shown.
5541                if (uid >= Process.FIRST_APPLICATION_UID) {
5542                    ProcessRecord proc;
5543                    synchronized (mPidsSelfLocked) {
5544                        proc = mPidsSelfLocked.get(pid);
5545                    }
5546                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5547                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5548                                + " from background process " + proc);
5549                        return;
5550                    }
5551                }
5552                closeSystemDialogsLocked(reason);
5553            }
5554        } finally {
5555            Binder.restoreCallingIdentity(origId);
5556        }
5557    }
5558
5559    void closeSystemDialogsLocked(String reason) {
5560        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5561        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5562                | Intent.FLAG_RECEIVER_FOREGROUND);
5563        if (reason != null) {
5564            intent.putExtra("reason", reason);
5565        }
5566        mWindowManager.closeSystemDialogs(reason);
5567
5568        mStackSupervisor.closeSystemDialogsLocked();
5569
5570        broadcastIntentLocked(null, null, intent, null,
5571                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5572                Process.SYSTEM_UID, UserHandle.USER_ALL);
5573    }
5574
5575    @Override
5576    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5577        enforceNotIsolatedCaller("getProcessMemoryInfo");
5578        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5579        for (int i=pids.length-1; i>=0; i--) {
5580            ProcessRecord proc;
5581            int oomAdj;
5582            synchronized (this) {
5583                synchronized (mPidsSelfLocked) {
5584                    proc = mPidsSelfLocked.get(pids[i]);
5585                    oomAdj = proc != null ? proc.setAdj : 0;
5586                }
5587            }
5588            infos[i] = new Debug.MemoryInfo();
5589            Debug.getMemoryInfo(pids[i], infos[i]);
5590            if (proc != null) {
5591                synchronized (this) {
5592                    if (proc.thread != null && proc.setAdj == oomAdj) {
5593                        // Record this for posterity if the process has been stable.
5594                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5595                                infos[i].getTotalUss(), false, proc.pkgList);
5596                    }
5597                }
5598            }
5599        }
5600        return infos;
5601    }
5602
5603    @Override
5604    public long[] getProcessPss(int[] pids) {
5605        enforceNotIsolatedCaller("getProcessPss");
5606        long[] pss = new long[pids.length];
5607        for (int i=pids.length-1; i>=0; i--) {
5608            ProcessRecord proc;
5609            int oomAdj;
5610            synchronized (this) {
5611                synchronized (mPidsSelfLocked) {
5612                    proc = mPidsSelfLocked.get(pids[i]);
5613                    oomAdj = proc != null ? proc.setAdj : 0;
5614                }
5615            }
5616            long[] tmpUss = new long[1];
5617            pss[i] = Debug.getPss(pids[i], tmpUss);
5618            if (proc != null) {
5619                synchronized (this) {
5620                    if (proc.thread != null && proc.setAdj == oomAdj) {
5621                        // Record this for posterity if the process has been stable.
5622                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5623                    }
5624                }
5625            }
5626        }
5627        return pss;
5628    }
5629
5630    @Override
5631    public void killApplicationProcess(String processName, int uid) {
5632        if (processName == null) {
5633            return;
5634        }
5635
5636        int callerUid = Binder.getCallingUid();
5637        // Only the system server can kill an application
5638        if (callerUid == Process.SYSTEM_UID) {
5639            synchronized (this) {
5640                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5641                if (app != null && app.thread != null) {
5642                    try {
5643                        app.thread.scheduleSuicide();
5644                    } catch (RemoteException e) {
5645                        // If the other end already died, then our work here is done.
5646                    }
5647                } else {
5648                    Slog.w(TAG, "Process/uid not found attempting kill of "
5649                            + processName + " / " + uid);
5650                }
5651            }
5652        } else {
5653            throw new SecurityException(callerUid + " cannot kill app process: " +
5654                    processName);
5655        }
5656    }
5657
5658    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5659        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5660                false, true, false, false, UserHandle.getUserId(uid), reason);
5661        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5662                Uri.fromParts("package", packageName, null));
5663        if (!mProcessesReady) {
5664            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5665                    | Intent.FLAG_RECEIVER_FOREGROUND);
5666        }
5667        intent.putExtra(Intent.EXTRA_UID, uid);
5668        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5669        broadcastIntentLocked(null, null, intent,
5670                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5671                false, false,
5672                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5673    }
5674
5675    private void forceStopUserLocked(int userId, String reason) {
5676        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5677        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5678        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5679                | Intent.FLAG_RECEIVER_FOREGROUND);
5680        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5681        broadcastIntentLocked(null, null, intent,
5682                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5683                false, false,
5684                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5685    }
5686
5687    private final boolean killPackageProcessesLocked(String packageName, int appId,
5688            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5689            boolean doit, boolean evenPersistent, String reason) {
5690        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5691
5692        // Remove all processes this package may have touched: all with the
5693        // same UID (except for the system or root user), and all whose name
5694        // matches the package name.
5695        final int NP = mProcessNames.getMap().size();
5696        for (int ip=0; ip<NP; ip++) {
5697            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5698            final int NA = apps.size();
5699            for (int ia=0; ia<NA; ia++) {
5700                ProcessRecord app = apps.valueAt(ia);
5701                if (app.persistent && !evenPersistent) {
5702                    // we don't kill persistent processes
5703                    continue;
5704                }
5705                if (app.removed) {
5706                    if (doit) {
5707                        procs.add(app);
5708                    }
5709                    continue;
5710                }
5711
5712                // Skip process if it doesn't meet our oom adj requirement.
5713                if (app.setAdj < minOomAdj) {
5714                    continue;
5715                }
5716
5717                // If no package is specified, we call all processes under the
5718                // give user id.
5719                if (packageName == null) {
5720                    if (app.userId != userId) {
5721                        continue;
5722                    }
5723                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5724                        continue;
5725                    }
5726                // Package has been specified, we want to hit all processes
5727                // that match it.  We need to qualify this by the processes
5728                // that are running under the specified app and user ID.
5729                } else {
5730                    final boolean isDep = app.pkgDeps != null
5731                            && app.pkgDeps.contains(packageName);
5732                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5733                        continue;
5734                    }
5735                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5736                        continue;
5737                    }
5738                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5739                        continue;
5740                    }
5741                }
5742
5743                // Process has passed all conditions, kill it!
5744                if (!doit) {
5745                    return true;
5746                }
5747                app.removed = true;
5748                procs.add(app);
5749            }
5750        }
5751
5752        int N = procs.size();
5753        for (int i=0; i<N; i++) {
5754            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5755        }
5756        updateOomAdjLocked();
5757        return N > 0;
5758    }
5759
5760    private final boolean forceStopPackageLocked(String name, int appId,
5761            boolean callerWillRestart, boolean purgeCache, boolean doit,
5762            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5763        int i;
5764        int N;
5765
5766        if (userId == UserHandle.USER_ALL && name == null) {
5767            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5768        }
5769
5770        if (appId < 0 && name != null) {
5771            try {
5772                appId = UserHandle.getAppId(
5773                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5774            } catch (RemoteException e) {
5775            }
5776        }
5777
5778        if (doit) {
5779            if (name != null) {
5780                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5781                        + " user=" + userId + ": " + reason);
5782            } else {
5783                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5784            }
5785
5786            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5787            for (int ip=pmap.size()-1; ip>=0; ip--) {
5788                SparseArray<Long> ba = pmap.valueAt(ip);
5789                for (i=ba.size()-1; i>=0; i--) {
5790                    boolean remove = false;
5791                    final int entUid = ba.keyAt(i);
5792                    if (name != null) {
5793                        if (userId == UserHandle.USER_ALL) {
5794                            if (UserHandle.getAppId(entUid) == appId) {
5795                                remove = true;
5796                            }
5797                        } else {
5798                            if (entUid == UserHandle.getUid(userId, appId)) {
5799                                remove = true;
5800                            }
5801                        }
5802                    } else if (UserHandle.getUserId(entUid) == userId) {
5803                        remove = true;
5804                    }
5805                    if (remove) {
5806                        ba.removeAt(i);
5807                    }
5808                }
5809                if (ba.size() == 0) {
5810                    pmap.removeAt(ip);
5811                }
5812            }
5813        }
5814
5815        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5816                -100, callerWillRestart, true, doit, evenPersistent,
5817                name == null ? ("stop user " + userId) : ("stop " + name));
5818
5819        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5820            if (!doit) {
5821                return true;
5822            }
5823            didSomething = true;
5824        }
5825
5826        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5827            if (!doit) {
5828                return true;
5829            }
5830            didSomething = true;
5831        }
5832
5833        if (name == null) {
5834            // Remove all sticky broadcasts from this user.
5835            mStickyBroadcasts.remove(userId);
5836        }
5837
5838        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5839        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5840                userId, providers)) {
5841            if (!doit) {
5842                return true;
5843            }
5844            didSomething = true;
5845        }
5846        N = providers.size();
5847        for (i=0; i<N; i++) {
5848            removeDyingProviderLocked(null, providers.get(i), true);
5849        }
5850
5851        // Remove transient permissions granted from/to this package/user
5852        removeUriPermissionsForPackageLocked(name, userId, false);
5853
5854        if (name == null || uninstalling) {
5855            // Remove pending intents.  For now we only do this when force
5856            // stopping users, because we have some problems when doing this
5857            // for packages -- app widgets are not currently cleaned up for
5858            // such packages, so they can be left with bad pending intents.
5859            if (mIntentSenderRecords.size() > 0) {
5860                Iterator<WeakReference<PendingIntentRecord>> it
5861                        = mIntentSenderRecords.values().iterator();
5862                while (it.hasNext()) {
5863                    WeakReference<PendingIntentRecord> wpir = it.next();
5864                    if (wpir == null) {
5865                        it.remove();
5866                        continue;
5867                    }
5868                    PendingIntentRecord pir = wpir.get();
5869                    if (pir == null) {
5870                        it.remove();
5871                        continue;
5872                    }
5873                    if (name == null) {
5874                        // Stopping user, remove all objects for the user.
5875                        if (pir.key.userId != userId) {
5876                            // Not the same user, skip it.
5877                            continue;
5878                        }
5879                    } else {
5880                        if (UserHandle.getAppId(pir.uid) != appId) {
5881                            // Different app id, skip it.
5882                            continue;
5883                        }
5884                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5885                            // Different user, skip it.
5886                            continue;
5887                        }
5888                        if (!pir.key.packageName.equals(name)) {
5889                            // Different package, skip it.
5890                            continue;
5891                        }
5892                    }
5893                    if (!doit) {
5894                        return true;
5895                    }
5896                    didSomething = true;
5897                    it.remove();
5898                    pir.canceled = true;
5899                    if (pir.key.activity != null) {
5900                        pir.key.activity.pendingResults.remove(pir.ref);
5901                    }
5902                }
5903            }
5904        }
5905
5906        if (doit) {
5907            if (purgeCache && name != null) {
5908                AttributeCache ac = AttributeCache.instance();
5909                if (ac != null) {
5910                    ac.removePackage(name);
5911                }
5912            }
5913            if (mBooted) {
5914                mStackSupervisor.resumeTopActivitiesLocked();
5915                mStackSupervisor.scheduleIdleLocked();
5916            }
5917        }
5918
5919        return didSomething;
5920    }
5921
5922    private final boolean removeProcessLocked(ProcessRecord app,
5923            boolean callerWillRestart, boolean allowRestart, String reason) {
5924        final String name = app.processName;
5925        final int uid = app.uid;
5926        if (DEBUG_PROCESSES) Slog.d(
5927            TAG, "Force removing proc " + app.toShortString() + " (" + name
5928            + "/" + uid + ")");
5929
5930        mProcessNames.remove(name, uid);
5931        mIsolatedProcesses.remove(app.uid);
5932        if (mHeavyWeightProcess == app) {
5933            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5934                    mHeavyWeightProcess.userId, 0));
5935            mHeavyWeightProcess = null;
5936        }
5937        boolean needRestart = false;
5938        if (app.pid > 0 && app.pid != MY_PID) {
5939            int pid = app.pid;
5940            synchronized (mPidsSelfLocked) {
5941                mPidsSelfLocked.remove(pid);
5942                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5943            }
5944            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5945            if (app.isolated) {
5946                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5947            }
5948            app.kill(reason, true);
5949            handleAppDiedLocked(app, true, allowRestart);
5950            removeLruProcessLocked(app);
5951
5952            if (app.persistent && !app.isolated) {
5953                if (!callerWillRestart) {
5954                    addAppLocked(app.info, false, null /* ABI override */);
5955                } else {
5956                    needRestart = true;
5957                }
5958            }
5959        } else {
5960            mRemovedProcesses.add(app);
5961        }
5962
5963        return needRestart;
5964    }
5965
5966    private final void processStartTimedOutLocked(ProcessRecord app) {
5967        final int pid = app.pid;
5968        boolean gone = false;
5969        synchronized (mPidsSelfLocked) {
5970            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5971            if (knownApp != null && knownApp.thread == null) {
5972                mPidsSelfLocked.remove(pid);
5973                gone = true;
5974            }
5975        }
5976
5977        if (gone) {
5978            Slog.w(TAG, "Process " + app + " failed to attach");
5979            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5980                    pid, app.uid, app.processName);
5981            mProcessNames.remove(app.processName, app.uid);
5982            mIsolatedProcesses.remove(app.uid);
5983            if (mHeavyWeightProcess == app) {
5984                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5985                        mHeavyWeightProcess.userId, 0));
5986                mHeavyWeightProcess = null;
5987            }
5988            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5989            if (app.isolated) {
5990                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5991            }
5992            // Take care of any launching providers waiting for this process.
5993            checkAppInLaunchingProvidersLocked(app, true);
5994            // Take care of any services that are waiting for the process.
5995            mServices.processStartTimedOutLocked(app);
5996            app.kill("start timeout", true);
5997            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5998                Slog.w(TAG, "Unattached app died before backup, skipping");
5999                try {
6000                    IBackupManager bm = IBackupManager.Stub.asInterface(
6001                            ServiceManager.getService(Context.BACKUP_SERVICE));
6002                    bm.agentDisconnected(app.info.packageName);
6003                } catch (RemoteException e) {
6004                    // Can't happen; the backup manager is local
6005                }
6006            }
6007            if (isPendingBroadcastProcessLocked(pid)) {
6008                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6009                skipPendingBroadcastLocked(pid);
6010            }
6011        } else {
6012            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6013        }
6014    }
6015
6016    private final boolean attachApplicationLocked(IApplicationThread thread,
6017            int pid) {
6018
6019        // Find the application record that is being attached...  either via
6020        // the pid if we are running in multiple processes, or just pull the
6021        // next app record if we are emulating process with anonymous threads.
6022        ProcessRecord app;
6023        if (pid != MY_PID && pid >= 0) {
6024            synchronized (mPidsSelfLocked) {
6025                app = mPidsSelfLocked.get(pid);
6026            }
6027        } else {
6028            app = null;
6029        }
6030
6031        if (app == null) {
6032            Slog.w(TAG, "No pending application record for pid " + pid
6033                    + " (IApplicationThread " + thread + "); dropping process");
6034            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6035            if (pid > 0 && pid != MY_PID) {
6036                Process.killProcessQuiet(pid);
6037                //TODO: Process.killProcessGroup(app.info.uid, pid);
6038            } else {
6039                try {
6040                    thread.scheduleExit();
6041                } catch (Exception e) {
6042                    // Ignore exceptions.
6043                }
6044            }
6045            return false;
6046        }
6047
6048        // If this application record is still attached to a previous
6049        // process, clean it up now.
6050        if (app.thread != null) {
6051            handleAppDiedLocked(app, true, true);
6052        }
6053
6054        // Tell the process all about itself.
6055
6056        if (localLOGV) Slog.v(
6057                TAG, "Binding process pid " + pid + " to record " + app);
6058
6059        final String processName = app.processName;
6060        try {
6061            AppDeathRecipient adr = new AppDeathRecipient(
6062                    app, pid, thread);
6063            thread.asBinder().linkToDeath(adr, 0);
6064            app.deathRecipient = adr;
6065        } catch (RemoteException e) {
6066            app.resetPackageList(mProcessStats);
6067            startProcessLocked(app, "link fail", processName);
6068            return false;
6069        }
6070
6071        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6072
6073        app.makeActive(thread, mProcessStats);
6074        app.curAdj = app.setAdj = -100;
6075        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6076        app.forcingToForeground = null;
6077        updateProcessForegroundLocked(app, false, false);
6078        app.hasShownUi = false;
6079        app.debugging = false;
6080        app.cached = false;
6081
6082        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6083
6084        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6085        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6086
6087        if (!normalMode) {
6088            Slog.i(TAG, "Launching preboot mode app: " + app);
6089        }
6090
6091        if (localLOGV) Slog.v(
6092            TAG, "New app record " + app
6093            + " thread=" + thread.asBinder() + " pid=" + pid);
6094        try {
6095            int testMode = IApplicationThread.DEBUG_OFF;
6096            if (mDebugApp != null && mDebugApp.equals(processName)) {
6097                testMode = mWaitForDebugger
6098                    ? IApplicationThread.DEBUG_WAIT
6099                    : IApplicationThread.DEBUG_ON;
6100                app.debugging = true;
6101                if (mDebugTransient) {
6102                    mDebugApp = mOrigDebugApp;
6103                    mWaitForDebugger = mOrigWaitForDebugger;
6104                }
6105            }
6106            String profileFile = app.instrumentationProfileFile;
6107            ParcelFileDescriptor profileFd = null;
6108            int samplingInterval = 0;
6109            boolean profileAutoStop = false;
6110            if (mProfileApp != null && mProfileApp.equals(processName)) {
6111                mProfileProc = app;
6112                profileFile = mProfileFile;
6113                profileFd = mProfileFd;
6114                samplingInterval = mSamplingInterval;
6115                profileAutoStop = mAutoStopProfiler;
6116            }
6117            boolean enableOpenGlTrace = false;
6118            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6119                enableOpenGlTrace = true;
6120                mOpenGlTraceApp = null;
6121            }
6122
6123            // If the app is being launched for restore or full backup, set it up specially
6124            boolean isRestrictedBackupMode = false;
6125            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6126                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6127                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6128                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6129            }
6130
6131            ensurePackageDexOpt(app.instrumentationInfo != null
6132                    ? app.instrumentationInfo.packageName
6133                    : app.info.packageName);
6134            if (app.instrumentationClass != null) {
6135                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6136            }
6137            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6138                    + processName + " with config " + mConfiguration);
6139            ApplicationInfo appInfo = app.instrumentationInfo != null
6140                    ? app.instrumentationInfo : app.info;
6141            app.compat = compatibilityInfoForPackageLocked(appInfo);
6142            if (profileFd != null) {
6143                profileFd = profileFd.dup();
6144            }
6145            ProfilerInfo profilerInfo = profileFile == null ? null
6146                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6147            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6148                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6149                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6150                    isRestrictedBackupMode || !normalMode, app.persistent,
6151                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6152                    mCoreSettingsObserver.getCoreSettingsLocked());
6153            updateLruProcessLocked(app, false, null);
6154            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6155        } catch (Exception e) {
6156            // todo: Yikes!  What should we do?  For now we will try to
6157            // start another process, but that could easily get us in
6158            // an infinite loop of restarting processes...
6159            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6160
6161            app.resetPackageList(mProcessStats);
6162            app.unlinkDeathRecipient();
6163            startProcessLocked(app, "bind fail", processName);
6164            return false;
6165        }
6166
6167        // Remove this record from the list of starting applications.
6168        mPersistentStartingProcesses.remove(app);
6169        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6170                "Attach application locked removing on hold: " + app);
6171        mProcessesOnHold.remove(app);
6172
6173        boolean badApp = false;
6174        boolean didSomething = false;
6175
6176        // See if the top visible activity is waiting to run in this process...
6177        if (normalMode) {
6178            try {
6179                if (mStackSupervisor.attachApplicationLocked(app)) {
6180                    didSomething = true;
6181                }
6182            } catch (Exception e) {
6183                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6184                badApp = true;
6185            }
6186        }
6187
6188        // Find any services that should be running in this process...
6189        if (!badApp) {
6190            try {
6191                didSomething |= mServices.attachApplicationLocked(app, processName);
6192            } catch (Exception e) {
6193                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6194                badApp = true;
6195            }
6196        }
6197
6198        // Check if a next-broadcast receiver is in this process...
6199        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6200            try {
6201                didSomething |= sendPendingBroadcastsLocked(app);
6202            } catch (Exception e) {
6203                // If the app died trying to launch the receiver we declare it 'bad'
6204                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6205                badApp = true;
6206            }
6207        }
6208
6209        // Check whether the next backup agent is in this process...
6210        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6211            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6212            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6213            try {
6214                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6215                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6216                        mBackupTarget.backupMode);
6217            } catch (Exception e) {
6218                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6219                badApp = true;
6220            }
6221        }
6222
6223        if (badApp) {
6224            app.kill("error during init", true);
6225            handleAppDiedLocked(app, false, true);
6226            return false;
6227        }
6228
6229        if (!didSomething) {
6230            updateOomAdjLocked();
6231        }
6232
6233        return true;
6234    }
6235
6236    @Override
6237    public final void attachApplication(IApplicationThread thread) {
6238        synchronized (this) {
6239            int callingPid = Binder.getCallingPid();
6240            final long origId = Binder.clearCallingIdentity();
6241            attachApplicationLocked(thread, callingPid);
6242            Binder.restoreCallingIdentity(origId);
6243        }
6244    }
6245
6246    @Override
6247    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6248        final long origId = Binder.clearCallingIdentity();
6249        synchronized (this) {
6250            ActivityStack stack = ActivityRecord.getStackLocked(token);
6251            if (stack != null) {
6252                ActivityRecord r =
6253                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6254                if (stopProfiling) {
6255                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6256                        try {
6257                            mProfileFd.close();
6258                        } catch (IOException e) {
6259                        }
6260                        clearProfilerLocked();
6261                    }
6262                }
6263            }
6264        }
6265        Binder.restoreCallingIdentity(origId);
6266    }
6267
6268    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6269        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6270                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6271    }
6272
6273    void enableScreenAfterBoot() {
6274        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6275                SystemClock.uptimeMillis());
6276        mWindowManager.enableScreenAfterBoot();
6277
6278        synchronized (this) {
6279            updateEventDispatchingLocked();
6280        }
6281    }
6282
6283    @Override
6284    public void showBootMessage(final CharSequence msg, final boolean always) {
6285        enforceNotIsolatedCaller("showBootMessage");
6286        mWindowManager.showBootMessage(msg, always);
6287    }
6288
6289    @Override
6290    public void keyguardWaitingForActivityDrawn() {
6291        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6292        final long token = Binder.clearCallingIdentity();
6293        try {
6294            synchronized (this) {
6295                if (DEBUG_LOCKSCREEN) logLockScreen("");
6296                mWindowManager.keyguardWaitingForActivityDrawn();
6297                if (mLockScreenShown) {
6298                    mLockScreenShown = false;
6299                    comeOutOfSleepIfNeededLocked();
6300                }
6301            }
6302        } finally {
6303            Binder.restoreCallingIdentity(token);
6304        }
6305    }
6306
6307    final void finishBooting() {
6308        synchronized (this) {
6309            if (!mBootAnimationComplete) {
6310                mCallFinishBooting = true;
6311                return;
6312            }
6313            mCallFinishBooting = false;
6314        }
6315
6316        // Register receivers to handle package update events
6317        mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false);
6318
6319        // Let system services know.
6320        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6321
6322        synchronized (this) {
6323            // Ensure that any processes we had put on hold are now started
6324            // up.
6325            final int NP = mProcessesOnHold.size();
6326            if (NP > 0) {
6327                ArrayList<ProcessRecord> procs =
6328                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6329                for (int ip=0; ip<NP; ip++) {
6330                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6331                            + procs.get(ip));
6332                    startProcessLocked(procs.get(ip), "on-hold", null);
6333                }
6334            }
6335
6336            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6337                // Start looking for apps that are abusing wake locks.
6338                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6339                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6340                // Tell anyone interested that we are done booting!
6341                SystemProperties.set("sys.boot_completed", "1");
6342
6343                // And trigger dev.bootcomplete if we are not showing encryption progress
6344                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6345                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6346                    SystemProperties.set("dev.bootcomplete", "1");
6347                }
6348                for (int i=0; i<mStartedUsers.size(); i++) {
6349                    UserStartedState uss = mStartedUsers.valueAt(i);
6350                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6351                        uss.mState = UserStartedState.STATE_RUNNING;
6352                        final int userId = mStartedUsers.keyAt(i);
6353                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6354                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6355                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6356                        broadcastIntentLocked(null, null, intent, null,
6357                                new IIntentReceiver.Stub() {
6358                                    @Override
6359                                    public void performReceive(Intent intent, int resultCode,
6360                                            String data, Bundle extras, boolean ordered,
6361                                            boolean sticky, int sendingUser) {
6362                                        synchronized (ActivityManagerService.this) {
6363                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6364                                                    true, false);
6365                                        }
6366                                    }
6367                                },
6368                                0, null, null,
6369                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6370                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6371                                userId);
6372                    }
6373                }
6374                scheduleStartProfilesLocked();
6375            }
6376        }
6377    }
6378
6379    @Override
6380    public void bootAnimationComplete() {
6381        final boolean callFinishBooting;
6382        synchronized (this) {
6383            callFinishBooting = mCallFinishBooting;
6384            mBootAnimationComplete = true;
6385        }
6386        if (callFinishBooting) {
6387            finishBooting();
6388        }
6389    }
6390
6391    final void ensureBootCompleted() {
6392        boolean booting;
6393        boolean enableScreen;
6394        synchronized (this) {
6395            booting = mBooting;
6396            mBooting = false;
6397            enableScreen = !mBooted;
6398            mBooted = true;
6399        }
6400
6401        if (booting) {
6402            finishBooting();
6403        }
6404
6405        if (enableScreen) {
6406            enableScreenAfterBoot();
6407        }
6408    }
6409
6410    @Override
6411    public final void activityResumed(IBinder token) {
6412        final long origId = Binder.clearCallingIdentity();
6413        synchronized(this) {
6414            ActivityStack stack = ActivityRecord.getStackLocked(token);
6415            if (stack != null) {
6416                ActivityRecord.activityResumedLocked(token);
6417            }
6418        }
6419        Binder.restoreCallingIdentity(origId);
6420    }
6421
6422    @Override
6423    public final void activityPaused(IBinder token) {
6424        final long origId = Binder.clearCallingIdentity();
6425        synchronized(this) {
6426            ActivityStack stack = ActivityRecord.getStackLocked(token);
6427            if (stack != null) {
6428                stack.activityPausedLocked(token, false);
6429            }
6430        }
6431        Binder.restoreCallingIdentity(origId);
6432    }
6433
6434    @Override
6435    public final void activityStopped(IBinder token, Bundle icicle,
6436            PersistableBundle persistentState, CharSequence description) {
6437        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6438
6439        // Refuse possible leaked file descriptors
6440        if (icicle != null && icicle.hasFileDescriptors()) {
6441            throw new IllegalArgumentException("File descriptors passed in Bundle");
6442        }
6443
6444        final long origId = Binder.clearCallingIdentity();
6445
6446        synchronized (this) {
6447            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6448            if (r != null) {
6449                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6450            }
6451        }
6452
6453        trimApplications();
6454
6455        Binder.restoreCallingIdentity(origId);
6456    }
6457
6458    @Override
6459    public final void activityDestroyed(IBinder token) {
6460        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6461        synchronized (this) {
6462            ActivityStack stack = ActivityRecord.getStackLocked(token);
6463            if (stack != null) {
6464                stack.activityDestroyedLocked(token);
6465            }
6466        }
6467    }
6468
6469    @Override
6470    public final void backgroundResourcesReleased(IBinder token) {
6471        final long origId = Binder.clearCallingIdentity();
6472        try {
6473            synchronized (this) {
6474                ActivityStack stack = ActivityRecord.getStackLocked(token);
6475                if (stack != null) {
6476                    stack.backgroundResourcesReleased(token);
6477                }
6478            }
6479        } finally {
6480            Binder.restoreCallingIdentity(origId);
6481        }
6482    }
6483
6484    @Override
6485    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6486        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6487    }
6488
6489    @Override
6490    public final void notifyEnterAnimationComplete(IBinder token) {
6491        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6492    }
6493
6494    @Override
6495    public String getCallingPackage(IBinder token) {
6496        synchronized (this) {
6497            ActivityRecord r = getCallingRecordLocked(token);
6498            return r != null ? r.info.packageName : null;
6499        }
6500    }
6501
6502    @Override
6503    public ComponentName getCallingActivity(IBinder token) {
6504        synchronized (this) {
6505            ActivityRecord r = getCallingRecordLocked(token);
6506            return r != null ? r.intent.getComponent() : null;
6507        }
6508    }
6509
6510    private ActivityRecord getCallingRecordLocked(IBinder token) {
6511        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6512        if (r == null) {
6513            return null;
6514        }
6515        return r.resultTo;
6516    }
6517
6518    @Override
6519    public ComponentName getActivityClassForToken(IBinder token) {
6520        synchronized(this) {
6521            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6522            if (r == null) {
6523                return null;
6524            }
6525            return r.intent.getComponent();
6526        }
6527    }
6528
6529    @Override
6530    public String getPackageForToken(IBinder token) {
6531        synchronized(this) {
6532            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6533            if (r == null) {
6534                return null;
6535            }
6536            return r.packageName;
6537        }
6538    }
6539
6540    @Override
6541    public IIntentSender getIntentSender(int type,
6542            String packageName, IBinder token, String resultWho,
6543            int requestCode, Intent[] intents, String[] resolvedTypes,
6544            int flags, Bundle options, int userId) {
6545        enforceNotIsolatedCaller("getIntentSender");
6546        // Refuse possible leaked file descriptors
6547        if (intents != null) {
6548            if (intents.length < 1) {
6549                throw new IllegalArgumentException("Intents array length must be >= 1");
6550            }
6551            for (int i=0; i<intents.length; i++) {
6552                Intent intent = intents[i];
6553                if (intent != null) {
6554                    if (intent.hasFileDescriptors()) {
6555                        throw new IllegalArgumentException("File descriptors passed in Intent");
6556                    }
6557                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6558                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6559                        throw new IllegalArgumentException(
6560                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6561                    }
6562                    intents[i] = new Intent(intent);
6563                }
6564            }
6565            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6566                throw new IllegalArgumentException(
6567                        "Intent array length does not match resolvedTypes length");
6568            }
6569        }
6570        if (options != null) {
6571            if (options.hasFileDescriptors()) {
6572                throw new IllegalArgumentException("File descriptors passed in options");
6573            }
6574        }
6575
6576        synchronized(this) {
6577            int callingUid = Binder.getCallingUid();
6578            int origUserId = userId;
6579            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6580                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6581                    ALLOW_NON_FULL, "getIntentSender", null);
6582            if (origUserId == UserHandle.USER_CURRENT) {
6583                // We don't want to evaluate this until the pending intent is
6584                // actually executed.  However, we do want to always do the
6585                // security checking for it above.
6586                userId = UserHandle.USER_CURRENT;
6587            }
6588            try {
6589                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6590                    int uid = AppGlobals.getPackageManager()
6591                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6592                    if (!UserHandle.isSameApp(callingUid, uid)) {
6593                        String msg = "Permission Denial: getIntentSender() from pid="
6594                            + Binder.getCallingPid()
6595                            + ", uid=" + Binder.getCallingUid()
6596                            + ", (need uid=" + uid + ")"
6597                            + " is not allowed to send as package " + packageName;
6598                        Slog.w(TAG, msg);
6599                        throw new SecurityException(msg);
6600                    }
6601                }
6602
6603                return getIntentSenderLocked(type, packageName, callingUid, userId,
6604                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6605
6606            } catch (RemoteException e) {
6607                throw new SecurityException(e);
6608            }
6609        }
6610    }
6611
6612    IIntentSender getIntentSenderLocked(int type, String packageName,
6613            int callingUid, int userId, IBinder token, String resultWho,
6614            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6615            Bundle options) {
6616        if (DEBUG_MU)
6617            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6618        ActivityRecord activity = null;
6619        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6620            activity = ActivityRecord.isInStackLocked(token);
6621            if (activity == null) {
6622                return null;
6623            }
6624            if (activity.finishing) {
6625                return null;
6626            }
6627        }
6628
6629        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6630        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6631        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6632        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6633                |PendingIntent.FLAG_UPDATE_CURRENT);
6634
6635        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6636                type, packageName, activity, resultWho,
6637                requestCode, intents, resolvedTypes, flags, options, userId);
6638        WeakReference<PendingIntentRecord> ref;
6639        ref = mIntentSenderRecords.get(key);
6640        PendingIntentRecord rec = ref != null ? ref.get() : null;
6641        if (rec != null) {
6642            if (!cancelCurrent) {
6643                if (updateCurrent) {
6644                    if (rec.key.requestIntent != null) {
6645                        rec.key.requestIntent.replaceExtras(intents != null ?
6646                                intents[intents.length - 1] : null);
6647                    }
6648                    if (intents != null) {
6649                        intents[intents.length-1] = rec.key.requestIntent;
6650                        rec.key.allIntents = intents;
6651                        rec.key.allResolvedTypes = resolvedTypes;
6652                    } else {
6653                        rec.key.allIntents = null;
6654                        rec.key.allResolvedTypes = null;
6655                    }
6656                }
6657                return rec;
6658            }
6659            rec.canceled = true;
6660            mIntentSenderRecords.remove(key);
6661        }
6662        if (noCreate) {
6663            return rec;
6664        }
6665        rec = new PendingIntentRecord(this, key, callingUid);
6666        mIntentSenderRecords.put(key, rec.ref);
6667        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6668            if (activity.pendingResults == null) {
6669                activity.pendingResults
6670                        = new HashSet<WeakReference<PendingIntentRecord>>();
6671            }
6672            activity.pendingResults.add(rec.ref);
6673        }
6674        return rec;
6675    }
6676
6677    @Override
6678    public void cancelIntentSender(IIntentSender sender) {
6679        if (!(sender instanceof PendingIntentRecord)) {
6680            return;
6681        }
6682        synchronized(this) {
6683            PendingIntentRecord rec = (PendingIntentRecord)sender;
6684            try {
6685                int uid = AppGlobals.getPackageManager()
6686                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6687                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6688                    String msg = "Permission Denial: cancelIntentSender() from pid="
6689                        + Binder.getCallingPid()
6690                        + ", uid=" + Binder.getCallingUid()
6691                        + " is not allowed to cancel packges "
6692                        + rec.key.packageName;
6693                    Slog.w(TAG, msg);
6694                    throw new SecurityException(msg);
6695                }
6696            } catch (RemoteException e) {
6697                throw new SecurityException(e);
6698            }
6699            cancelIntentSenderLocked(rec, true);
6700        }
6701    }
6702
6703    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6704        rec.canceled = true;
6705        mIntentSenderRecords.remove(rec.key);
6706        if (cleanActivity && rec.key.activity != null) {
6707            rec.key.activity.pendingResults.remove(rec.ref);
6708        }
6709    }
6710
6711    @Override
6712    public String getPackageForIntentSender(IIntentSender pendingResult) {
6713        if (!(pendingResult instanceof PendingIntentRecord)) {
6714            return null;
6715        }
6716        try {
6717            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6718            return res.key.packageName;
6719        } catch (ClassCastException e) {
6720        }
6721        return null;
6722    }
6723
6724    @Override
6725    public int getUidForIntentSender(IIntentSender sender) {
6726        if (sender instanceof PendingIntentRecord) {
6727            try {
6728                PendingIntentRecord res = (PendingIntentRecord)sender;
6729                return res.uid;
6730            } catch (ClassCastException e) {
6731            }
6732        }
6733        return -1;
6734    }
6735
6736    @Override
6737    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6738        if (!(pendingResult instanceof PendingIntentRecord)) {
6739            return false;
6740        }
6741        try {
6742            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6743            if (res.key.allIntents == null) {
6744                return false;
6745            }
6746            for (int i=0; i<res.key.allIntents.length; i++) {
6747                Intent intent = res.key.allIntents[i];
6748                if (intent.getPackage() != null && intent.getComponent() != null) {
6749                    return false;
6750                }
6751            }
6752            return true;
6753        } catch (ClassCastException e) {
6754        }
6755        return false;
6756    }
6757
6758    @Override
6759    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6760        if (!(pendingResult instanceof PendingIntentRecord)) {
6761            return false;
6762        }
6763        try {
6764            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6765            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6766                return true;
6767            }
6768            return false;
6769        } catch (ClassCastException e) {
6770        }
6771        return false;
6772    }
6773
6774    @Override
6775    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6776        if (!(pendingResult instanceof PendingIntentRecord)) {
6777            return null;
6778        }
6779        try {
6780            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6781            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6782        } catch (ClassCastException e) {
6783        }
6784        return null;
6785    }
6786
6787    @Override
6788    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6789        if (!(pendingResult instanceof PendingIntentRecord)) {
6790            return null;
6791        }
6792        try {
6793            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6794            Intent intent = res.key.requestIntent;
6795            if (intent != null) {
6796                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6797                        || res.lastTagPrefix.equals(prefix))) {
6798                    return res.lastTag;
6799                }
6800                res.lastTagPrefix = prefix;
6801                StringBuilder sb = new StringBuilder(128);
6802                if (prefix != null) {
6803                    sb.append(prefix);
6804                }
6805                if (intent.getAction() != null) {
6806                    sb.append(intent.getAction());
6807                } else if (intent.getComponent() != null) {
6808                    intent.getComponent().appendShortString(sb);
6809                } else {
6810                    sb.append("?");
6811                }
6812                return res.lastTag = sb.toString();
6813            }
6814        } catch (ClassCastException e) {
6815        }
6816        return null;
6817    }
6818
6819    @Override
6820    public void setProcessLimit(int max) {
6821        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6822                "setProcessLimit()");
6823        synchronized (this) {
6824            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6825            mProcessLimitOverride = max;
6826        }
6827        trimApplications();
6828    }
6829
6830    @Override
6831    public int getProcessLimit() {
6832        synchronized (this) {
6833            return mProcessLimitOverride;
6834        }
6835    }
6836
6837    void foregroundTokenDied(ForegroundToken token) {
6838        synchronized (ActivityManagerService.this) {
6839            synchronized (mPidsSelfLocked) {
6840                ForegroundToken cur
6841                    = mForegroundProcesses.get(token.pid);
6842                if (cur != token) {
6843                    return;
6844                }
6845                mForegroundProcesses.remove(token.pid);
6846                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6847                if (pr == null) {
6848                    return;
6849                }
6850                pr.forcingToForeground = null;
6851                updateProcessForegroundLocked(pr, false, false);
6852            }
6853            updateOomAdjLocked();
6854        }
6855    }
6856
6857    @Override
6858    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6859        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6860                "setProcessForeground()");
6861        synchronized(this) {
6862            boolean changed = false;
6863
6864            synchronized (mPidsSelfLocked) {
6865                ProcessRecord pr = mPidsSelfLocked.get(pid);
6866                if (pr == null && isForeground) {
6867                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6868                    return;
6869                }
6870                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6871                if (oldToken != null) {
6872                    oldToken.token.unlinkToDeath(oldToken, 0);
6873                    mForegroundProcesses.remove(pid);
6874                    if (pr != null) {
6875                        pr.forcingToForeground = null;
6876                    }
6877                    changed = true;
6878                }
6879                if (isForeground && token != null) {
6880                    ForegroundToken newToken = new ForegroundToken() {
6881                        @Override
6882                        public void binderDied() {
6883                            foregroundTokenDied(this);
6884                        }
6885                    };
6886                    newToken.pid = pid;
6887                    newToken.token = token;
6888                    try {
6889                        token.linkToDeath(newToken, 0);
6890                        mForegroundProcesses.put(pid, newToken);
6891                        pr.forcingToForeground = token;
6892                        changed = true;
6893                    } catch (RemoteException e) {
6894                        // If the process died while doing this, we will later
6895                        // do the cleanup with the process death link.
6896                    }
6897                }
6898            }
6899
6900            if (changed) {
6901                updateOomAdjLocked();
6902            }
6903        }
6904    }
6905
6906    // =========================================================
6907    // PERMISSIONS
6908    // =========================================================
6909
6910    static class PermissionController extends IPermissionController.Stub {
6911        ActivityManagerService mActivityManagerService;
6912        PermissionController(ActivityManagerService activityManagerService) {
6913            mActivityManagerService = activityManagerService;
6914        }
6915
6916        @Override
6917        public boolean checkPermission(String permission, int pid, int uid) {
6918            return mActivityManagerService.checkPermission(permission, pid,
6919                    uid) == PackageManager.PERMISSION_GRANTED;
6920        }
6921    }
6922
6923    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6924        @Override
6925        public int checkComponentPermission(String permission, int pid, int uid,
6926                int owningUid, boolean exported) {
6927            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6928                    owningUid, exported);
6929        }
6930
6931        @Override
6932        public Object getAMSLock() {
6933            return ActivityManagerService.this;
6934        }
6935    }
6936
6937    /**
6938     * This can be called with or without the global lock held.
6939     */
6940    int checkComponentPermission(String permission, int pid, int uid,
6941            int owningUid, boolean exported) {
6942        // We might be performing an operation on behalf of an indirect binder
6943        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6944        // client identity accordingly before proceeding.
6945        Identity tlsIdentity = sCallerIdentity.get();
6946        if (tlsIdentity != null) {
6947            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6948                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6949            uid = tlsIdentity.uid;
6950            pid = tlsIdentity.pid;
6951        }
6952
6953        if (pid == MY_PID) {
6954            return PackageManager.PERMISSION_GRANTED;
6955        }
6956
6957        return ActivityManager.checkComponentPermission(permission, uid,
6958                owningUid, exported);
6959    }
6960
6961    /**
6962     * As the only public entry point for permissions checking, this method
6963     * can enforce the semantic that requesting a check on a null global
6964     * permission is automatically denied.  (Internally a null permission
6965     * string is used when calling {@link #checkComponentPermission} in cases
6966     * when only uid-based security is needed.)
6967     *
6968     * This can be called with or without the global lock held.
6969     */
6970    @Override
6971    public int checkPermission(String permission, int pid, int uid) {
6972        if (permission == null) {
6973            return PackageManager.PERMISSION_DENIED;
6974        }
6975        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6976    }
6977
6978    /**
6979     * Binder IPC calls go through the public entry point.
6980     * This can be called with or without the global lock held.
6981     */
6982    int checkCallingPermission(String permission) {
6983        return checkPermission(permission,
6984                Binder.getCallingPid(),
6985                UserHandle.getAppId(Binder.getCallingUid()));
6986    }
6987
6988    /**
6989     * This can be called with or without the global lock held.
6990     */
6991    void enforceCallingPermission(String permission, String func) {
6992        if (checkCallingPermission(permission)
6993                == PackageManager.PERMISSION_GRANTED) {
6994            return;
6995        }
6996
6997        String msg = "Permission Denial: " + func + " from pid="
6998                + Binder.getCallingPid()
6999                + ", uid=" + Binder.getCallingUid()
7000                + " requires " + permission;
7001        Slog.w(TAG, msg);
7002        throw new SecurityException(msg);
7003    }
7004
7005    /**
7006     * Determine if UID is holding permissions required to access {@link Uri} in
7007     * the given {@link ProviderInfo}. Final permission checking is always done
7008     * in {@link ContentProvider}.
7009     */
7010    private final boolean checkHoldingPermissionsLocked(
7011            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7012        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7013                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7014        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7015            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7016                    != PERMISSION_GRANTED) {
7017                return false;
7018            }
7019        }
7020        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7021    }
7022
7023    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7024            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7025        if (pi.applicationInfo.uid == uid) {
7026            return true;
7027        } else if (!pi.exported) {
7028            return false;
7029        }
7030
7031        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7032        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7033        try {
7034            // check if target holds top-level <provider> permissions
7035            if (!readMet && pi.readPermission != null && considerUidPermissions
7036                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7037                readMet = true;
7038            }
7039            if (!writeMet && pi.writePermission != null && considerUidPermissions
7040                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7041                writeMet = true;
7042            }
7043
7044            // track if unprotected read/write is allowed; any denied
7045            // <path-permission> below removes this ability
7046            boolean allowDefaultRead = pi.readPermission == null;
7047            boolean allowDefaultWrite = pi.writePermission == null;
7048
7049            // check if target holds any <path-permission> that match uri
7050            final PathPermission[] pps = pi.pathPermissions;
7051            if (pps != null) {
7052                final String path = grantUri.uri.getPath();
7053                int i = pps.length;
7054                while (i > 0 && (!readMet || !writeMet)) {
7055                    i--;
7056                    PathPermission pp = pps[i];
7057                    if (pp.match(path)) {
7058                        if (!readMet) {
7059                            final String pprperm = pp.getReadPermission();
7060                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
7061                                    + pprperm + " for " + pp.getPath()
7062                                    + ": match=" + pp.match(path)
7063                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7064                            if (pprperm != null) {
7065                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7066                                        == PERMISSION_GRANTED) {
7067                                    readMet = true;
7068                                } else {
7069                                    allowDefaultRead = false;
7070                                }
7071                            }
7072                        }
7073                        if (!writeMet) {
7074                            final String ppwperm = pp.getWritePermission();
7075                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
7076                                    + ppwperm + " for " + pp.getPath()
7077                                    + ": match=" + pp.match(path)
7078                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7079                            if (ppwperm != null) {
7080                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7081                                        == PERMISSION_GRANTED) {
7082                                    writeMet = true;
7083                                } else {
7084                                    allowDefaultWrite = false;
7085                                }
7086                            }
7087                        }
7088                    }
7089                }
7090            }
7091
7092            // grant unprotected <provider> read/write, if not blocked by
7093            // <path-permission> above
7094            if (allowDefaultRead) readMet = true;
7095            if (allowDefaultWrite) writeMet = true;
7096
7097        } catch (RemoteException e) {
7098            return false;
7099        }
7100
7101        return readMet && writeMet;
7102    }
7103
7104    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7105        ProviderInfo pi = null;
7106        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7107        if (cpr != null) {
7108            pi = cpr.info;
7109        } else {
7110            try {
7111                pi = AppGlobals.getPackageManager().resolveContentProvider(
7112                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7113            } catch (RemoteException ex) {
7114            }
7115        }
7116        return pi;
7117    }
7118
7119    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7120        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7121        if (targetUris != null) {
7122            return targetUris.get(grantUri);
7123        }
7124        return null;
7125    }
7126
7127    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7128            String targetPkg, int targetUid, GrantUri grantUri) {
7129        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7130        if (targetUris == null) {
7131            targetUris = Maps.newArrayMap();
7132            mGrantedUriPermissions.put(targetUid, targetUris);
7133        }
7134
7135        UriPermission perm = targetUris.get(grantUri);
7136        if (perm == null) {
7137            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7138            targetUris.put(grantUri, perm);
7139        }
7140
7141        return perm;
7142    }
7143
7144    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7145            final int modeFlags) {
7146        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7147        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7148                : UriPermission.STRENGTH_OWNED;
7149
7150        // Root gets to do everything.
7151        if (uid == 0) {
7152            return true;
7153        }
7154
7155        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7156        if (perms == null) return false;
7157
7158        // First look for exact match
7159        final UriPermission exactPerm = perms.get(grantUri);
7160        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7161            return true;
7162        }
7163
7164        // No exact match, look for prefixes
7165        final int N = perms.size();
7166        for (int i = 0; i < N; i++) {
7167            final UriPermission perm = perms.valueAt(i);
7168            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7169                    && perm.getStrength(modeFlags) >= minStrength) {
7170                return true;
7171            }
7172        }
7173
7174        return false;
7175    }
7176
7177    /**
7178     * @param uri This uri must NOT contain an embedded userId.
7179     * @param userId The userId in which the uri is to be resolved.
7180     */
7181    @Override
7182    public int checkUriPermission(Uri uri, int pid, int uid,
7183            final int modeFlags, int userId) {
7184        enforceNotIsolatedCaller("checkUriPermission");
7185
7186        // Another redirected-binder-call permissions check as in
7187        // {@link checkComponentPermission}.
7188        Identity tlsIdentity = sCallerIdentity.get();
7189        if (tlsIdentity != null) {
7190            uid = tlsIdentity.uid;
7191            pid = tlsIdentity.pid;
7192        }
7193
7194        // Our own process gets to do everything.
7195        if (pid == MY_PID) {
7196            return PackageManager.PERMISSION_GRANTED;
7197        }
7198        synchronized (this) {
7199            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7200                    ? PackageManager.PERMISSION_GRANTED
7201                    : PackageManager.PERMISSION_DENIED;
7202        }
7203    }
7204
7205    /**
7206     * Check if the targetPkg can be granted permission to access uri by
7207     * the callingUid using the given modeFlags.  Throws a security exception
7208     * if callingUid is not allowed to do this.  Returns the uid of the target
7209     * if the URI permission grant should be performed; returns -1 if it is not
7210     * needed (for example targetPkg already has permission to access the URI).
7211     * If you already know the uid of the target, you can supply it in
7212     * lastTargetUid else set that to -1.
7213     */
7214    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7215            final int modeFlags, int lastTargetUid) {
7216        if (!Intent.isAccessUriMode(modeFlags)) {
7217            return -1;
7218        }
7219
7220        if (targetPkg != null) {
7221            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7222                    "Checking grant " + targetPkg + " permission to " + grantUri);
7223        }
7224
7225        final IPackageManager pm = AppGlobals.getPackageManager();
7226
7227        // If this is not a content: uri, we can't do anything with it.
7228        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7229            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7230                    "Can't grant URI permission for non-content URI: " + grantUri);
7231            return -1;
7232        }
7233
7234        final String authority = grantUri.uri.getAuthority();
7235        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7236        if (pi == null) {
7237            Slog.w(TAG, "No content provider found for permission check: " +
7238                    grantUri.uri.toSafeString());
7239            return -1;
7240        }
7241
7242        int targetUid = lastTargetUid;
7243        if (targetUid < 0 && targetPkg != null) {
7244            try {
7245                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7246                if (targetUid < 0) {
7247                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7248                            "Can't grant URI permission no uid for: " + targetPkg);
7249                    return -1;
7250                }
7251            } catch (RemoteException ex) {
7252                return -1;
7253            }
7254        }
7255
7256        if (targetUid >= 0) {
7257            // First...  does the target actually need this permission?
7258            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7259                // No need to grant the target this permission.
7260                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7261                        "Target " + targetPkg + " already has full permission to " + grantUri);
7262                return -1;
7263            }
7264        } else {
7265            // First...  there is no target package, so can anyone access it?
7266            boolean allowed = pi.exported;
7267            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7268                if (pi.readPermission != null) {
7269                    allowed = false;
7270                }
7271            }
7272            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7273                if (pi.writePermission != null) {
7274                    allowed = false;
7275                }
7276            }
7277            if (allowed) {
7278                return -1;
7279            }
7280        }
7281
7282        /* There is a special cross user grant if:
7283         * - The target is on another user.
7284         * - Apps on the current user can access the uri without any uid permissions.
7285         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7286         * grant uri permissions.
7287         */
7288        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7289                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7290                modeFlags, false /*without considering the uid permissions*/);
7291
7292        // Second...  is the provider allowing granting of URI permissions?
7293        if (!specialCrossUserGrant) {
7294            if (!pi.grantUriPermissions) {
7295                throw new SecurityException("Provider " + pi.packageName
7296                        + "/" + pi.name
7297                        + " does not allow granting of Uri permissions (uri "
7298                        + grantUri + ")");
7299            }
7300            if (pi.uriPermissionPatterns != null) {
7301                final int N = pi.uriPermissionPatterns.length;
7302                boolean allowed = false;
7303                for (int i=0; i<N; i++) {
7304                    if (pi.uriPermissionPatterns[i] != null
7305                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7306                        allowed = true;
7307                        break;
7308                    }
7309                }
7310                if (!allowed) {
7311                    throw new SecurityException("Provider " + pi.packageName
7312                            + "/" + pi.name
7313                            + " does not allow granting of permission to path of Uri "
7314                            + grantUri);
7315                }
7316            }
7317        }
7318
7319        // Third...  does the caller itself have permission to access
7320        // this uri?
7321        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7322            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7323                // Require they hold a strong enough Uri permission
7324                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7325                    throw new SecurityException("Uid " + callingUid
7326                            + " does not have permission to uri " + grantUri);
7327                }
7328            }
7329        }
7330        return targetUid;
7331    }
7332
7333    /**
7334     * @param uri This uri must NOT contain an embedded userId.
7335     * @param userId The userId in which the uri is to be resolved.
7336     */
7337    @Override
7338    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7339            final int modeFlags, int userId) {
7340        enforceNotIsolatedCaller("checkGrantUriPermission");
7341        synchronized(this) {
7342            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7343                    new GrantUri(userId, uri, false), modeFlags, -1);
7344        }
7345    }
7346
7347    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7348            final int modeFlags, UriPermissionOwner owner) {
7349        if (!Intent.isAccessUriMode(modeFlags)) {
7350            return;
7351        }
7352
7353        // So here we are: the caller has the assumed permission
7354        // to the uri, and the target doesn't.  Let's now give this to
7355        // the target.
7356
7357        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7358                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7359
7360        final String authority = grantUri.uri.getAuthority();
7361        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7362        if (pi == null) {
7363            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7364            return;
7365        }
7366
7367        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7368            grantUri.prefix = true;
7369        }
7370        final UriPermission perm = findOrCreateUriPermissionLocked(
7371                pi.packageName, targetPkg, targetUid, grantUri);
7372        perm.grantModes(modeFlags, owner);
7373    }
7374
7375    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7376            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7377        if (targetPkg == null) {
7378            throw new NullPointerException("targetPkg");
7379        }
7380        int targetUid;
7381        final IPackageManager pm = AppGlobals.getPackageManager();
7382        try {
7383            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7384        } catch (RemoteException ex) {
7385            return;
7386        }
7387
7388        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7389                targetUid);
7390        if (targetUid < 0) {
7391            return;
7392        }
7393
7394        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7395                owner);
7396    }
7397
7398    static class NeededUriGrants extends ArrayList<GrantUri> {
7399        final String targetPkg;
7400        final int targetUid;
7401        final int flags;
7402
7403        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7404            this.targetPkg = targetPkg;
7405            this.targetUid = targetUid;
7406            this.flags = flags;
7407        }
7408    }
7409
7410    /**
7411     * Like checkGrantUriPermissionLocked, but takes an Intent.
7412     */
7413    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7414            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7415        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7416                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7417                + " clip=" + (intent != null ? intent.getClipData() : null)
7418                + " from " + intent + "; flags=0x"
7419                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7420
7421        if (targetPkg == null) {
7422            throw new NullPointerException("targetPkg");
7423        }
7424
7425        if (intent == null) {
7426            return null;
7427        }
7428        Uri data = intent.getData();
7429        ClipData clip = intent.getClipData();
7430        if (data == null && clip == null) {
7431            return null;
7432        }
7433        // Default userId for uris in the intent (if they don't specify it themselves)
7434        int contentUserHint = intent.getContentUserHint();
7435        if (contentUserHint == UserHandle.USER_CURRENT) {
7436            contentUserHint = UserHandle.getUserId(callingUid);
7437        }
7438        final IPackageManager pm = AppGlobals.getPackageManager();
7439        int targetUid;
7440        if (needed != null) {
7441            targetUid = needed.targetUid;
7442        } else {
7443            try {
7444                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7445            } catch (RemoteException ex) {
7446                return null;
7447            }
7448            if (targetUid < 0) {
7449                if (DEBUG_URI_PERMISSION) {
7450                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7451                            + " on user " + targetUserId);
7452                }
7453                return null;
7454            }
7455        }
7456        if (data != null) {
7457            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7458            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7459                    targetUid);
7460            if (targetUid > 0) {
7461                if (needed == null) {
7462                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7463                }
7464                needed.add(grantUri);
7465            }
7466        }
7467        if (clip != null) {
7468            for (int i=0; i<clip.getItemCount(); i++) {
7469                Uri uri = clip.getItemAt(i).getUri();
7470                if (uri != null) {
7471                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7472                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7473                            targetUid);
7474                    if (targetUid > 0) {
7475                        if (needed == null) {
7476                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7477                        }
7478                        needed.add(grantUri);
7479                    }
7480                } else {
7481                    Intent clipIntent = clip.getItemAt(i).getIntent();
7482                    if (clipIntent != null) {
7483                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7484                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7485                        if (newNeeded != null) {
7486                            needed = newNeeded;
7487                        }
7488                    }
7489                }
7490            }
7491        }
7492
7493        return needed;
7494    }
7495
7496    /**
7497     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7498     */
7499    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7500            UriPermissionOwner owner) {
7501        if (needed != null) {
7502            for (int i=0; i<needed.size(); i++) {
7503                GrantUri grantUri = needed.get(i);
7504                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7505                        grantUri, needed.flags, owner);
7506            }
7507        }
7508    }
7509
7510    void grantUriPermissionFromIntentLocked(int callingUid,
7511            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7512        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7513                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7514        if (needed == null) {
7515            return;
7516        }
7517
7518        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7519    }
7520
7521    /**
7522     * @param uri This uri must NOT contain an embedded userId.
7523     * @param userId The userId in which the uri is to be resolved.
7524     */
7525    @Override
7526    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7527            final int modeFlags, int userId) {
7528        enforceNotIsolatedCaller("grantUriPermission");
7529        GrantUri grantUri = new GrantUri(userId, uri, false);
7530        synchronized(this) {
7531            final ProcessRecord r = getRecordForAppLocked(caller);
7532            if (r == null) {
7533                throw new SecurityException("Unable to find app for caller "
7534                        + caller
7535                        + " when granting permission to uri " + grantUri);
7536            }
7537            if (targetPkg == null) {
7538                throw new IllegalArgumentException("null target");
7539            }
7540            if (grantUri == null) {
7541                throw new IllegalArgumentException("null uri");
7542            }
7543
7544            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7545                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7546                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7547                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7548
7549            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7550                    UserHandle.getUserId(r.uid));
7551        }
7552    }
7553
7554    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7555        if (perm.modeFlags == 0) {
7556            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7557                    perm.targetUid);
7558            if (perms != null) {
7559                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7560                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7561
7562                perms.remove(perm.uri);
7563                if (perms.isEmpty()) {
7564                    mGrantedUriPermissions.remove(perm.targetUid);
7565                }
7566            }
7567        }
7568    }
7569
7570    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7571        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7572
7573        final IPackageManager pm = AppGlobals.getPackageManager();
7574        final String authority = grantUri.uri.getAuthority();
7575        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7576        if (pi == null) {
7577            Slog.w(TAG, "No content provider found for permission revoke: "
7578                    + grantUri.toSafeString());
7579            return;
7580        }
7581
7582        // Does the caller have this permission on the URI?
7583        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7584            // If they don't have direct access to the URI, then revoke any
7585            // ownerless URI permissions that have been granted to them.
7586            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7587            if (perms != null) {
7588                boolean persistChanged = false;
7589                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7590                    final UriPermission perm = it.next();
7591                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7592                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7593                        if (DEBUG_URI_PERMISSION)
7594                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7595                                    " permission to " + perm.uri);
7596                        persistChanged |= perm.revokeModes(
7597                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7598                        if (perm.modeFlags == 0) {
7599                            it.remove();
7600                        }
7601                    }
7602                }
7603                if (perms.isEmpty()) {
7604                    mGrantedUriPermissions.remove(callingUid);
7605                }
7606                if (persistChanged) {
7607                    schedulePersistUriGrants();
7608                }
7609            }
7610            return;
7611        }
7612
7613        boolean persistChanged = false;
7614
7615        // Go through all of the permissions and remove any that match.
7616        int N = mGrantedUriPermissions.size();
7617        for (int i = 0; i < N; i++) {
7618            final int targetUid = mGrantedUriPermissions.keyAt(i);
7619            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7620
7621            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7622                final UriPermission perm = it.next();
7623                if (perm.uri.sourceUserId == grantUri.sourceUserId
7624                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7625                    if (DEBUG_URI_PERMISSION)
7626                        Slog.v(TAG,
7627                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7628                    persistChanged |= perm.revokeModes(
7629                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7630                    if (perm.modeFlags == 0) {
7631                        it.remove();
7632                    }
7633                }
7634            }
7635
7636            if (perms.isEmpty()) {
7637                mGrantedUriPermissions.remove(targetUid);
7638                N--;
7639                i--;
7640            }
7641        }
7642
7643        if (persistChanged) {
7644            schedulePersistUriGrants();
7645        }
7646    }
7647
7648    /**
7649     * @param uri This uri must NOT contain an embedded userId.
7650     * @param userId The userId in which the uri is to be resolved.
7651     */
7652    @Override
7653    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7654            int userId) {
7655        enforceNotIsolatedCaller("revokeUriPermission");
7656        synchronized(this) {
7657            final ProcessRecord r = getRecordForAppLocked(caller);
7658            if (r == null) {
7659                throw new SecurityException("Unable to find app for caller "
7660                        + caller
7661                        + " when revoking permission to uri " + uri);
7662            }
7663            if (uri == null) {
7664                Slog.w(TAG, "revokeUriPermission: null uri");
7665                return;
7666            }
7667
7668            if (!Intent.isAccessUriMode(modeFlags)) {
7669                return;
7670            }
7671
7672            final IPackageManager pm = AppGlobals.getPackageManager();
7673            final String authority = uri.getAuthority();
7674            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7675            if (pi == null) {
7676                Slog.w(TAG, "No content provider found for permission revoke: "
7677                        + uri.toSafeString());
7678                return;
7679            }
7680
7681            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7682        }
7683    }
7684
7685    /**
7686     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7687     * given package.
7688     *
7689     * @param packageName Package name to match, or {@code null} to apply to all
7690     *            packages.
7691     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7692     *            to all users.
7693     * @param persistable If persistable grants should be removed.
7694     */
7695    private void removeUriPermissionsForPackageLocked(
7696            String packageName, int userHandle, boolean persistable) {
7697        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7698            throw new IllegalArgumentException("Must narrow by either package or user");
7699        }
7700
7701        boolean persistChanged = false;
7702
7703        int N = mGrantedUriPermissions.size();
7704        for (int i = 0; i < N; i++) {
7705            final int targetUid = mGrantedUriPermissions.keyAt(i);
7706            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7707
7708            // Only inspect grants matching user
7709            if (userHandle == UserHandle.USER_ALL
7710                    || userHandle == UserHandle.getUserId(targetUid)) {
7711                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7712                    final UriPermission perm = it.next();
7713
7714                    // Only inspect grants matching package
7715                    if (packageName == null || perm.sourcePkg.equals(packageName)
7716                            || perm.targetPkg.equals(packageName)) {
7717                        persistChanged |= perm.revokeModes(persistable
7718                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7719
7720                        // Only remove when no modes remain; any persisted grants
7721                        // will keep this alive.
7722                        if (perm.modeFlags == 0) {
7723                            it.remove();
7724                        }
7725                    }
7726                }
7727
7728                if (perms.isEmpty()) {
7729                    mGrantedUriPermissions.remove(targetUid);
7730                    N--;
7731                    i--;
7732                }
7733            }
7734        }
7735
7736        if (persistChanged) {
7737            schedulePersistUriGrants();
7738        }
7739    }
7740
7741    @Override
7742    public IBinder newUriPermissionOwner(String name) {
7743        enforceNotIsolatedCaller("newUriPermissionOwner");
7744        synchronized(this) {
7745            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7746            return owner.getExternalTokenLocked();
7747        }
7748    }
7749
7750    /**
7751     * @param uri This uri must NOT contain an embedded userId.
7752     * @param sourceUserId The userId in which the uri is to be resolved.
7753     * @param targetUserId The userId of the app that receives the grant.
7754     */
7755    @Override
7756    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7757            final int modeFlags, int sourceUserId, int targetUserId) {
7758        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7759                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7760        synchronized(this) {
7761            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7762            if (owner == null) {
7763                throw new IllegalArgumentException("Unknown owner: " + token);
7764            }
7765            if (fromUid != Binder.getCallingUid()) {
7766                if (Binder.getCallingUid() != Process.myUid()) {
7767                    // Only system code can grant URI permissions on behalf
7768                    // of other users.
7769                    throw new SecurityException("nice try");
7770                }
7771            }
7772            if (targetPkg == null) {
7773                throw new IllegalArgumentException("null target");
7774            }
7775            if (uri == null) {
7776                throw new IllegalArgumentException("null uri");
7777            }
7778
7779            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7780                    modeFlags, owner, targetUserId);
7781        }
7782    }
7783
7784    /**
7785     * @param uri This uri must NOT contain an embedded userId.
7786     * @param userId The userId in which the uri is to be resolved.
7787     */
7788    @Override
7789    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7790        synchronized(this) {
7791            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7792            if (owner == null) {
7793                throw new IllegalArgumentException("Unknown owner: " + token);
7794            }
7795
7796            if (uri == null) {
7797                owner.removeUriPermissionsLocked(mode);
7798            } else {
7799                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7800            }
7801        }
7802    }
7803
7804    private void schedulePersistUriGrants() {
7805        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7806            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7807                    10 * DateUtils.SECOND_IN_MILLIS);
7808        }
7809    }
7810
7811    private void writeGrantedUriPermissions() {
7812        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7813
7814        // Snapshot permissions so we can persist without lock
7815        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7816        synchronized (this) {
7817            final int size = mGrantedUriPermissions.size();
7818            for (int i = 0; i < size; i++) {
7819                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7820                for (UriPermission perm : perms.values()) {
7821                    if (perm.persistedModeFlags != 0) {
7822                        persist.add(perm.snapshot());
7823                    }
7824                }
7825            }
7826        }
7827
7828        FileOutputStream fos = null;
7829        try {
7830            fos = mGrantFile.startWrite();
7831
7832            XmlSerializer out = new FastXmlSerializer();
7833            out.setOutput(fos, "utf-8");
7834            out.startDocument(null, true);
7835            out.startTag(null, TAG_URI_GRANTS);
7836            for (UriPermission.Snapshot perm : persist) {
7837                out.startTag(null, TAG_URI_GRANT);
7838                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7839                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7840                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7841                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7842                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7843                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7844                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7845                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7846                out.endTag(null, TAG_URI_GRANT);
7847            }
7848            out.endTag(null, TAG_URI_GRANTS);
7849            out.endDocument();
7850
7851            mGrantFile.finishWrite(fos);
7852        } catch (IOException e) {
7853            if (fos != null) {
7854                mGrantFile.failWrite(fos);
7855            }
7856        }
7857    }
7858
7859    private void readGrantedUriPermissionsLocked() {
7860        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7861
7862        final long now = System.currentTimeMillis();
7863
7864        FileInputStream fis = null;
7865        try {
7866            fis = mGrantFile.openRead();
7867            final XmlPullParser in = Xml.newPullParser();
7868            in.setInput(fis, null);
7869
7870            int type;
7871            while ((type = in.next()) != END_DOCUMENT) {
7872                final String tag = in.getName();
7873                if (type == START_TAG) {
7874                    if (TAG_URI_GRANT.equals(tag)) {
7875                        final int sourceUserId;
7876                        final int targetUserId;
7877                        final int userHandle = readIntAttribute(in,
7878                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7879                        if (userHandle != UserHandle.USER_NULL) {
7880                            // For backwards compatibility.
7881                            sourceUserId = userHandle;
7882                            targetUserId = userHandle;
7883                        } else {
7884                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7885                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7886                        }
7887                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7888                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7889                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7890                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7891                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7892                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7893
7894                        // Sanity check that provider still belongs to source package
7895                        final ProviderInfo pi = getProviderInfoLocked(
7896                                uri.getAuthority(), sourceUserId);
7897                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7898                            int targetUid = -1;
7899                            try {
7900                                targetUid = AppGlobals.getPackageManager()
7901                                        .getPackageUid(targetPkg, targetUserId);
7902                            } catch (RemoteException e) {
7903                            }
7904                            if (targetUid != -1) {
7905                                final UriPermission perm = findOrCreateUriPermissionLocked(
7906                                        sourcePkg, targetPkg, targetUid,
7907                                        new GrantUri(sourceUserId, uri, prefix));
7908                                perm.initPersistedModes(modeFlags, createdTime);
7909                            }
7910                        } else {
7911                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7912                                    + " but instead found " + pi);
7913                        }
7914                    }
7915                }
7916            }
7917        } catch (FileNotFoundException e) {
7918            // Missing grants is okay
7919        } catch (IOException e) {
7920            Slog.wtf(TAG, "Failed reading Uri grants", e);
7921        } catch (XmlPullParserException e) {
7922            Slog.wtf(TAG, "Failed reading Uri grants", e);
7923        } finally {
7924            IoUtils.closeQuietly(fis);
7925        }
7926    }
7927
7928    /**
7929     * @param uri This uri must NOT contain an embedded userId.
7930     * @param userId The userId in which the uri is to be resolved.
7931     */
7932    @Override
7933    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7934        enforceNotIsolatedCaller("takePersistableUriPermission");
7935
7936        Preconditions.checkFlagsArgument(modeFlags,
7937                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7938
7939        synchronized (this) {
7940            final int callingUid = Binder.getCallingUid();
7941            boolean persistChanged = false;
7942            GrantUri grantUri = new GrantUri(userId, uri, false);
7943
7944            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7945                    new GrantUri(userId, uri, false));
7946            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7947                    new GrantUri(userId, uri, true));
7948
7949            final boolean exactValid = (exactPerm != null)
7950                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7951            final boolean prefixValid = (prefixPerm != null)
7952                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7953
7954            if (!(exactValid || prefixValid)) {
7955                throw new SecurityException("No persistable permission grants found for UID "
7956                        + callingUid + " and Uri " + grantUri.toSafeString());
7957            }
7958
7959            if (exactValid) {
7960                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7961            }
7962            if (prefixValid) {
7963                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7964            }
7965
7966            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7967
7968            if (persistChanged) {
7969                schedulePersistUriGrants();
7970            }
7971        }
7972    }
7973
7974    /**
7975     * @param uri This uri must NOT contain an embedded userId.
7976     * @param userId The userId in which the uri is to be resolved.
7977     */
7978    @Override
7979    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7980        enforceNotIsolatedCaller("releasePersistableUriPermission");
7981
7982        Preconditions.checkFlagsArgument(modeFlags,
7983                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7984
7985        synchronized (this) {
7986            final int callingUid = Binder.getCallingUid();
7987            boolean persistChanged = false;
7988
7989            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7990                    new GrantUri(userId, uri, false));
7991            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7992                    new GrantUri(userId, uri, true));
7993            if (exactPerm == null && prefixPerm == null) {
7994                throw new SecurityException("No permission grants found for UID " + callingUid
7995                        + " and Uri " + uri.toSafeString());
7996            }
7997
7998            if (exactPerm != null) {
7999                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8000                removeUriPermissionIfNeededLocked(exactPerm);
8001            }
8002            if (prefixPerm != null) {
8003                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8004                removeUriPermissionIfNeededLocked(prefixPerm);
8005            }
8006
8007            if (persistChanged) {
8008                schedulePersistUriGrants();
8009            }
8010        }
8011    }
8012
8013    /**
8014     * Prune any older {@link UriPermission} for the given UID until outstanding
8015     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8016     *
8017     * @return if any mutations occured that require persisting.
8018     */
8019    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8020        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8021        if (perms == null) return false;
8022        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8023
8024        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8025        for (UriPermission perm : perms.values()) {
8026            if (perm.persistedModeFlags != 0) {
8027                persisted.add(perm);
8028            }
8029        }
8030
8031        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8032        if (trimCount <= 0) return false;
8033
8034        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8035        for (int i = 0; i < trimCount; i++) {
8036            final UriPermission perm = persisted.get(i);
8037
8038            if (DEBUG_URI_PERMISSION) {
8039                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
8040            }
8041
8042            perm.releasePersistableModes(~0);
8043            removeUriPermissionIfNeededLocked(perm);
8044        }
8045
8046        return true;
8047    }
8048
8049    @Override
8050    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8051            String packageName, boolean incoming) {
8052        enforceNotIsolatedCaller("getPersistedUriPermissions");
8053        Preconditions.checkNotNull(packageName, "packageName");
8054
8055        final int callingUid = Binder.getCallingUid();
8056        final IPackageManager pm = AppGlobals.getPackageManager();
8057        try {
8058            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8059            if (packageUid != callingUid) {
8060                throw new SecurityException(
8061                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8062            }
8063        } catch (RemoteException e) {
8064            throw new SecurityException("Failed to verify package name ownership");
8065        }
8066
8067        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8068        synchronized (this) {
8069            if (incoming) {
8070                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8071                        callingUid);
8072                if (perms == null) {
8073                    Slog.w(TAG, "No permission grants found for " + packageName);
8074                } else {
8075                    for (UriPermission perm : perms.values()) {
8076                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8077                            result.add(perm.buildPersistedPublicApiObject());
8078                        }
8079                    }
8080                }
8081            } else {
8082                final int size = mGrantedUriPermissions.size();
8083                for (int i = 0; i < size; i++) {
8084                    final ArrayMap<GrantUri, UriPermission> perms =
8085                            mGrantedUriPermissions.valueAt(i);
8086                    for (UriPermission perm : perms.values()) {
8087                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8088                            result.add(perm.buildPersistedPublicApiObject());
8089                        }
8090                    }
8091                }
8092            }
8093        }
8094        return new ParceledListSlice<android.content.UriPermission>(result);
8095    }
8096
8097    @Override
8098    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8099        synchronized (this) {
8100            ProcessRecord app =
8101                who != null ? getRecordForAppLocked(who) : null;
8102            if (app == null) return;
8103
8104            Message msg = Message.obtain();
8105            msg.what = WAIT_FOR_DEBUGGER_MSG;
8106            msg.obj = app;
8107            msg.arg1 = waiting ? 1 : 0;
8108            mHandler.sendMessage(msg);
8109        }
8110    }
8111
8112    @Override
8113    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8114        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8115        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8116        outInfo.availMem = Process.getFreeMemory();
8117        outInfo.totalMem = Process.getTotalMemory();
8118        outInfo.threshold = homeAppMem;
8119        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8120        outInfo.hiddenAppThreshold = cachedAppMem;
8121        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8122                ProcessList.SERVICE_ADJ);
8123        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8124                ProcessList.VISIBLE_APP_ADJ);
8125        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8126                ProcessList.FOREGROUND_APP_ADJ);
8127    }
8128
8129    // =========================================================
8130    // TASK MANAGEMENT
8131    // =========================================================
8132
8133    @Override
8134    public List<IAppTask> getAppTasks(String callingPackage) {
8135        int callingUid = Binder.getCallingUid();
8136        long ident = Binder.clearCallingIdentity();
8137
8138        synchronized(this) {
8139            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8140            try {
8141                if (localLOGV) Slog.v(TAG, "getAppTasks");
8142
8143                final int N = mRecentTasks.size();
8144                for (int i = 0; i < N; i++) {
8145                    TaskRecord tr = mRecentTasks.get(i);
8146                    // Skip tasks that do not match the caller.  We don't need to verify
8147                    // callingPackage, because we are also limiting to callingUid and know
8148                    // that will limit to the correct security sandbox.
8149                    if (tr.effectiveUid != callingUid) {
8150                        continue;
8151                    }
8152                    Intent intent = tr.getBaseIntent();
8153                    if (intent == null ||
8154                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8155                        continue;
8156                    }
8157                    ActivityManager.RecentTaskInfo taskInfo =
8158                            createRecentTaskInfoFromTaskRecord(tr);
8159                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8160                    list.add(taskImpl);
8161                }
8162            } finally {
8163                Binder.restoreCallingIdentity(ident);
8164            }
8165            return list;
8166        }
8167    }
8168
8169    @Override
8170    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8171        final int callingUid = Binder.getCallingUid();
8172        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8173
8174        synchronized(this) {
8175            if (localLOGV) Slog.v(
8176                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8177
8178            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8179                    callingUid);
8180
8181            // TODO: Improve with MRU list from all ActivityStacks.
8182            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8183        }
8184
8185        return list;
8186    }
8187
8188    TaskRecord getMostRecentTask() {
8189        return mRecentTasks.get(0);
8190    }
8191
8192    /**
8193     * Creates a new RecentTaskInfo from a TaskRecord.
8194     */
8195    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8196        // Update the task description to reflect any changes in the task stack
8197        tr.updateTaskDescription();
8198
8199        // Compose the recent task info
8200        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8201        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8202        rti.persistentId = tr.taskId;
8203        rti.baseIntent = new Intent(tr.getBaseIntent());
8204        rti.origActivity = tr.origActivity;
8205        rti.description = tr.lastDescription;
8206        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8207        rti.userId = tr.userId;
8208        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8209        rti.firstActiveTime = tr.firstActiveTime;
8210        rti.lastActiveTime = tr.lastActiveTime;
8211        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8212        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8213        return rti;
8214    }
8215
8216    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8217        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8218                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8219        if (!allowed) {
8220            if (checkPermission(android.Manifest.permission.GET_TASKS,
8221                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8222                // Temporary compatibility: some existing apps on the system image may
8223                // still be requesting the old permission and not switched to the new
8224                // one; if so, we'll still allow them full access.  This means we need
8225                // to see if they are holding the old permission and are a system app.
8226                try {
8227                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8228                        allowed = true;
8229                        Slog.w(TAG, caller + ": caller " + callingUid
8230                                + " is using old GET_TASKS but privileged; allowing");
8231                    }
8232                } catch (RemoteException e) {
8233                }
8234            }
8235        }
8236        if (!allowed) {
8237            Slog.w(TAG, caller + ": caller " + callingUid
8238                    + " does not hold GET_TASKS; limiting output");
8239        }
8240        return allowed;
8241    }
8242
8243    @Override
8244    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8245        final int callingUid = Binder.getCallingUid();
8246        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8247                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8248
8249        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8250        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8251        synchronized (this) {
8252            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8253                    callingUid);
8254            final boolean detailed = checkCallingPermission(
8255                    android.Manifest.permission.GET_DETAILED_TASKS)
8256                    == PackageManager.PERMISSION_GRANTED;
8257
8258            final int N = mRecentTasks.size();
8259            ArrayList<ActivityManager.RecentTaskInfo> res
8260                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8261                            maxNum < N ? maxNum : N);
8262
8263            final Set<Integer> includedUsers;
8264            if (includeProfiles) {
8265                includedUsers = getProfileIdsLocked(userId);
8266            } else {
8267                includedUsers = new HashSet<Integer>();
8268            }
8269            includedUsers.add(Integer.valueOf(userId));
8270
8271            for (int i=0; i<N && maxNum > 0; i++) {
8272                TaskRecord tr = mRecentTasks.get(i);
8273                // Only add calling user or related users recent tasks
8274                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8275                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8276                    continue;
8277                }
8278
8279                // Return the entry if desired by the caller.  We always return
8280                // the first entry, because callers always expect this to be the
8281                // foreground app.  We may filter others if the caller has
8282                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8283                // we should exclude the entry.
8284
8285                if (i == 0
8286                        || withExcluded
8287                        || (tr.intent == null)
8288                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8289                                == 0)) {
8290                    if (!allowed) {
8291                        // If the caller doesn't have the GET_TASKS permission, then only
8292                        // allow them to see a small subset of tasks -- their own and home.
8293                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8294                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8295                            continue;
8296                        }
8297                    }
8298                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8299                        if (tr.stack != null && tr.stack.isHomeStack()) {
8300                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8301                            continue;
8302                        }
8303                    }
8304                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8305                        // Don't include auto remove tasks that are finished or finishing.
8306                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8307                                + tr);
8308                        continue;
8309                    }
8310                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8311                            && !tr.isAvailable) {
8312                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8313                        continue;
8314                    }
8315
8316                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8317                    if (!detailed) {
8318                        rti.baseIntent.replaceExtras((Bundle)null);
8319                    }
8320
8321                    res.add(rti);
8322                    maxNum--;
8323                }
8324            }
8325            return res;
8326        }
8327    }
8328
8329    private TaskRecord recentTaskForIdLocked(int id) {
8330        final int N = mRecentTasks.size();
8331            for (int i=0; i<N; i++) {
8332                TaskRecord tr = mRecentTasks.get(i);
8333                if (tr.taskId == id) {
8334                    return tr;
8335                }
8336            }
8337            return null;
8338    }
8339
8340    @Override
8341    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8342        synchronized (this) {
8343            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8344                    "getTaskThumbnail()");
8345            TaskRecord tr = recentTaskForIdLocked(id);
8346            if (tr != null) {
8347                return tr.getTaskThumbnailLocked();
8348            }
8349        }
8350        return null;
8351    }
8352
8353    @Override
8354    public int addAppTask(IBinder activityToken, Intent intent,
8355            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8356        final int callingUid = Binder.getCallingUid();
8357        final long callingIdent = Binder.clearCallingIdentity();
8358
8359        try {
8360            synchronized (this) {
8361                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8362                if (r == null) {
8363                    throw new IllegalArgumentException("Activity does not exist; token="
8364                            + activityToken);
8365                }
8366                ComponentName comp = intent.getComponent();
8367                if (comp == null) {
8368                    throw new IllegalArgumentException("Intent " + intent
8369                            + " must specify explicit component");
8370                }
8371                if (thumbnail.getWidth() != mThumbnailWidth
8372                        || thumbnail.getHeight() != mThumbnailHeight) {
8373                    throw new IllegalArgumentException("Bad thumbnail size: got "
8374                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8375                            + mThumbnailWidth + "x" + mThumbnailHeight);
8376                }
8377                if (intent.getSelector() != null) {
8378                    intent.setSelector(null);
8379                }
8380                if (intent.getSourceBounds() != null) {
8381                    intent.setSourceBounds(null);
8382                }
8383                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8384                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8385                        // The caller has added this as an auto-remove task...  that makes no
8386                        // sense, so turn off auto-remove.
8387                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8388                    }
8389                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8390                    // Must be a new task.
8391                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8392                }
8393                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8394                    mLastAddedTaskActivity = null;
8395                }
8396                ActivityInfo ainfo = mLastAddedTaskActivity;
8397                if (ainfo == null) {
8398                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8399                            comp, 0, UserHandle.getUserId(callingUid));
8400                    if (ainfo.applicationInfo.uid != callingUid) {
8401                        throw new SecurityException(
8402                                "Can't add task for another application: target uid="
8403                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8404                    }
8405                }
8406
8407                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8408                        intent, description);
8409
8410                int trimIdx = trimRecentsForTask(task, false);
8411                if (trimIdx >= 0) {
8412                    // If this would have caused a trim, then we'll abort because that
8413                    // means it would be added at the end of the list but then just removed.
8414                    return -1;
8415                }
8416
8417                final int N = mRecentTasks.size();
8418                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8419                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8420                    tr.removedFromRecents(mTaskPersister);
8421                }
8422
8423                task.inRecents = true;
8424                mRecentTasks.add(task);
8425                r.task.stack.addTask(task, false, false);
8426
8427                task.setLastThumbnail(thumbnail);
8428                task.freeLastThumbnail();
8429
8430                return task.taskId;
8431            }
8432        } finally {
8433            Binder.restoreCallingIdentity(callingIdent);
8434        }
8435    }
8436
8437    @Override
8438    public Point getAppTaskThumbnailSize() {
8439        synchronized (this) {
8440            return new Point(mThumbnailWidth,  mThumbnailHeight);
8441        }
8442    }
8443
8444    @Override
8445    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8446        synchronized (this) {
8447            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8448            if (r != null) {
8449                r.setTaskDescription(td);
8450                r.task.updateTaskDescription();
8451            }
8452        }
8453    }
8454
8455    @Override
8456    public Bitmap getTaskDescriptionIcon(String filename) {
8457        if (!FileUtils.isValidExtFilename(filename)
8458                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8459            throw new IllegalArgumentException("Bad filename: " + filename);
8460        }
8461        return mTaskPersister.getTaskDescriptionIcon(filename);
8462    }
8463
8464    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8465        mRecentTasks.remove(tr);
8466        tr.removedFromRecents(mTaskPersister);
8467        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8468        Intent baseIntent = new Intent(
8469                tr.intent != null ? tr.intent : tr.affinityIntent);
8470        ComponentName component = baseIntent.getComponent();
8471        if (component == null) {
8472            Slog.w(TAG, "Now component for base intent of task: " + tr);
8473            return;
8474        }
8475
8476        // Find any running services associated with this app.
8477        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8478
8479        if (killProcesses) {
8480            // Find any running processes associated with this app.
8481            final String pkg = component.getPackageName();
8482            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8483            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8484            for (int i=0; i<pmap.size(); i++) {
8485                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8486                for (int j=0; j<uids.size(); j++) {
8487                    ProcessRecord proc = uids.valueAt(j);
8488                    if (proc.userId != tr.userId) {
8489                        continue;
8490                    }
8491                    if (!proc.pkgList.containsKey(pkg)) {
8492                        continue;
8493                    }
8494                    procs.add(proc);
8495                }
8496            }
8497
8498            // Kill the running processes.
8499            for (int i=0; i<procs.size(); i++) {
8500                ProcessRecord pr = procs.get(i);
8501                if (pr == mHomeProcess) {
8502                    // Don't kill the home process along with tasks from the same package.
8503                    continue;
8504                }
8505                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8506                    pr.kill("remove task", true);
8507                } else {
8508                    pr.waitingToKill = "remove task";
8509                }
8510            }
8511        }
8512    }
8513
8514    /**
8515     * Removes the task with the specified task id.
8516     *
8517     * @param taskId Identifier of the task to be removed.
8518     * @param flags Additional operational flags.  May be 0 or
8519     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8520     * @return Returns true if the given task was found and removed.
8521     */
8522    private boolean removeTaskByIdLocked(int taskId, int flags) {
8523        TaskRecord tr = recentTaskForIdLocked(taskId);
8524        if (tr != null) {
8525            tr.removeTaskActivitiesLocked();
8526            cleanUpRemovedTaskLocked(tr, flags);
8527            if (tr.isPersistable) {
8528                notifyTaskPersisterLocked(null, true);
8529            }
8530            return true;
8531        }
8532        return false;
8533    }
8534
8535    @Override
8536    public boolean removeTask(int taskId, int flags) {
8537        synchronized (this) {
8538            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8539                    "removeTask()");
8540            long ident = Binder.clearCallingIdentity();
8541            try {
8542                return removeTaskByIdLocked(taskId, flags);
8543            } finally {
8544                Binder.restoreCallingIdentity(ident);
8545            }
8546        }
8547    }
8548
8549    /**
8550     * TODO: Add mController hook
8551     */
8552    @Override
8553    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8554        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8555                "moveTaskToFront()");
8556
8557        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8558        synchronized(this) {
8559            moveTaskToFrontLocked(taskId, flags, options);
8560        }
8561    }
8562
8563    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8564        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8565                Binder.getCallingUid(), -1, -1, "Task to front")) {
8566            ActivityOptions.abort(options);
8567            return;
8568        }
8569        final long origId = Binder.clearCallingIdentity();
8570        try {
8571            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8572            if (task == null) {
8573                return;
8574            }
8575            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8576                mStackSupervisor.showLockTaskToast();
8577                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8578                return;
8579            }
8580            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8581            if (prev != null && prev.isRecentsActivity()) {
8582                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8583            }
8584            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8585        } finally {
8586            Binder.restoreCallingIdentity(origId);
8587        }
8588        ActivityOptions.abort(options);
8589    }
8590
8591    @Override
8592    public void moveTaskToBack(int taskId) {
8593        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8594                "moveTaskToBack()");
8595
8596        synchronized(this) {
8597            TaskRecord tr = recentTaskForIdLocked(taskId);
8598            if (tr != null) {
8599                if (tr == mStackSupervisor.mLockTaskModeTask) {
8600                    mStackSupervisor.showLockTaskToast();
8601                    return;
8602                }
8603                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8604                ActivityStack stack = tr.stack;
8605                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8606                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8607                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8608                        return;
8609                    }
8610                }
8611                final long origId = Binder.clearCallingIdentity();
8612                try {
8613                    stack.moveTaskToBackLocked(taskId, null);
8614                } finally {
8615                    Binder.restoreCallingIdentity(origId);
8616                }
8617            }
8618        }
8619    }
8620
8621    /**
8622     * Moves an activity, and all of the other activities within the same task, to the bottom
8623     * of the history stack.  The activity's order within the task is unchanged.
8624     *
8625     * @param token A reference to the activity we wish to move
8626     * @param nonRoot If false then this only works if the activity is the root
8627     *                of a task; if true it will work for any activity in a task.
8628     * @return Returns true if the move completed, false if not.
8629     */
8630    @Override
8631    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8632        enforceNotIsolatedCaller("moveActivityTaskToBack");
8633        synchronized(this) {
8634            final long origId = Binder.clearCallingIdentity();
8635            try {
8636                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8637                if (taskId >= 0) {
8638                    if ((mStackSupervisor.mLockTaskModeTask != null)
8639                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8640                        mStackSupervisor.showLockTaskToast();
8641                        return false;
8642                    }
8643                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8644                }
8645            } finally {
8646                Binder.restoreCallingIdentity(origId);
8647            }
8648        }
8649        return false;
8650    }
8651
8652    @Override
8653    public void moveTaskBackwards(int task) {
8654        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8655                "moveTaskBackwards()");
8656
8657        synchronized(this) {
8658            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8659                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8660                return;
8661            }
8662            final long origId = Binder.clearCallingIdentity();
8663            moveTaskBackwardsLocked(task);
8664            Binder.restoreCallingIdentity(origId);
8665        }
8666    }
8667
8668    private final void moveTaskBackwardsLocked(int task) {
8669        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8670    }
8671
8672    @Override
8673    public IBinder getHomeActivityToken() throws RemoteException {
8674        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8675                "getHomeActivityToken()");
8676        synchronized (this) {
8677            return mStackSupervisor.getHomeActivityToken();
8678        }
8679    }
8680
8681    @Override
8682    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8683            IActivityContainerCallback callback) throws RemoteException {
8684        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8685                "createActivityContainer()");
8686        synchronized (this) {
8687            if (parentActivityToken == null) {
8688                throw new IllegalArgumentException("parent token must not be null");
8689            }
8690            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8691            if (r == null) {
8692                return null;
8693            }
8694            if (callback == null) {
8695                throw new IllegalArgumentException("callback must not be null");
8696            }
8697            return mStackSupervisor.createActivityContainer(r, callback);
8698        }
8699    }
8700
8701    @Override
8702    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8703        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8704                "deleteActivityContainer()");
8705        synchronized (this) {
8706            mStackSupervisor.deleteActivityContainer(container);
8707        }
8708    }
8709
8710    @Override
8711    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8712            throws RemoteException {
8713        synchronized (this) {
8714            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8715            if (stack != null) {
8716                return stack.mActivityContainer;
8717            }
8718            return null;
8719        }
8720    }
8721
8722    @Override
8723    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8724        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8725                "moveTaskToStack()");
8726        if (stackId == HOME_STACK_ID) {
8727            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8728                    new RuntimeException("here").fillInStackTrace());
8729        }
8730        synchronized (this) {
8731            long ident = Binder.clearCallingIdentity();
8732            try {
8733                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8734                        + stackId + " toTop=" + toTop);
8735                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8736            } finally {
8737                Binder.restoreCallingIdentity(ident);
8738            }
8739        }
8740    }
8741
8742    @Override
8743    public void resizeStack(int stackBoxId, Rect bounds) {
8744        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8745                "resizeStackBox()");
8746        long ident = Binder.clearCallingIdentity();
8747        try {
8748            mWindowManager.resizeStack(stackBoxId, bounds);
8749        } finally {
8750            Binder.restoreCallingIdentity(ident);
8751        }
8752    }
8753
8754    @Override
8755    public List<StackInfo> getAllStackInfos() {
8756        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8757                "getAllStackInfos()");
8758        long ident = Binder.clearCallingIdentity();
8759        try {
8760            synchronized (this) {
8761                return mStackSupervisor.getAllStackInfosLocked();
8762            }
8763        } finally {
8764            Binder.restoreCallingIdentity(ident);
8765        }
8766    }
8767
8768    @Override
8769    public StackInfo getStackInfo(int stackId) {
8770        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8771                "getStackInfo()");
8772        long ident = Binder.clearCallingIdentity();
8773        try {
8774            synchronized (this) {
8775                return mStackSupervisor.getStackInfoLocked(stackId);
8776            }
8777        } finally {
8778            Binder.restoreCallingIdentity(ident);
8779        }
8780    }
8781
8782    @Override
8783    public boolean isInHomeStack(int taskId) {
8784        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8785                "getStackInfo()");
8786        long ident = Binder.clearCallingIdentity();
8787        try {
8788            synchronized (this) {
8789                TaskRecord tr = recentTaskForIdLocked(taskId);
8790                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8791            }
8792        } finally {
8793            Binder.restoreCallingIdentity(ident);
8794        }
8795    }
8796
8797    @Override
8798    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8799        synchronized(this) {
8800            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8801        }
8802    }
8803
8804    private boolean isLockTaskAuthorized(String pkg) {
8805        final DevicePolicyManager dpm = (DevicePolicyManager)
8806                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8807        try {
8808            int uid = mContext.getPackageManager().getPackageUid(pkg,
8809                    Binder.getCallingUserHandle().getIdentifier());
8810            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8811        } catch (NameNotFoundException e) {
8812            return false;
8813        }
8814    }
8815
8816    void startLockTaskMode(TaskRecord task) {
8817        final String pkg;
8818        synchronized (this) {
8819            pkg = task.intent.getComponent().getPackageName();
8820        }
8821        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8822        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8823            final TaskRecord taskRecord = task;
8824            mHandler.post(new Runnable() {
8825                @Override
8826                public void run() {
8827                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8828                }
8829            });
8830            return;
8831        }
8832        long ident = Binder.clearCallingIdentity();
8833        try {
8834            synchronized (this) {
8835                // Since we lost lock on task, make sure it is still there.
8836                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8837                if (task != null) {
8838                    if (!isSystemInitiated
8839                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8840                        throw new IllegalArgumentException("Invalid task, not in foreground");
8841                    }
8842                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8843                }
8844            }
8845        } finally {
8846            Binder.restoreCallingIdentity(ident);
8847        }
8848    }
8849
8850    @Override
8851    public void startLockTaskMode(int taskId) {
8852        final TaskRecord task;
8853        long ident = Binder.clearCallingIdentity();
8854        try {
8855            synchronized (this) {
8856                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8857            }
8858        } finally {
8859            Binder.restoreCallingIdentity(ident);
8860        }
8861        if (task != null) {
8862            startLockTaskMode(task);
8863        }
8864    }
8865
8866    @Override
8867    public void startLockTaskMode(IBinder token) {
8868        final TaskRecord task;
8869        long ident = Binder.clearCallingIdentity();
8870        try {
8871            synchronized (this) {
8872                final ActivityRecord r = ActivityRecord.forToken(token);
8873                if (r == null) {
8874                    return;
8875                }
8876                task = r.task;
8877            }
8878        } finally {
8879            Binder.restoreCallingIdentity(ident);
8880        }
8881        if (task != null) {
8882            startLockTaskMode(task);
8883        }
8884    }
8885
8886    @Override
8887    public void startLockTaskModeOnCurrent() throws RemoteException {
8888        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8889                "startLockTaskModeOnCurrent");
8890        ActivityRecord r = null;
8891        synchronized (this) {
8892            r = mStackSupervisor.topRunningActivityLocked();
8893        }
8894        startLockTaskMode(r.task);
8895    }
8896
8897    @Override
8898    public void stopLockTaskMode() {
8899        // Verify that the user matches the package of the intent for the TaskRecord
8900        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8901        // and stopLockTaskMode.
8902        final int callingUid = Binder.getCallingUid();
8903        if (callingUid != Process.SYSTEM_UID) {
8904            try {
8905                String pkg =
8906                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8907                int uid = mContext.getPackageManager().getPackageUid(pkg,
8908                        Binder.getCallingUserHandle().getIdentifier());
8909                if (uid != callingUid) {
8910                    throw new SecurityException("Invalid uid, expected " + uid);
8911                }
8912            } catch (NameNotFoundException e) {
8913                Log.d(TAG, "stopLockTaskMode " + e);
8914                return;
8915            }
8916        }
8917        long ident = Binder.clearCallingIdentity();
8918        try {
8919            Log.d(TAG, "stopLockTaskMode");
8920            // Stop lock task
8921            synchronized (this) {
8922                mStackSupervisor.setLockTaskModeLocked(null, false);
8923            }
8924        } finally {
8925            Binder.restoreCallingIdentity(ident);
8926        }
8927    }
8928
8929    @Override
8930    public void stopLockTaskModeOnCurrent() throws RemoteException {
8931        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8932                "stopLockTaskModeOnCurrent");
8933        long ident = Binder.clearCallingIdentity();
8934        try {
8935            stopLockTaskMode();
8936        } finally {
8937            Binder.restoreCallingIdentity(ident);
8938        }
8939    }
8940
8941    @Override
8942    public boolean isInLockTaskMode() {
8943        synchronized (this) {
8944            return mStackSupervisor.isInLockTaskMode();
8945        }
8946    }
8947
8948    // =========================================================
8949    // CONTENT PROVIDERS
8950    // =========================================================
8951
8952    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8953        List<ProviderInfo> providers = null;
8954        try {
8955            providers = AppGlobals.getPackageManager().
8956                queryContentProviders(app.processName, app.uid,
8957                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8958        } catch (RemoteException ex) {
8959        }
8960        if (DEBUG_MU)
8961            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8962        int userId = app.userId;
8963        if (providers != null) {
8964            int N = providers.size();
8965            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8966            for (int i=0; i<N; i++) {
8967                ProviderInfo cpi =
8968                    (ProviderInfo)providers.get(i);
8969                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8970                        cpi.name, cpi.flags);
8971                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8972                    // This is a singleton provider, but a user besides the
8973                    // default user is asking to initialize a process it runs
8974                    // in...  well, no, it doesn't actually run in this process,
8975                    // it runs in the process of the default user.  Get rid of it.
8976                    providers.remove(i);
8977                    N--;
8978                    i--;
8979                    continue;
8980                }
8981
8982                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8983                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8984                if (cpr == null) {
8985                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8986                    mProviderMap.putProviderByClass(comp, cpr);
8987                }
8988                if (DEBUG_MU)
8989                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8990                app.pubProviders.put(cpi.name, cpr);
8991                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8992                    // Don't add this if it is a platform component that is marked
8993                    // to run in multiple processes, because this is actually
8994                    // part of the framework so doesn't make sense to track as a
8995                    // separate apk in the process.
8996                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8997                            mProcessStats);
8998                }
8999                ensurePackageDexOpt(cpi.applicationInfo.packageName);
9000            }
9001        }
9002        return providers;
9003    }
9004
9005    /**
9006     * Check if {@link ProcessRecord} has a possible chance at accessing the
9007     * given {@link ProviderInfo}. Final permission checking is always done
9008     * in {@link ContentProvider}.
9009     */
9010    private final String checkContentProviderPermissionLocked(
9011            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9012        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9013        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9014        boolean checkedGrants = false;
9015        if (checkUser) {
9016            // Looking for cross-user grants before enforcing the typical cross-users permissions
9017            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
9018            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9019                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9020                    return null;
9021                }
9022                checkedGrants = true;
9023            }
9024            userId = handleIncomingUser(callingPid, callingUid, userId,
9025                    false, ALLOW_NON_FULL,
9026                    "checkContentProviderPermissionLocked " + cpi.authority, null);
9027            if (userId != tmpTargetUserId) {
9028                // When we actually went to determine the final targer user ID, this ended
9029                // up different than our initial check for the authority.  This is because
9030                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9031                // SELF.  So we need to re-check the grants again.
9032                checkedGrants = false;
9033            }
9034        }
9035        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9036                cpi.applicationInfo.uid, cpi.exported)
9037                == PackageManager.PERMISSION_GRANTED) {
9038            return null;
9039        }
9040        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9041                cpi.applicationInfo.uid, cpi.exported)
9042                == PackageManager.PERMISSION_GRANTED) {
9043            return null;
9044        }
9045
9046        PathPermission[] pps = cpi.pathPermissions;
9047        if (pps != null) {
9048            int i = pps.length;
9049            while (i > 0) {
9050                i--;
9051                PathPermission pp = pps[i];
9052                String pprperm = pp.getReadPermission();
9053                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9054                        cpi.applicationInfo.uid, cpi.exported)
9055                        == PackageManager.PERMISSION_GRANTED) {
9056                    return null;
9057                }
9058                String ppwperm = pp.getWritePermission();
9059                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9060                        cpi.applicationInfo.uid, cpi.exported)
9061                        == PackageManager.PERMISSION_GRANTED) {
9062                    return null;
9063                }
9064            }
9065        }
9066        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9067            return null;
9068        }
9069
9070        String msg;
9071        if (!cpi.exported) {
9072            msg = "Permission Denial: opening provider " + cpi.name
9073                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9074                    + ", uid=" + callingUid + ") that is not exported from uid "
9075                    + cpi.applicationInfo.uid;
9076        } else {
9077            msg = "Permission Denial: opening provider " + cpi.name
9078                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9079                    + ", uid=" + callingUid + ") requires "
9080                    + cpi.readPermission + " or " + cpi.writePermission;
9081        }
9082        Slog.w(TAG, msg);
9083        return msg;
9084    }
9085
9086    /**
9087     * Returns if the ContentProvider has granted a uri to callingUid
9088     */
9089    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9090        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9091        if (perms != null) {
9092            for (int i=perms.size()-1; i>=0; i--) {
9093                GrantUri grantUri = perms.keyAt(i);
9094                if (grantUri.sourceUserId == userId || !checkUser) {
9095                    if (matchesProvider(grantUri.uri, cpi)) {
9096                        return true;
9097                    }
9098                }
9099            }
9100        }
9101        return false;
9102    }
9103
9104    /**
9105     * Returns true if the uri authority is one of the authorities specified in the provider.
9106     */
9107    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9108        String uriAuth = uri.getAuthority();
9109        String cpiAuth = cpi.authority;
9110        if (cpiAuth.indexOf(';') == -1) {
9111            return cpiAuth.equals(uriAuth);
9112        }
9113        String[] cpiAuths = cpiAuth.split(";");
9114        int length = cpiAuths.length;
9115        for (int i = 0; i < length; i++) {
9116            if (cpiAuths[i].equals(uriAuth)) return true;
9117        }
9118        return false;
9119    }
9120
9121    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9122            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9123        if (r != null) {
9124            for (int i=0; i<r.conProviders.size(); i++) {
9125                ContentProviderConnection conn = r.conProviders.get(i);
9126                if (conn.provider == cpr) {
9127                    if (DEBUG_PROVIDER) Slog.v(TAG,
9128                            "Adding provider requested by "
9129                            + r.processName + " from process "
9130                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9131                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9132                    if (stable) {
9133                        conn.stableCount++;
9134                        conn.numStableIncs++;
9135                    } else {
9136                        conn.unstableCount++;
9137                        conn.numUnstableIncs++;
9138                    }
9139                    return conn;
9140                }
9141            }
9142            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9143            if (stable) {
9144                conn.stableCount = 1;
9145                conn.numStableIncs = 1;
9146            } else {
9147                conn.unstableCount = 1;
9148                conn.numUnstableIncs = 1;
9149            }
9150            cpr.connections.add(conn);
9151            r.conProviders.add(conn);
9152            return conn;
9153        }
9154        cpr.addExternalProcessHandleLocked(externalProcessToken);
9155        return null;
9156    }
9157
9158    boolean decProviderCountLocked(ContentProviderConnection conn,
9159            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9160        if (conn != null) {
9161            cpr = conn.provider;
9162            if (DEBUG_PROVIDER) Slog.v(TAG,
9163                    "Removing provider requested by "
9164                    + conn.client.processName + " from process "
9165                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9166                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9167            if (stable) {
9168                conn.stableCount--;
9169            } else {
9170                conn.unstableCount--;
9171            }
9172            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9173                cpr.connections.remove(conn);
9174                conn.client.conProviders.remove(conn);
9175                return true;
9176            }
9177            return false;
9178        }
9179        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9180        return false;
9181    }
9182
9183    private void checkTime(long startTime, String where) {
9184        long now = SystemClock.elapsedRealtime();
9185        if ((now-startTime) > 1000) {
9186            // If we are taking more than a second, log about it.
9187            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9188        }
9189    }
9190
9191    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9192            String name, IBinder token, boolean stable, int userId) {
9193        ContentProviderRecord cpr;
9194        ContentProviderConnection conn = null;
9195        ProviderInfo cpi = null;
9196
9197        synchronized(this) {
9198            long startTime = SystemClock.elapsedRealtime();
9199
9200            ProcessRecord r = null;
9201            if (caller != null) {
9202                r = getRecordForAppLocked(caller);
9203                if (r == null) {
9204                    throw new SecurityException(
9205                            "Unable to find app for caller " + caller
9206                          + " (pid=" + Binder.getCallingPid()
9207                          + ") when getting content provider " + name);
9208                }
9209            }
9210
9211            boolean checkCrossUser = true;
9212
9213            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9214
9215            // First check if this content provider has been published...
9216            cpr = mProviderMap.getProviderByName(name, userId);
9217            // If that didn't work, check if it exists for user 0 and then
9218            // verify that it's a singleton provider before using it.
9219            if (cpr == null && userId != UserHandle.USER_OWNER) {
9220                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9221                if (cpr != null) {
9222                    cpi = cpr.info;
9223                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9224                            cpi.name, cpi.flags)
9225                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9226                        userId = UserHandle.USER_OWNER;
9227                        checkCrossUser = false;
9228                    } else {
9229                        cpr = null;
9230                        cpi = null;
9231                    }
9232                }
9233            }
9234
9235            boolean providerRunning = cpr != null;
9236            if (providerRunning) {
9237                cpi = cpr.info;
9238                String msg;
9239                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9240                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9241                        != null) {
9242                    throw new SecurityException(msg);
9243                }
9244                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9245
9246                if (r != null && cpr.canRunHere(r)) {
9247                    // This provider has been published or is in the process
9248                    // of being published...  but it is also allowed to run
9249                    // in the caller's process, so don't make a connection
9250                    // and just let the caller instantiate its own instance.
9251                    ContentProviderHolder holder = cpr.newHolder(null);
9252                    // don't give caller the provider object, it needs
9253                    // to make its own.
9254                    holder.provider = null;
9255                    return holder;
9256                }
9257
9258                final long origId = Binder.clearCallingIdentity();
9259
9260                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9261
9262                // In this case the provider instance already exists, so we can
9263                // return it right away.
9264                conn = incProviderCountLocked(r, cpr, token, stable);
9265                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9266                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9267                        // If this is a perceptible app accessing the provider,
9268                        // make sure to count it as being accessed and thus
9269                        // back up on the LRU list.  This is good because
9270                        // content providers are often expensive to start.
9271                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9272                        updateLruProcessLocked(cpr.proc, false, null);
9273                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9274                    }
9275                }
9276
9277                if (cpr.proc != null) {
9278                    if (false) {
9279                        if (cpr.name.flattenToShortString().equals(
9280                                "com.android.providers.calendar/.CalendarProvider2")) {
9281                            Slog.v(TAG, "****************** KILLING "
9282                                + cpr.name.flattenToShortString());
9283                            Process.killProcess(cpr.proc.pid);
9284                        }
9285                    }
9286                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9287                    boolean success = updateOomAdjLocked(cpr.proc);
9288                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9289                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9290                    // NOTE: there is still a race here where a signal could be
9291                    // pending on the process even though we managed to update its
9292                    // adj level.  Not sure what to do about this, but at least
9293                    // the race is now smaller.
9294                    if (!success) {
9295                        // Uh oh...  it looks like the provider's process
9296                        // has been killed on us.  We need to wait for a new
9297                        // process to be started, and make sure its death
9298                        // doesn't kill our process.
9299                        Slog.i(TAG,
9300                                "Existing provider " + cpr.name.flattenToShortString()
9301                                + " is crashing; detaching " + r);
9302                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9303                        checkTime(startTime, "getContentProviderImpl: before appDied");
9304                        appDiedLocked(cpr.proc);
9305                        checkTime(startTime, "getContentProviderImpl: after appDied");
9306                        if (!lastRef) {
9307                            // This wasn't the last ref our process had on
9308                            // the provider...  we have now been killed, bail.
9309                            return null;
9310                        }
9311                        providerRunning = false;
9312                        conn = null;
9313                    }
9314                }
9315
9316                Binder.restoreCallingIdentity(origId);
9317            }
9318
9319            boolean singleton;
9320            if (!providerRunning) {
9321                try {
9322                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9323                    cpi = AppGlobals.getPackageManager().
9324                        resolveContentProvider(name,
9325                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9326                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9327                } catch (RemoteException ex) {
9328                }
9329                if (cpi == null) {
9330                    return null;
9331                }
9332                // If the provider is a singleton AND
9333                // (it's a call within the same user || the provider is a
9334                // privileged app)
9335                // Then allow connecting to the singleton provider
9336                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9337                        cpi.name, cpi.flags)
9338                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9339                if (singleton) {
9340                    userId = UserHandle.USER_OWNER;
9341                }
9342                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9343                checkTime(startTime, "getContentProviderImpl: got app info for user");
9344
9345                String msg;
9346                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9347                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9348                        != null) {
9349                    throw new SecurityException(msg);
9350                }
9351                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9352
9353                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9354                        && !cpi.processName.equals("system")) {
9355                    // If this content provider does not run in the system
9356                    // process, and the system is not yet ready to run other
9357                    // processes, then fail fast instead of hanging.
9358                    throw new IllegalArgumentException(
9359                            "Attempt to launch content provider before system ready");
9360                }
9361
9362                // Make sure that the user who owns this provider is started.  If not,
9363                // we don't want to allow it to run.
9364                if (mStartedUsers.get(userId) == null) {
9365                    Slog.w(TAG, "Unable to launch app "
9366                            + cpi.applicationInfo.packageName + "/"
9367                            + cpi.applicationInfo.uid + " for provider "
9368                            + name + ": user " + userId + " is stopped");
9369                    return null;
9370                }
9371
9372                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9373                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9374                cpr = mProviderMap.getProviderByClass(comp, userId);
9375                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9376                final boolean firstClass = cpr == null;
9377                if (firstClass) {
9378                    final long ident = Binder.clearCallingIdentity();
9379                    try {
9380                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9381                        ApplicationInfo ai =
9382                            AppGlobals.getPackageManager().
9383                                getApplicationInfo(
9384                                        cpi.applicationInfo.packageName,
9385                                        STOCK_PM_FLAGS, userId);
9386                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9387                        if (ai == null) {
9388                            Slog.w(TAG, "No package info for content provider "
9389                                    + cpi.name);
9390                            return null;
9391                        }
9392                        ai = getAppInfoForUser(ai, userId);
9393                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9394                    } catch (RemoteException ex) {
9395                        // pm is in same process, this will never happen.
9396                    } finally {
9397                        Binder.restoreCallingIdentity(ident);
9398                    }
9399                }
9400
9401                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9402
9403                if (r != null && cpr.canRunHere(r)) {
9404                    // If this is a multiprocess provider, then just return its
9405                    // info and allow the caller to instantiate it.  Only do
9406                    // this if the provider is the same user as the caller's
9407                    // process, or can run as root (so can be in any process).
9408                    return cpr.newHolder(null);
9409                }
9410
9411                if (DEBUG_PROVIDER) {
9412                    RuntimeException e = new RuntimeException("here");
9413                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9414                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9415                }
9416
9417                // This is single process, and our app is now connecting to it.
9418                // See if we are already in the process of launching this
9419                // provider.
9420                final int N = mLaunchingProviders.size();
9421                int i;
9422                for (i=0; i<N; i++) {
9423                    if (mLaunchingProviders.get(i) == cpr) {
9424                        break;
9425                    }
9426                }
9427
9428                // If the provider is not already being launched, then get it
9429                // started.
9430                if (i >= N) {
9431                    final long origId = Binder.clearCallingIdentity();
9432
9433                    try {
9434                        // Content provider is now in use, its package can't be stopped.
9435                        try {
9436                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9437                            AppGlobals.getPackageManager().setPackageStoppedState(
9438                                    cpr.appInfo.packageName, false, userId);
9439                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9440                        } catch (RemoteException e) {
9441                        } catch (IllegalArgumentException e) {
9442                            Slog.w(TAG, "Failed trying to unstop package "
9443                                    + cpr.appInfo.packageName + ": " + e);
9444                        }
9445
9446                        // Use existing process if already started
9447                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9448                        ProcessRecord proc = getProcessRecordLocked(
9449                                cpi.processName, cpr.appInfo.uid, false);
9450                        if (proc != null && proc.thread != null) {
9451                            if (DEBUG_PROVIDER) {
9452                                Slog.d(TAG, "Installing in existing process " + proc);
9453                            }
9454                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9455                            proc.pubProviders.put(cpi.name, cpr);
9456                            try {
9457                                proc.thread.scheduleInstallProvider(cpi);
9458                            } catch (RemoteException e) {
9459                            }
9460                        } else {
9461                            checkTime(startTime, "getContentProviderImpl: before start process");
9462                            proc = startProcessLocked(cpi.processName,
9463                                    cpr.appInfo, false, 0, "content provider",
9464                                    new ComponentName(cpi.applicationInfo.packageName,
9465                                            cpi.name), false, false, false);
9466                            checkTime(startTime, "getContentProviderImpl: after start process");
9467                            if (proc == null) {
9468                                Slog.w(TAG, "Unable to launch app "
9469                                        + cpi.applicationInfo.packageName + "/"
9470                                        + cpi.applicationInfo.uid + " for provider "
9471                                        + name + ": process is bad");
9472                                return null;
9473                            }
9474                        }
9475                        cpr.launchingApp = proc;
9476                        mLaunchingProviders.add(cpr);
9477                    } finally {
9478                        Binder.restoreCallingIdentity(origId);
9479                    }
9480                }
9481
9482                checkTime(startTime, "getContentProviderImpl: updating data structures");
9483
9484                // Make sure the provider is published (the same provider class
9485                // may be published under multiple names).
9486                if (firstClass) {
9487                    mProviderMap.putProviderByClass(comp, cpr);
9488                }
9489
9490                mProviderMap.putProviderByName(name, cpr);
9491                conn = incProviderCountLocked(r, cpr, token, stable);
9492                if (conn != null) {
9493                    conn.waiting = true;
9494                }
9495            }
9496            checkTime(startTime, "getContentProviderImpl: done!");
9497        }
9498
9499        // Wait for the provider to be published...
9500        synchronized (cpr) {
9501            while (cpr.provider == null) {
9502                if (cpr.launchingApp == null) {
9503                    Slog.w(TAG, "Unable to launch app "
9504                            + cpi.applicationInfo.packageName + "/"
9505                            + cpi.applicationInfo.uid + " for provider "
9506                            + name + ": launching app became null");
9507                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9508                            UserHandle.getUserId(cpi.applicationInfo.uid),
9509                            cpi.applicationInfo.packageName,
9510                            cpi.applicationInfo.uid, name);
9511                    return null;
9512                }
9513                try {
9514                    if (DEBUG_MU) {
9515                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9516                                + cpr.launchingApp);
9517                    }
9518                    if (conn != null) {
9519                        conn.waiting = true;
9520                    }
9521                    cpr.wait();
9522                } catch (InterruptedException ex) {
9523                } finally {
9524                    if (conn != null) {
9525                        conn.waiting = false;
9526                    }
9527                }
9528            }
9529        }
9530        return cpr != null ? cpr.newHolder(conn) : null;
9531    }
9532
9533    @Override
9534    public final ContentProviderHolder getContentProvider(
9535            IApplicationThread caller, String name, int userId, boolean stable) {
9536        enforceNotIsolatedCaller("getContentProvider");
9537        if (caller == null) {
9538            String msg = "null IApplicationThread when getting content provider "
9539                    + name;
9540            Slog.w(TAG, msg);
9541            throw new SecurityException(msg);
9542        }
9543        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9544        // with cross-user grant.
9545        return getContentProviderImpl(caller, name, null, stable, userId);
9546    }
9547
9548    public ContentProviderHolder getContentProviderExternal(
9549            String name, int userId, IBinder token) {
9550        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9551            "Do not have permission in call getContentProviderExternal()");
9552        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9553                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9554        return getContentProviderExternalUnchecked(name, token, userId);
9555    }
9556
9557    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9558            IBinder token, int userId) {
9559        return getContentProviderImpl(null, name, token, true, userId);
9560    }
9561
9562    /**
9563     * Drop a content provider from a ProcessRecord's bookkeeping
9564     */
9565    public void removeContentProvider(IBinder connection, boolean stable) {
9566        enforceNotIsolatedCaller("removeContentProvider");
9567        long ident = Binder.clearCallingIdentity();
9568        try {
9569            synchronized (this) {
9570                ContentProviderConnection conn;
9571                try {
9572                    conn = (ContentProviderConnection)connection;
9573                } catch (ClassCastException e) {
9574                    String msg ="removeContentProvider: " + connection
9575                            + " not a ContentProviderConnection";
9576                    Slog.w(TAG, msg);
9577                    throw new IllegalArgumentException(msg);
9578                }
9579                if (conn == null) {
9580                    throw new NullPointerException("connection is null");
9581                }
9582                if (decProviderCountLocked(conn, null, null, stable)) {
9583                    updateOomAdjLocked();
9584                }
9585            }
9586        } finally {
9587            Binder.restoreCallingIdentity(ident);
9588        }
9589    }
9590
9591    public void removeContentProviderExternal(String name, IBinder token) {
9592        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9593            "Do not have permission in call removeContentProviderExternal()");
9594        int userId = UserHandle.getCallingUserId();
9595        long ident = Binder.clearCallingIdentity();
9596        try {
9597            removeContentProviderExternalUnchecked(name, token, userId);
9598        } finally {
9599            Binder.restoreCallingIdentity(ident);
9600        }
9601    }
9602
9603    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9604        synchronized (this) {
9605            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9606            if(cpr == null) {
9607                //remove from mProvidersByClass
9608                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9609                return;
9610            }
9611
9612            //update content provider record entry info
9613            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9614            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9615            if (localCpr.hasExternalProcessHandles()) {
9616                if (localCpr.removeExternalProcessHandleLocked(token)) {
9617                    updateOomAdjLocked();
9618                } else {
9619                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9620                            + " with no external reference for token: "
9621                            + token + ".");
9622                }
9623            } else {
9624                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9625                        + " with no external references.");
9626            }
9627        }
9628    }
9629
9630    public final void publishContentProviders(IApplicationThread caller,
9631            List<ContentProviderHolder> providers) {
9632        if (providers == null) {
9633            return;
9634        }
9635
9636        enforceNotIsolatedCaller("publishContentProviders");
9637        synchronized (this) {
9638            final ProcessRecord r = getRecordForAppLocked(caller);
9639            if (DEBUG_MU)
9640                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9641            if (r == null) {
9642                throw new SecurityException(
9643                        "Unable to find app for caller " + caller
9644                      + " (pid=" + Binder.getCallingPid()
9645                      + ") when publishing content providers");
9646            }
9647
9648            final long origId = Binder.clearCallingIdentity();
9649
9650            final int N = providers.size();
9651            for (int i=0; i<N; i++) {
9652                ContentProviderHolder src = providers.get(i);
9653                if (src == null || src.info == null || src.provider == null) {
9654                    continue;
9655                }
9656                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9657                if (DEBUG_MU)
9658                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9659                if (dst != null) {
9660                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9661                    mProviderMap.putProviderByClass(comp, dst);
9662                    String names[] = dst.info.authority.split(";");
9663                    for (int j = 0; j < names.length; j++) {
9664                        mProviderMap.putProviderByName(names[j], dst);
9665                    }
9666
9667                    int NL = mLaunchingProviders.size();
9668                    int j;
9669                    for (j=0; j<NL; j++) {
9670                        if (mLaunchingProviders.get(j) == dst) {
9671                            mLaunchingProviders.remove(j);
9672                            j--;
9673                            NL--;
9674                        }
9675                    }
9676                    synchronized (dst) {
9677                        dst.provider = src.provider;
9678                        dst.proc = r;
9679                        dst.notifyAll();
9680                    }
9681                    updateOomAdjLocked(r);
9682                }
9683            }
9684
9685            Binder.restoreCallingIdentity(origId);
9686        }
9687    }
9688
9689    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9690        ContentProviderConnection conn;
9691        try {
9692            conn = (ContentProviderConnection)connection;
9693        } catch (ClassCastException e) {
9694            String msg ="refContentProvider: " + connection
9695                    + " not a ContentProviderConnection";
9696            Slog.w(TAG, msg);
9697            throw new IllegalArgumentException(msg);
9698        }
9699        if (conn == null) {
9700            throw new NullPointerException("connection is null");
9701        }
9702
9703        synchronized (this) {
9704            if (stable > 0) {
9705                conn.numStableIncs += stable;
9706            }
9707            stable = conn.stableCount + stable;
9708            if (stable < 0) {
9709                throw new IllegalStateException("stableCount < 0: " + stable);
9710            }
9711
9712            if (unstable > 0) {
9713                conn.numUnstableIncs += unstable;
9714            }
9715            unstable = conn.unstableCount + unstable;
9716            if (unstable < 0) {
9717                throw new IllegalStateException("unstableCount < 0: " + unstable);
9718            }
9719
9720            if ((stable+unstable) <= 0) {
9721                throw new IllegalStateException("ref counts can't go to zero here: stable="
9722                        + stable + " unstable=" + unstable);
9723            }
9724            conn.stableCount = stable;
9725            conn.unstableCount = unstable;
9726            return !conn.dead;
9727        }
9728    }
9729
9730    public void unstableProviderDied(IBinder connection) {
9731        ContentProviderConnection conn;
9732        try {
9733            conn = (ContentProviderConnection)connection;
9734        } catch (ClassCastException e) {
9735            String msg ="refContentProvider: " + connection
9736                    + " not a ContentProviderConnection";
9737            Slog.w(TAG, msg);
9738            throw new IllegalArgumentException(msg);
9739        }
9740        if (conn == null) {
9741            throw new NullPointerException("connection is null");
9742        }
9743
9744        // Safely retrieve the content provider associated with the connection.
9745        IContentProvider provider;
9746        synchronized (this) {
9747            provider = conn.provider.provider;
9748        }
9749
9750        if (provider == null) {
9751            // Um, yeah, we're way ahead of you.
9752            return;
9753        }
9754
9755        // Make sure the caller is being honest with us.
9756        if (provider.asBinder().pingBinder()) {
9757            // Er, no, still looks good to us.
9758            synchronized (this) {
9759                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9760                        + " says " + conn + " died, but we don't agree");
9761                return;
9762            }
9763        }
9764
9765        // Well look at that!  It's dead!
9766        synchronized (this) {
9767            if (conn.provider.provider != provider) {
9768                // But something changed...  good enough.
9769                return;
9770            }
9771
9772            ProcessRecord proc = conn.provider.proc;
9773            if (proc == null || proc.thread == null) {
9774                // Seems like the process is already cleaned up.
9775                return;
9776            }
9777
9778            // As far as we're concerned, this is just like receiving a
9779            // death notification...  just a bit prematurely.
9780            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9781                    + ") early provider death");
9782            final long ident = Binder.clearCallingIdentity();
9783            try {
9784                appDiedLocked(proc);
9785            } finally {
9786                Binder.restoreCallingIdentity(ident);
9787            }
9788        }
9789    }
9790
9791    @Override
9792    public void appNotRespondingViaProvider(IBinder connection) {
9793        enforceCallingPermission(
9794                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9795
9796        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9797        if (conn == null) {
9798            Slog.w(TAG, "ContentProviderConnection is null");
9799            return;
9800        }
9801
9802        final ProcessRecord host = conn.provider.proc;
9803        if (host == null) {
9804            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9805            return;
9806        }
9807
9808        final long token = Binder.clearCallingIdentity();
9809        try {
9810            appNotResponding(host, null, null, false, "ContentProvider not responding");
9811        } finally {
9812            Binder.restoreCallingIdentity(token);
9813        }
9814    }
9815
9816    public final void installSystemProviders() {
9817        List<ProviderInfo> providers;
9818        synchronized (this) {
9819            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9820            providers = generateApplicationProvidersLocked(app);
9821            if (providers != null) {
9822                for (int i=providers.size()-1; i>=0; i--) {
9823                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9824                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9825                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9826                                + ": not system .apk");
9827                        providers.remove(i);
9828                    }
9829                }
9830            }
9831        }
9832        if (providers != null) {
9833            mSystemThread.installSystemProviders(providers);
9834        }
9835
9836        mCoreSettingsObserver = new CoreSettingsObserver(this);
9837
9838        //mUsageStatsService.monitorPackages();
9839    }
9840
9841    /**
9842     * Allows apps to retrieve the MIME type of a URI.
9843     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9844     * users, then it does not need permission to access the ContentProvider.
9845     * Either, it needs cross-user uri grants.
9846     *
9847     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9848     *
9849     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9850     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9851     */
9852    public String getProviderMimeType(Uri uri, int userId) {
9853        enforceNotIsolatedCaller("getProviderMimeType");
9854        final String name = uri.getAuthority();
9855        int callingUid = Binder.getCallingUid();
9856        int callingPid = Binder.getCallingPid();
9857        long ident = 0;
9858        boolean clearedIdentity = false;
9859        userId = unsafeConvertIncomingUser(userId);
9860        if (canClearIdentity(callingPid, callingUid, userId)) {
9861            clearedIdentity = true;
9862            ident = Binder.clearCallingIdentity();
9863        }
9864        ContentProviderHolder holder = null;
9865        try {
9866            holder = getContentProviderExternalUnchecked(name, null, userId);
9867            if (holder != null) {
9868                return holder.provider.getType(uri);
9869            }
9870        } catch (RemoteException e) {
9871            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9872            return null;
9873        } finally {
9874            // We need to clear the identity to call removeContentProviderExternalUnchecked
9875            if (!clearedIdentity) {
9876                ident = Binder.clearCallingIdentity();
9877            }
9878            try {
9879                if (holder != null) {
9880                    removeContentProviderExternalUnchecked(name, null, userId);
9881                }
9882            } finally {
9883                Binder.restoreCallingIdentity(ident);
9884            }
9885        }
9886
9887        return null;
9888    }
9889
9890    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9891        if (UserHandle.getUserId(callingUid) == userId) {
9892            return true;
9893        }
9894        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9895                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9896                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9897                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9898                return true;
9899        }
9900        return false;
9901    }
9902
9903    // =========================================================
9904    // GLOBAL MANAGEMENT
9905    // =========================================================
9906
9907    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9908            boolean isolated, int isolatedUid) {
9909        String proc = customProcess != null ? customProcess : info.processName;
9910        BatteryStatsImpl.Uid.Proc ps = null;
9911        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9912        int uid = info.uid;
9913        if (isolated) {
9914            if (isolatedUid == 0) {
9915                int userId = UserHandle.getUserId(uid);
9916                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9917                while (true) {
9918                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9919                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9920                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9921                    }
9922                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9923                    mNextIsolatedProcessUid++;
9924                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9925                        // No process for this uid, use it.
9926                        break;
9927                    }
9928                    stepsLeft--;
9929                    if (stepsLeft <= 0) {
9930                        return null;
9931                    }
9932                }
9933            } else {
9934                // Special case for startIsolatedProcess (internal only), where
9935                // the uid of the isolated process is specified by the caller.
9936                uid = isolatedUid;
9937            }
9938        }
9939        return new ProcessRecord(stats, info, proc, uid);
9940    }
9941
9942    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9943            String abiOverride) {
9944        ProcessRecord app;
9945        if (!isolated) {
9946            app = getProcessRecordLocked(info.processName, info.uid, true);
9947        } else {
9948            app = null;
9949        }
9950
9951        if (app == null) {
9952            app = newProcessRecordLocked(info, null, isolated, 0);
9953            mProcessNames.put(info.processName, app.uid, app);
9954            if (isolated) {
9955                mIsolatedProcesses.put(app.uid, app);
9956            }
9957            updateLruProcessLocked(app, false, null);
9958            updateOomAdjLocked();
9959        }
9960
9961        // This package really, really can not be stopped.
9962        try {
9963            AppGlobals.getPackageManager().setPackageStoppedState(
9964                    info.packageName, false, UserHandle.getUserId(app.uid));
9965        } catch (RemoteException e) {
9966        } catch (IllegalArgumentException e) {
9967            Slog.w(TAG, "Failed trying to unstop package "
9968                    + info.packageName + ": " + e);
9969        }
9970
9971        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9972                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9973            app.persistent = true;
9974            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9975        }
9976        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9977            mPersistentStartingProcesses.add(app);
9978            startProcessLocked(app, "added application", app.processName, abiOverride,
9979                    null /* entryPoint */, null /* entryPointArgs */);
9980        }
9981
9982        return app;
9983    }
9984
9985    public void unhandledBack() {
9986        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9987                "unhandledBack()");
9988
9989        synchronized(this) {
9990            final long origId = Binder.clearCallingIdentity();
9991            try {
9992                getFocusedStack().unhandledBackLocked();
9993            } finally {
9994                Binder.restoreCallingIdentity(origId);
9995            }
9996        }
9997    }
9998
9999    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10000        enforceNotIsolatedCaller("openContentUri");
10001        final int userId = UserHandle.getCallingUserId();
10002        String name = uri.getAuthority();
10003        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10004        ParcelFileDescriptor pfd = null;
10005        if (cph != null) {
10006            // We record the binder invoker's uid in thread-local storage before
10007            // going to the content provider to open the file.  Later, in the code
10008            // that handles all permissions checks, we look for this uid and use
10009            // that rather than the Activity Manager's own uid.  The effect is that
10010            // we do the check against the caller's permissions even though it looks
10011            // to the content provider like the Activity Manager itself is making
10012            // the request.
10013            sCallerIdentity.set(new Identity(
10014                    Binder.getCallingPid(), Binder.getCallingUid()));
10015            try {
10016                pfd = cph.provider.openFile(null, uri, "r", null);
10017            } catch (FileNotFoundException e) {
10018                // do nothing; pfd will be returned null
10019            } finally {
10020                // Ensure that whatever happens, we clean up the identity state
10021                sCallerIdentity.remove();
10022            }
10023
10024            // We've got the fd now, so we're done with the provider.
10025            removeContentProviderExternalUnchecked(name, null, userId);
10026        } else {
10027            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10028        }
10029        return pfd;
10030    }
10031
10032    // Actually is sleeping or shutting down or whatever else in the future
10033    // is an inactive state.
10034    public boolean isSleepingOrShuttingDown() {
10035        return isSleeping() || mShuttingDown;
10036    }
10037
10038    public boolean isSleeping() {
10039        return mSleeping;
10040    }
10041
10042    void goingToSleep() {
10043        synchronized(this) {
10044            mWentToSleep = true;
10045            goToSleepIfNeededLocked();
10046        }
10047    }
10048
10049    void finishRunningVoiceLocked() {
10050        if (mRunningVoice) {
10051            mRunningVoice = false;
10052            goToSleepIfNeededLocked();
10053        }
10054    }
10055
10056    void goToSleepIfNeededLocked() {
10057        if (mWentToSleep && !mRunningVoice) {
10058            if (!mSleeping) {
10059                mSleeping = true;
10060                mStackSupervisor.goingToSleepLocked();
10061
10062                // Initialize the wake times of all processes.
10063                checkExcessivePowerUsageLocked(false);
10064                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10065                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10066                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10067            }
10068        }
10069    }
10070
10071    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10072        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10073            // Never persist the home stack.
10074            return;
10075        }
10076        mTaskPersister.wakeup(task, flush);
10077    }
10078
10079    @Override
10080    public boolean shutdown(int timeout) {
10081        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10082                != PackageManager.PERMISSION_GRANTED) {
10083            throw new SecurityException("Requires permission "
10084                    + android.Manifest.permission.SHUTDOWN);
10085        }
10086
10087        boolean timedout = false;
10088
10089        synchronized(this) {
10090            mShuttingDown = true;
10091            updateEventDispatchingLocked();
10092            timedout = mStackSupervisor.shutdownLocked(timeout);
10093        }
10094
10095        mAppOpsService.shutdown();
10096        if (mUsageStatsService != null) {
10097            mUsageStatsService.prepareShutdown();
10098        }
10099        mBatteryStatsService.shutdown();
10100        synchronized (this) {
10101            mProcessStats.shutdownLocked();
10102        }
10103        notifyTaskPersisterLocked(null, true);
10104
10105        return timedout;
10106    }
10107
10108    public final void activitySlept(IBinder token) {
10109        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10110
10111        final long origId = Binder.clearCallingIdentity();
10112
10113        synchronized (this) {
10114            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10115            if (r != null) {
10116                mStackSupervisor.activitySleptLocked(r);
10117            }
10118        }
10119
10120        Binder.restoreCallingIdentity(origId);
10121    }
10122
10123    void logLockScreen(String msg) {
10124        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
10125                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
10126                mWentToSleep + " mSleeping=" + mSleeping);
10127    }
10128
10129    private void comeOutOfSleepIfNeededLocked() {
10130        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
10131            if (mSleeping) {
10132                mSleeping = false;
10133                mStackSupervisor.comeOutOfSleepIfNeededLocked();
10134            }
10135        }
10136    }
10137
10138    void wakingUp() {
10139        synchronized(this) {
10140            mWentToSleep = false;
10141            comeOutOfSleepIfNeededLocked();
10142        }
10143    }
10144
10145    void startRunningVoiceLocked() {
10146        if (!mRunningVoice) {
10147            mRunningVoice = true;
10148            comeOutOfSleepIfNeededLocked();
10149        }
10150    }
10151
10152    private void updateEventDispatchingLocked() {
10153        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10154    }
10155
10156    public void setLockScreenShown(boolean shown) {
10157        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10158                != PackageManager.PERMISSION_GRANTED) {
10159            throw new SecurityException("Requires permission "
10160                    + android.Manifest.permission.DEVICE_POWER);
10161        }
10162
10163        synchronized(this) {
10164            long ident = Binder.clearCallingIdentity();
10165            try {
10166                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10167                mLockScreenShown = shown;
10168                comeOutOfSleepIfNeededLocked();
10169            } finally {
10170                Binder.restoreCallingIdentity(ident);
10171            }
10172        }
10173    }
10174
10175    @Override
10176    public void stopAppSwitches() {
10177        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10178                != PackageManager.PERMISSION_GRANTED) {
10179            throw new SecurityException("Requires permission "
10180                    + android.Manifest.permission.STOP_APP_SWITCHES);
10181        }
10182
10183        synchronized(this) {
10184            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10185                    + APP_SWITCH_DELAY_TIME;
10186            mDidAppSwitch = false;
10187            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10188            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10189            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10190        }
10191    }
10192
10193    public void resumeAppSwitches() {
10194        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10195                != PackageManager.PERMISSION_GRANTED) {
10196            throw new SecurityException("Requires permission "
10197                    + android.Manifest.permission.STOP_APP_SWITCHES);
10198        }
10199
10200        synchronized(this) {
10201            // Note that we don't execute any pending app switches... we will
10202            // let those wait until either the timeout, or the next start
10203            // activity request.
10204            mAppSwitchesAllowedTime = 0;
10205        }
10206    }
10207
10208    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10209            int callingPid, int callingUid, String name) {
10210        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10211            return true;
10212        }
10213
10214        int perm = checkComponentPermission(
10215                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10216                sourceUid, -1, true);
10217        if (perm == PackageManager.PERMISSION_GRANTED) {
10218            return true;
10219        }
10220
10221        // If the actual IPC caller is different from the logical source, then
10222        // also see if they are allowed to control app switches.
10223        if (callingUid != -1 && callingUid != sourceUid) {
10224            perm = checkComponentPermission(
10225                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10226                    callingUid, -1, true);
10227            if (perm == PackageManager.PERMISSION_GRANTED) {
10228                return true;
10229            }
10230        }
10231
10232        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10233        return false;
10234    }
10235
10236    public void setDebugApp(String packageName, boolean waitForDebugger,
10237            boolean persistent) {
10238        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10239                "setDebugApp()");
10240
10241        long ident = Binder.clearCallingIdentity();
10242        try {
10243            // Note that this is not really thread safe if there are multiple
10244            // callers into it at the same time, but that's not a situation we
10245            // care about.
10246            if (persistent) {
10247                final ContentResolver resolver = mContext.getContentResolver();
10248                Settings.Global.putString(
10249                    resolver, Settings.Global.DEBUG_APP,
10250                    packageName);
10251                Settings.Global.putInt(
10252                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10253                    waitForDebugger ? 1 : 0);
10254            }
10255
10256            synchronized (this) {
10257                if (!persistent) {
10258                    mOrigDebugApp = mDebugApp;
10259                    mOrigWaitForDebugger = mWaitForDebugger;
10260                }
10261                mDebugApp = packageName;
10262                mWaitForDebugger = waitForDebugger;
10263                mDebugTransient = !persistent;
10264                if (packageName != null) {
10265                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10266                            false, UserHandle.USER_ALL, "set debug app");
10267                }
10268            }
10269        } finally {
10270            Binder.restoreCallingIdentity(ident);
10271        }
10272    }
10273
10274    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10275        synchronized (this) {
10276            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10277            if (!isDebuggable) {
10278                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10279                    throw new SecurityException("Process not debuggable: " + app.packageName);
10280                }
10281            }
10282
10283            mOpenGlTraceApp = processName;
10284        }
10285    }
10286
10287    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10288        synchronized (this) {
10289            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10290            if (!isDebuggable) {
10291                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10292                    throw new SecurityException("Process not debuggable: " + app.packageName);
10293                }
10294            }
10295            mProfileApp = processName;
10296            mProfileFile = profilerInfo.profileFile;
10297            if (mProfileFd != null) {
10298                try {
10299                    mProfileFd.close();
10300                } catch (IOException e) {
10301                }
10302                mProfileFd = null;
10303            }
10304            mProfileFd = profilerInfo.profileFd;
10305            mSamplingInterval = profilerInfo.samplingInterval;
10306            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10307            mProfileType = 0;
10308        }
10309    }
10310
10311    @Override
10312    public void setAlwaysFinish(boolean enabled) {
10313        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10314                "setAlwaysFinish()");
10315
10316        Settings.Global.putInt(
10317                mContext.getContentResolver(),
10318                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10319
10320        synchronized (this) {
10321            mAlwaysFinishActivities = enabled;
10322        }
10323    }
10324
10325    @Override
10326    public void setActivityController(IActivityController controller) {
10327        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10328                "setActivityController()");
10329        synchronized (this) {
10330            mController = controller;
10331            Watchdog.getInstance().setActivityController(controller);
10332        }
10333    }
10334
10335    @Override
10336    public void setUserIsMonkey(boolean userIsMonkey) {
10337        synchronized (this) {
10338            synchronized (mPidsSelfLocked) {
10339                final int callingPid = Binder.getCallingPid();
10340                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10341                if (precessRecord == null) {
10342                    throw new SecurityException("Unknown process: " + callingPid);
10343                }
10344                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10345                    throw new SecurityException("Only an instrumentation process "
10346                            + "with a UiAutomation can call setUserIsMonkey");
10347                }
10348            }
10349            mUserIsMonkey = userIsMonkey;
10350        }
10351    }
10352
10353    @Override
10354    public boolean isUserAMonkey() {
10355        synchronized (this) {
10356            // If there is a controller also implies the user is a monkey.
10357            return (mUserIsMonkey || mController != null);
10358        }
10359    }
10360
10361    public void requestBugReport() {
10362        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10363        SystemProperties.set("ctl.start", "bugreport");
10364    }
10365
10366    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10367        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10368    }
10369
10370    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10371        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10372            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10373        }
10374        return KEY_DISPATCHING_TIMEOUT;
10375    }
10376
10377    @Override
10378    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10379        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10380                != PackageManager.PERMISSION_GRANTED) {
10381            throw new SecurityException("Requires permission "
10382                    + android.Manifest.permission.FILTER_EVENTS);
10383        }
10384        ProcessRecord proc;
10385        long timeout;
10386        synchronized (this) {
10387            synchronized (mPidsSelfLocked) {
10388                proc = mPidsSelfLocked.get(pid);
10389            }
10390            timeout = getInputDispatchingTimeoutLocked(proc);
10391        }
10392
10393        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10394            return -1;
10395        }
10396
10397        return timeout;
10398    }
10399
10400    /**
10401     * Handle input dispatching timeouts.
10402     * Returns whether input dispatching should be aborted or not.
10403     */
10404    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10405            final ActivityRecord activity, final ActivityRecord parent,
10406            final boolean aboveSystem, String reason) {
10407        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10408                != PackageManager.PERMISSION_GRANTED) {
10409            throw new SecurityException("Requires permission "
10410                    + android.Manifest.permission.FILTER_EVENTS);
10411        }
10412
10413        final String annotation;
10414        if (reason == null) {
10415            annotation = "Input dispatching timed out";
10416        } else {
10417            annotation = "Input dispatching timed out (" + reason + ")";
10418        }
10419
10420        if (proc != null) {
10421            synchronized (this) {
10422                if (proc.debugging) {
10423                    return false;
10424                }
10425
10426                if (mDidDexOpt) {
10427                    // Give more time since we were dexopting.
10428                    mDidDexOpt = false;
10429                    return false;
10430                }
10431
10432                if (proc.instrumentationClass != null) {
10433                    Bundle info = new Bundle();
10434                    info.putString("shortMsg", "keyDispatchingTimedOut");
10435                    info.putString("longMsg", annotation);
10436                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10437                    return true;
10438                }
10439            }
10440            mHandler.post(new Runnable() {
10441                @Override
10442                public void run() {
10443                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10444                }
10445            });
10446        }
10447
10448        return true;
10449    }
10450
10451    public Bundle getAssistContextExtras(int requestType) {
10452        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10453                "getAssistContextExtras()");
10454        PendingAssistExtras pae;
10455        Bundle extras = new Bundle();
10456        synchronized (this) {
10457            ActivityRecord activity = getFocusedStack().mResumedActivity;
10458            if (activity == null) {
10459                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10460                return null;
10461            }
10462            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10463            if (activity.app == null || activity.app.thread == null) {
10464                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10465                return extras;
10466            }
10467            if (activity.app.pid == Binder.getCallingPid()) {
10468                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10469                return extras;
10470            }
10471            pae = new PendingAssistExtras(activity);
10472            try {
10473                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10474                        requestType);
10475                mPendingAssistExtras.add(pae);
10476                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10477            } catch (RemoteException e) {
10478                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10479                return extras;
10480            }
10481        }
10482        synchronized (pae) {
10483            while (!pae.haveResult) {
10484                try {
10485                    pae.wait();
10486                } catch (InterruptedException e) {
10487                }
10488            }
10489            if (pae.result != null) {
10490                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10491            }
10492        }
10493        synchronized (this) {
10494            mPendingAssistExtras.remove(pae);
10495            mHandler.removeCallbacks(pae);
10496        }
10497        return extras;
10498    }
10499
10500    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10501        PendingAssistExtras pae = (PendingAssistExtras)token;
10502        synchronized (pae) {
10503            pae.result = extras;
10504            pae.haveResult = true;
10505            pae.notifyAll();
10506        }
10507    }
10508
10509    public void registerProcessObserver(IProcessObserver observer) {
10510        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10511                "registerProcessObserver()");
10512        synchronized (this) {
10513            mProcessObservers.register(observer);
10514        }
10515    }
10516
10517    @Override
10518    public void unregisterProcessObserver(IProcessObserver observer) {
10519        synchronized (this) {
10520            mProcessObservers.unregister(observer);
10521        }
10522    }
10523
10524    @Override
10525    public boolean convertFromTranslucent(IBinder token) {
10526        final long origId = Binder.clearCallingIdentity();
10527        try {
10528            synchronized (this) {
10529                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10530                if (r == null) {
10531                    return false;
10532                }
10533                final boolean translucentChanged = r.changeWindowTranslucency(true);
10534                if (translucentChanged) {
10535                    r.task.stack.releaseBackgroundResources();
10536                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10537                }
10538                mWindowManager.setAppFullscreen(token, true);
10539                return translucentChanged;
10540            }
10541        } finally {
10542            Binder.restoreCallingIdentity(origId);
10543        }
10544    }
10545
10546    @Override
10547    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10548        final long origId = Binder.clearCallingIdentity();
10549        try {
10550            synchronized (this) {
10551                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10552                if (r == null) {
10553                    return false;
10554                }
10555                int index = r.task.mActivities.lastIndexOf(r);
10556                if (index > 0) {
10557                    ActivityRecord under = r.task.mActivities.get(index - 1);
10558                    under.returningOptions = options;
10559                }
10560                final boolean translucentChanged = r.changeWindowTranslucency(false);
10561                if (translucentChanged) {
10562                    r.task.stack.convertToTranslucent(r);
10563                }
10564                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10565                mWindowManager.setAppFullscreen(token, false);
10566                return translucentChanged;
10567            }
10568        } finally {
10569            Binder.restoreCallingIdentity(origId);
10570        }
10571    }
10572
10573    @Override
10574    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10575        final long origId = Binder.clearCallingIdentity();
10576        try {
10577            synchronized (this) {
10578                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10579                if (r != null) {
10580                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10581                }
10582            }
10583            return false;
10584        } finally {
10585            Binder.restoreCallingIdentity(origId);
10586        }
10587    }
10588
10589    @Override
10590    public boolean isBackgroundVisibleBehind(IBinder token) {
10591        final long origId = Binder.clearCallingIdentity();
10592        try {
10593            synchronized (this) {
10594                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10595                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10596                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10597                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10598                return visible;
10599            }
10600        } finally {
10601            Binder.restoreCallingIdentity(origId);
10602        }
10603    }
10604
10605    @Override
10606    public ActivityOptions getActivityOptions(IBinder token) {
10607        final long origId = Binder.clearCallingIdentity();
10608        try {
10609            synchronized (this) {
10610                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10611                if (r != null) {
10612                    final ActivityOptions activityOptions = r.pendingOptions;
10613                    r.pendingOptions = null;
10614                    return activityOptions;
10615                }
10616                return null;
10617            }
10618        } finally {
10619            Binder.restoreCallingIdentity(origId);
10620        }
10621    }
10622
10623    @Override
10624    public void setImmersive(IBinder token, boolean immersive) {
10625        synchronized(this) {
10626            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10627            if (r == null) {
10628                throw new IllegalArgumentException();
10629            }
10630            r.immersive = immersive;
10631
10632            // update associated state if we're frontmost
10633            if (r == mFocusedActivity) {
10634                if (DEBUG_IMMERSIVE) {
10635                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10636                }
10637                applyUpdateLockStateLocked(r);
10638            }
10639        }
10640    }
10641
10642    @Override
10643    public boolean isImmersive(IBinder token) {
10644        synchronized (this) {
10645            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10646            if (r == null) {
10647                throw new IllegalArgumentException();
10648            }
10649            return r.immersive;
10650        }
10651    }
10652
10653    public boolean isTopActivityImmersive() {
10654        enforceNotIsolatedCaller("startActivity");
10655        synchronized (this) {
10656            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10657            return (r != null) ? r.immersive : false;
10658        }
10659    }
10660
10661    @Override
10662    public boolean isTopOfTask(IBinder token) {
10663        synchronized (this) {
10664            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10665            if (r == null) {
10666                throw new IllegalArgumentException();
10667            }
10668            return r.task.getTopActivity() == r;
10669        }
10670    }
10671
10672    public final void enterSafeMode() {
10673        synchronized(this) {
10674            // It only makes sense to do this before the system is ready
10675            // and started launching other packages.
10676            if (!mSystemReady) {
10677                try {
10678                    AppGlobals.getPackageManager().enterSafeMode();
10679                } catch (RemoteException e) {
10680                }
10681            }
10682
10683            mSafeMode = true;
10684        }
10685    }
10686
10687    public final void showSafeModeOverlay() {
10688        View v = LayoutInflater.from(mContext).inflate(
10689                com.android.internal.R.layout.safe_mode, null);
10690        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10691        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10692        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10693        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10694        lp.gravity = Gravity.BOTTOM | Gravity.START;
10695        lp.format = v.getBackground().getOpacity();
10696        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10697                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10698        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10699        ((WindowManager)mContext.getSystemService(
10700                Context.WINDOW_SERVICE)).addView(v, lp);
10701    }
10702
10703    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10704        if (!(sender instanceof PendingIntentRecord)) {
10705            return;
10706        }
10707        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10708        synchronized (stats) {
10709            if (mBatteryStatsService.isOnBattery()) {
10710                mBatteryStatsService.enforceCallingPermission();
10711                PendingIntentRecord rec = (PendingIntentRecord)sender;
10712                int MY_UID = Binder.getCallingUid();
10713                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10714                BatteryStatsImpl.Uid.Pkg pkg =
10715                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10716                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10717                pkg.incWakeupsLocked();
10718            }
10719        }
10720    }
10721
10722    public boolean killPids(int[] pids, String pReason, boolean secure) {
10723        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10724            throw new SecurityException("killPids only available to the system");
10725        }
10726        String reason = (pReason == null) ? "Unknown" : pReason;
10727        // XXX Note: don't acquire main activity lock here, because the window
10728        // manager calls in with its locks held.
10729
10730        boolean killed = false;
10731        synchronized (mPidsSelfLocked) {
10732            int[] types = new int[pids.length];
10733            int worstType = 0;
10734            for (int i=0; i<pids.length; i++) {
10735                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10736                if (proc != null) {
10737                    int type = proc.setAdj;
10738                    types[i] = type;
10739                    if (type > worstType) {
10740                        worstType = type;
10741                    }
10742                }
10743            }
10744
10745            // If the worst oom_adj is somewhere in the cached proc LRU range,
10746            // then constrain it so we will kill all cached procs.
10747            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10748                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10749                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10750            }
10751
10752            // If this is not a secure call, don't let it kill processes that
10753            // are important.
10754            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10755                worstType = ProcessList.SERVICE_ADJ;
10756            }
10757
10758            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10759            for (int i=0; i<pids.length; i++) {
10760                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10761                if (proc == null) {
10762                    continue;
10763                }
10764                int adj = proc.setAdj;
10765                if (adj >= worstType && !proc.killedByAm) {
10766                    proc.kill(reason, true);
10767                    killed = true;
10768                }
10769            }
10770        }
10771        return killed;
10772    }
10773
10774    @Override
10775    public void killUid(int uid, String reason) {
10776        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10777            throw new SecurityException("killUid only available to the system");
10778        }
10779        synchronized (this) {
10780            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10781                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10782                    reason != null ? reason : "kill uid");
10783        }
10784    }
10785
10786    @Override
10787    public boolean killProcessesBelowForeground(String reason) {
10788        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10789            throw new SecurityException("killProcessesBelowForeground() only available to system");
10790        }
10791
10792        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10793    }
10794
10795    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10796        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10797            throw new SecurityException("killProcessesBelowAdj() only available to system");
10798        }
10799
10800        boolean killed = false;
10801        synchronized (mPidsSelfLocked) {
10802            final int size = mPidsSelfLocked.size();
10803            for (int i = 0; i < size; i++) {
10804                final int pid = mPidsSelfLocked.keyAt(i);
10805                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10806                if (proc == null) continue;
10807
10808                final int adj = proc.setAdj;
10809                if (adj > belowAdj && !proc.killedByAm) {
10810                    proc.kill(reason, true);
10811                    killed = true;
10812                }
10813            }
10814        }
10815        return killed;
10816    }
10817
10818    @Override
10819    public void hang(final IBinder who, boolean allowRestart) {
10820        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10821                != PackageManager.PERMISSION_GRANTED) {
10822            throw new SecurityException("Requires permission "
10823                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10824        }
10825
10826        final IBinder.DeathRecipient death = new DeathRecipient() {
10827            @Override
10828            public void binderDied() {
10829                synchronized (this) {
10830                    notifyAll();
10831                }
10832            }
10833        };
10834
10835        try {
10836            who.linkToDeath(death, 0);
10837        } catch (RemoteException e) {
10838            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10839            return;
10840        }
10841
10842        synchronized (this) {
10843            Watchdog.getInstance().setAllowRestart(allowRestart);
10844            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10845            synchronized (death) {
10846                while (who.isBinderAlive()) {
10847                    try {
10848                        death.wait();
10849                    } catch (InterruptedException e) {
10850                    }
10851                }
10852            }
10853            Watchdog.getInstance().setAllowRestart(true);
10854        }
10855    }
10856
10857    @Override
10858    public void restart() {
10859        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10860                != PackageManager.PERMISSION_GRANTED) {
10861            throw new SecurityException("Requires permission "
10862                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10863        }
10864
10865        Log.i(TAG, "Sending shutdown broadcast...");
10866
10867        BroadcastReceiver br = new BroadcastReceiver() {
10868            @Override public void onReceive(Context context, Intent intent) {
10869                // Now the broadcast is done, finish up the low-level shutdown.
10870                Log.i(TAG, "Shutting down activity manager...");
10871                shutdown(10000);
10872                Log.i(TAG, "Shutdown complete, restarting!");
10873                Process.killProcess(Process.myPid());
10874                System.exit(10);
10875            }
10876        };
10877
10878        // First send the high-level shut down broadcast.
10879        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10880        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10881        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10882        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10883        mContext.sendOrderedBroadcastAsUser(intent,
10884                UserHandle.ALL, null, br, mHandler, 0, null, null);
10885        */
10886        br.onReceive(mContext, intent);
10887    }
10888
10889    private long getLowRamTimeSinceIdle(long now) {
10890        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10891    }
10892
10893    @Override
10894    public void performIdleMaintenance() {
10895        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10896                != PackageManager.PERMISSION_GRANTED) {
10897            throw new SecurityException("Requires permission "
10898                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10899        }
10900
10901        synchronized (this) {
10902            final long now = SystemClock.uptimeMillis();
10903            final long timeSinceLastIdle = now - mLastIdleTime;
10904            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10905            mLastIdleTime = now;
10906            mLowRamTimeSinceLastIdle = 0;
10907            if (mLowRamStartTime != 0) {
10908                mLowRamStartTime = now;
10909            }
10910
10911            StringBuilder sb = new StringBuilder(128);
10912            sb.append("Idle maintenance over ");
10913            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10914            sb.append(" low RAM for ");
10915            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10916            Slog.i(TAG, sb.toString());
10917
10918            // If at least 1/3 of our time since the last idle period has been spent
10919            // with RAM low, then we want to kill processes.
10920            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10921
10922            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10923                ProcessRecord proc = mLruProcesses.get(i);
10924                if (proc.notCachedSinceIdle) {
10925                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10926                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10927                        if (doKilling && proc.initialIdlePss != 0
10928                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10929                            proc.kill("idle maint (pss " + proc.lastPss
10930                                    + " from " + proc.initialIdlePss + ")", true);
10931                        }
10932                    }
10933                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10934                    proc.notCachedSinceIdle = true;
10935                    proc.initialIdlePss = 0;
10936                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10937                            isSleeping(), now);
10938                }
10939            }
10940
10941            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10942            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10943        }
10944    }
10945
10946    private void retrieveSettings() {
10947        final ContentResolver resolver = mContext.getContentResolver();
10948        String debugApp = Settings.Global.getString(
10949            resolver, Settings.Global.DEBUG_APP);
10950        boolean waitForDebugger = Settings.Global.getInt(
10951            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10952        boolean alwaysFinishActivities = Settings.Global.getInt(
10953            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10954        boolean forceRtl = Settings.Global.getInt(
10955                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10956        // Transfer any global setting for forcing RTL layout, into a System Property
10957        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10958
10959        Configuration configuration = new Configuration();
10960        Settings.System.getConfiguration(resolver, configuration);
10961        if (forceRtl) {
10962            // This will take care of setting the correct layout direction flags
10963            configuration.setLayoutDirection(configuration.locale);
10964        }
10965
10966        synchronized (this) {
10967            mDebugApp = mOrigDebugApp = debugApp;
10968            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10969            mAlwaysFinishActivities = alwaysFinishActivities;
10970            // This happens before any activities are started, so we can
10971            // change mConfiguration in-place.
10972            updateConfigurationLocked(configuration, null, false, true);
10973            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10974        }
10975    }
10976
10977    /** Loads resources after the current configuration has been set. */
10978    private void loadResourcesOnSystemReady() {
10979        final Resources res = mContext.getResources();
10980        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10981        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10982        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10983    }
10984
10985    public boolean testIsSystemReady() {
10986        // no need to synchronize(this) just to read & return the value
10987        return mSystemReady;
10988    }
10989
10990    private static File getCalledPreBootReceiversFile() {
10991        File dataDir = Environment.getDataDirectory();
10992        File systemDir = new File(dataDir, "system");
10993        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10994        return fname;
10995    }
10996
10997    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10998        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10999        File file = getCalledPreBootReceiversFile();
11000        FileInputStream fis = null;
11001        try {
11002            fis = new FileInputStream(file);
11003            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11004            int fvers = dis.readInt();
11005            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11006                String vers = dis.readUTF();
11007                String codename = dis.readUTF();
11008                String build = dis.readUTF();
11009                if (android.os.Build.VERSION.RELEASE.equals(vers)
11010                        && android.os.Build.VERSION.CODENAME.equals(codename)
11011                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11012                    int num = dis.readInt();
11013                    while (num > 0) {
11014                        num--;
11015                        String pkg = dis.readUTF();
11016                        String cls = dis.readUTF();
11017                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11018                    }
11019                }
11020            }
11021        } catch (FileNotFoundException e) {
11022        } catch (IOException e) {
11023            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11024        } finally {
11025            if (fis != null) {
11026                try {
11027                    fis.close();
11028                } catch (IOException e) {
11029                }
11030            }
11031        }
11032        return lastDoneReceivers;
11033    }
11034
11035    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11036        File file = getCalledPreBootReceiversFile();
11037        FileOutputStream fos = null;
11038        DataOutputStream dos = null;
11039        try {
11040            fos = new FileOutputStream(file);
11041            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11042            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11043            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11044            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11045            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11046            dos.writeInt(list.size());
11047            for (int i=0; i<list.size(); i++) {
11048                dos.writeUTF(list.get(i).getPackageName());
11049                dos.writeUTF(list.get(i).getClassName());
11050            }
11051        } catch (IOException e) {
11052            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11053            file.delete();
11054        } finally {
11055            FileUtils.sync(fos);
11056            if (dos != null) {
11057                try {
11058                    dos.close();
11059                } catch (IOException e) {
11060                    // TODO Auto-generated catch block
11061                    e.printStackTrace();
11062                }
11063            }
11064        }
11065    }
11066
11067    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11068            ArrayList<ComponentName> doneReceivers, int userId) {
11069        boolean waitingUpdate = false;
11070        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11071        List<ResolveInfo> ris = null;
11072        try {
11073            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11074                    intent, null, 0, userId);
11075        } catch (RemoteException e) {
11076        }
11077        if (ris != null) {
11078            for (int i=ris.size()-1; i>=0; i--) {
11079                if ((ris.get(i).activityInfo.applicationInfo.flags
11080                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11081                    ris.remove(i);
11082                }
11083            }
11084            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11085
11086            // For User 0, load the version number. When delivering to a new user, deliver
11087            // to all receivers.
11088            if (userId == UserHandle.USER_OWNER) {
11089                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11090                for (int i=0; i<ris.size(); i++) {
11091                    ActivityInfo ai = ris.get(i).activityInfo;
11092                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11093                    if (lastDoneReceivers.contains(comp)) {
11094                        // We already did the pre boot receiver for this app with the current
11095                        // platform version, so don't do it again...
11096                        ris.remove(i);
11097                        i--;
11098                        // ...however, do keep it as one that has been done, so we don't
11099                        // forget about it when rewriting the file of last done receivers.
11100                        doneReceivers.add(comp);
11101                    }
11102                }
11103            }
11104
11105            // If primary user, send broadcast to all available users, else just to userId
11106            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11107                    : new int[] { userId };
11108            for (int i = 0; i < ris.size(); i++) {
11109                ActivityInfo ai = ris.get(i).activityInfo;
11110                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11111                doneReceivers.add(comp);
11112                intent.setComponent(comp);
11113                for (int j=0; j<users.length; j++) {
11114                    IIntentReceiver finisher = null;
11115                    // On last receiver and user, set up a completion callback
11116                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11117                        finisher = new IIntentReceiver.Stub() {
11118                            public void performReceive(Intent intent, int resultCode,
11119                                    String data, Bundle extras, boolean ordered,
11120                                    boolean sticky, int sendingUser) {
11121                                // The raw IIntentReceiver interface is called
11122                                // with the AM lock held, so redispatch to
11123                                // execute our code without the lock.
11124                                mHandler.post(onFinishCallback);
11125                            }
11126                        };
11127                    }
11128                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11129                            + " for user " + users[j]);
11130                    broadcastIntentLocked(null, null, intent, null, finisher,
11131                            0, null, null, null, AppOpsManager.OP_NONE,
11132                            true, false, MY_PID, Process.SYSTEM_UID,
11133                            users[j]);
11134                    if (finisher != null) {
11135                        waitingUpdate = true;
11136                    }
11137                }
11138            }
11139        }
11140
11141        return waitingUpdate;
11142    }
11143
11144    public void systemReady(final Runnable goingCallback) {
11145        synchronized(this) {
11146            if (mSystemReady) {
11147                // If we're done calling all the receivers, run the next "boot phase" passed in
11148                // by the SystemServer
11149                if (goingCallback != null) {
11150                    goingCallback.run();
11151                }
11152                return;
11153            }
11154
11155            // Make sure we have the current profile info, since it is needed for
11156            // security checks.
11157            updateCurrentProfileIdsLocked();
11158
11159            if (mRecentTasks == null) {
11160                mRecentTasks = mTaskPersister.restoreTasksLocked();
11161                if (!mRecentTasks.isEmpty()) {
11162                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11163                }
11164                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11165                mTaskPersister.startPersisting();
11166            }
11167
11168            // Check to see if there are any update receivers to run.
11169            if (!mDidUpdate) {
11170                if (mWaitingUpdate) {
11171                    return;
11172                }
11173                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11174                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11175                    public void run() {
11176                        synchronized (ActivityManagerService.this) {
11177                            mDidUpdate = true;
11178                        }
11179                        writeLastDonePreBootReceivers(doneReceivers);
11180                        showBootMessage(mContext.getText(
11181                                R.string.android_upgrading_complete),
11182                                false);
11183                        systemReady(goingCallback);
11184                    }
11185                }, doneReceivers, UserHandle.USER_OWNER);
11186
11187                if (mWaitingUpdate) {
11188                    return;
11189                }
11190                mDidUpdate = true;
11191            }
11192
11193            mAppOpsService.systemReady();
11194            mSystemReady = true;
11195        }
11196
11197        ArrayList<ProcessRecord> procsToKill = null;
11198        synchronized(mPidsSelfLocked) {
11199            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11200                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11201                if (!isAllowedWhileBooting(proc.info)){
11202                    if (procsToKill == null) {
11203                        procsToKill = new ArrayList<ProcessRecord>();
11204                    }
11205                    procsToKill.add(proc);
11206                }
11207            }
11208        }
11209
11210        synchronized(this) {
11211            if (procsToKill != null) {
11212                for (int i=procsToKill.size()-1; i>=0; i--) {
11213                    ProcessRecord proc = procsToKill.get(i);
11214                    Slog.i(TAG, "Removing system update proc: " + proc);
11215                    removeProcessLocked(proc, true, false, "system update done");
11216                }
11217            }
11218
11219            // Now that we have cleaned up any update processes, we
11220            // are ready to start launching real processes and know that
11221            // we won't trample on them any more.
11222            mProcessesReady = true;
11223        }
11224
11225        Slog.i(TAG, "System now ready");
11226        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11227            SystemClock.uptimeMillis());
11228
11229        synchronized(this) {
11230            // Make sure we have no pre-ready processes sitting around.
11231
11232            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11233                ResolveInfo ri = mContext.getPackageManager()
11234                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11235                                STOCK_PM_FLAGS);
11236                CharSequence errorMsg = null;
11237                if (ri != null) {
11238                    ActivityInfo ai = ri.activityInfo;
11239                    ApplicationInfo app = ai.applicationInfo;
11240                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11241                        mTopAction = Intent.ACTION_FACTORY_TEST;
11242                        mTopData = null;
11243                        mTopComponent = new ComponentName(app.packageName,
11244                                ai.name);
11245                    } else {
11246                        errorMsg = mContext.getResources().getText(
11247                                com.android.internal.R.string.factorytest_not_system);
11248                    }
11249                } else {
11250                    errorMsg = mContext.getResources().getText(
11251                            com.android.internal.R.string.factorytest_no_action);
11252                }
11253                if (errorMsg != null) {
11254                    mTopAction = null;
11255                    mTopData = null;
11256                    mTopComponent = null;
11257                    Message msg = Message.obtain();
11258                    msg.what = SHOW_FACTORY_ERROR_MSG;
11259                    msg.getData().putCharSequence("msg", errorMsg);
11260                    mHandler.sendMessage(msg);
11261                }
11262            }
11263        }
11264
11265        retrieveSettings();
11266        loadResourcesOnSystemReady();
11267
11268        synchronized (this) {
11269            readGrantedUriPermissionsLocked();
11270        }
11271
11272        if (goingCallback != null) goingCallback.run();
11273
11274        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11275                Integer.toString(mCurrentUserId), mCurrentUserId);
11276        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11277                Integer.toString(mCurrentUserId), mCurrentUserId);
11278        mSystemServiceManager.startUser(mCurrentUserId);
11279
11280        synchronized (this) {
11281            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11282                try {
11283                    List apps = AppGlobals.getPackageManager().
11284                        getPersistentApplications(STOCK_PM_FLAGS);
11285                    if (apps != null) {
11286                        int N = apps.size();
11287                        int i;
11288                        for (i=0; i<N; i++) {
11289                            ApplicationInfo info
11290                                = (ApplicationInfo)apps.get(i);
11291                            if (info != null &&
11292                                    !info.packageName.equals("android")) {
11293                                addAppLocked(info, false, null /* ABI override */);
11294                            }
11295                        }
11296                    }
11297                } catch (RemoteException ex) {
11298                    // pm is in same process, this will never happen.
11299                }
11300            }
11301
11302            // Start up initial activity.
11303            mBooting = true;
11304            startHomeActivityLocked(mCurrentUserId);
11305
11306            try {
11307                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11308                    Message msg = Message.obtain();
11309                    msg.what = SHOW_UID_ERROR_MSG;
11310                    mHandler.sendMessage(msg);
11311                }
11312            } catch (RemoteException e) {
11313            }
11314
11315            long ident = Binder.clearCallingIdentity();
11316            try {
11317                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11318                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11319                        | Intent.FLAG_RECEIVER_FOREGROUND);
11320                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11321                broadcastIntentLocked(null, null, intent,
11322                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11323                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11324                intent = new Intent(Intent.ACTION_USER_STARTING);
11325                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11326                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11327                broadcastIntentLocked(null, null, intent,
11328                        null, new IIntentReceiver.Stub() {
11329                            @Override
11330                            public void performReceive(Intent intent, int resultCode, String data,
11331                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11332                                    throws RemoteException {
11333                            }
11334                        }, 0, null, null,
11335                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11336                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11337            } catch (Throwable t) {
11338                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11339            } finally {
11340                Binder.restoreCallingIdentity(ident);
11341            }
11342            mStackSupervisor.resumeTopActivitiesLocked();
11343            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11344        }
11345    }
11346
11347    private boolean makeAppCrashingLocked(ProcessRecord app,
11348            String shortMsg, String longMsg, String stackTrace) {
11349        app.crashing = true;
11350        app.crashingReport = generateProcessError(app,
11351                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11352        startAppProblemLocked(app);
11353        app.stopFreezingAllLocked();
11354        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11355    }
11356
11357    private void makeAppNotRespondingLocked(ProcessRecord app,
11358            String activity, String shortMsg, String longMsg) {
11359        app.notResponding = true;
11360        app.notRespondingReport = generateProcessError(app,
11361                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11362                activity, shortMsg, longMsg, null);
11363        startAppProblemLocked(app);
11364        app.stopFreezingAllLocked();
11365    }
11366
11367    /**
11368     * Generate a process error record, suitable for attachment to a ProcessRecord.
11369     *
11370     * @param app The ProcessRecord in which the error occurred.
11371     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11372     *                      ActivityManager.AppErrorStateInfo
11373     * @param activity The activity associated with the crash, if known.
11374     * @param shortMsg Short message describing the crash.
11375     * @param longMsg Long message describing the crash.
11376     * @param stackTrace Full crash stack trace, may be null.
11377     *
11378     * @return Returns a fully-formed AppErrorStateInfo record.
11379     */
11380    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11381            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11382        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11383
11384        report.condition = condition;
11385        report.processName = app.processName;
11386        report.pid = app.pid;
11387        report.uid = app.info.uid;
11388        report.tag = activity;
11389        report.shortMsg = shortMsg;
11390        report.longMsg = longMsg;
11391        report.stackTrace = stackTrace;
11392
11393        return report;
11394    }
11395
11396    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11397        synchronized (this) {
11398            app.crashing = false;
11399            app.crashingReport = null;
11400            app.notResponding = false;
11401            app.notRespondingReport = null;
11402            if (app.anrDialog == fromDialog) {
11403                app.anrDialog = null;
11404            }
11405            if (app.waitDialog == fromDialog) {
11406                app.waitDialog = null;
11407            }
11408            if (app.pid > 0 && app.pid != MY_PID) {
11409                handleAppCrashLocked(app, null, null, null);
11410                app.kill("user request after error", true);
11411            }
11412        }
11413    }
11414
11415    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11416            String stackTrace) {
11417        long now = SystemClock.uptimeMillis();
11418
11419        Long crashTime;
11420        if (!app.isolated) {
11421            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11422        } else {
11423            crashTime = null;
11424        }
11425        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11426            // This process loses!
11427            Slog.w(TAG, "Process " + app.info.processName
11428                    + " has crashed too many times: killing!");
11429            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11430                    app.userId, app.info.processName, app.uid);
11431            mStackSupervisor.handleAppCrashLocked(app);
11432            if (!app.persistent) {
11433                // We don't want to start this process again until the user
11434                // explicitly does so...  but for persistent process, we really
11435                // need to keep it running.  If a persistent process is actually
11436                // repeatedly crashing, then badness for everyone.
11437                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11438                        app.info.processName);
11439                if (!app.isolated) {
11440                    // XXX We don't have a way to mark isolated processes
11441                    // as bad, since they don't have a peristent identity.
11442                    mBadProcesses.put(app.info.processName, app.uid,
11443                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11444                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11445                }
11446                app.bad = true;
11447                app.removed = true;
11448                // Don't let services in this process be restarted and potentially
11449                // annoy the user repeatedly.  Unless it is persistent, since those
11450                // processes run critical code.
11451                removeProcessLocked(app, false, false, "crash");
11452                mStackSupervisor.resumeTopActivitiesLocked();
11453                return false;
11454            }
11455            mStackSupervisor.resumeTopActivitiesLocked();
11456        } else {
11457            mStackSupervisor.finishTopRunningActivityLocked(app);
11458        }
11459
11460        // Bump up the crash count of any services currently running in the proc.
11461        for (int i=app.services.size()-1; i>=0; i--) {
11462            // Any services running in the application need to be placed
11463            // back in the pending list.
11464            ServiceRecord sr = app.services.valueAt(i);
11465            sr.crashCount++;
11466        }
11467
11468        // If the crashing process is what we consider to be the "home process" and it has been
11469        // replaced by a third-party app, clear the package preferred activities from packages
11470        // with a home activity running in the process to prevent a repeatedly crashing app
11471        // from blocking the user to manually clear the list.
11472        final ArrayList<ActivityRecord> activities = app.activities;
11473        if (app == mHomeProcess && activities.size() > 0
11474                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11475            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11476                final ActivityRecord r = activities.get(activityNdx);
11477                if (r.isHomeActivity()) {
11478                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11479                    try {
11480                        ActivityThread.getPackageManager()
11481                                .clearPackagePreferredActivities(r.packageName);
11482                    } catch (RemoteException c) {
11483                        // pm is in same process, this will never happen.
11484                    }
11485                }
11486            }
11487        }
11488
11489        if (!app.isolated) {
11490            // XXX Can't keep track of crash times for isolated processes,
11491            // because they don't have a perisistent identity.
11492            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11493        }
11494
11495        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11496        return true;
11497    }
11498
11499    void startAppProblemLocked(ProcessRecord app) {
11500        // If this app is not running under the current user, then we
11501        // can't give it a report button because that would require
11502        // launching the report UI under a different user.
11503        app.errorReportReceiver = null;
11504
11505        for (int userId : mCurrentProfileIds) {
11506            if (app.userId == userId) {
11507                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11508                        mContext, app.info.packageName, app.info.flags);
11509            }
11510        }
11511        skipCurrentReceiverLocked(app);
11512    }
11513
11514    void skipCurrentReceiverLocked(ProcessRecord app) {
11515        for (BroadcastQueue queue : mBroadcastQueues) {
11516            queue.skipCurrentReceiverLocked(app);
11517        }
11518    }
11519
11520    /**
11521     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11522     * The application process will exit immediately after this call returns.
11523     * @param app object of the crashing app, null for the system server
11524     * @param crashInfo describing the exception
11525     */
11526    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11527        ProcessRecord r = findAppProcess(app, "Crash");
11528        final String processName = app == null ? "system_server"
11529                : (r == null ? "unknown" : r.processName);
11530
11531        handleApplicationCrashInner("crash", r, processName, crashInfo);
11532    }
11533
11534    /* Native crash reporting uses this inner version because it needs to be somewhat
11535     * decoupled from the AM-managed cleanup lifecycle
11536     */
11537    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11538            ApplicationErrorReport.CrashInfo crashInfo) {
11539        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11540                UserHandle.getUserId(Binder.getCallingUid()), processName,
11541                r == null ? -1 : r.info.flags,
11542                crashInfo.exceptionClassName,
11543                crashInfo.exceptionMessage,
11544                crashInfo.throwFileName,
11545                crashInfo.throwLineNumber);
11546
11547        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11548
11549        crashApplication(r, crashInfo);
11550    }
11551
11552    public void handleApplicationStrictModeViolation(
11553            IBinder app,
11554            int violationMask,
11555            StrictMode.ViolationInfo info) {
11556        ProcessRecord r = findAppProcess(app, "StrictMode");
11557        if (r == null) {
11558            return;
11559        }
11560
11561        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11562            Integer stackFingerprint = info.hashCode();
11563            boolean logIt = true;
11564            synchronized (mAlreadyLoggedViolatedStacks) {
11565                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11566                    logIt = false;
11567                    // TODO: sub-sample into EventLog for these, with
11568                    // the info.durationMillis?  Then we'd get
11569                    // the relative pain numbers, without logging all
11570                    // the stack traces repeatedly.  We'd want to do
11571                    // likewise in the client code, which also does
11572                    // dup suppression, before the Binder call.
11573                } else {
11574                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11575                        mAlreadyLoggedViolatedStacks.clear();
11576                    }
11577                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11578                }
11579            }
11580            if (logIt) {
11581                logStrictModeViolationToDropBox(r, info);
11582            }
11583        }
11584
11585        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11586            AppErrorResult result = new AppErrorResult();
11587            synchronized (this) {
11588                final long origId = Binder.clearCallingIdentity();
11589
11590                Message msg = Message.obtain();
11591                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11592                HashMap<String, Object> data = new HashMap<String, Object>();
11593                data.put("result", result);
11594                data.put("app", r);
11595                data.put("violationMask", violationMask);
11596                data.put("info", info);
11597                msg.obj = data;
11598                mHandler.sendMessage(msg);
11599
11600                Binder.restoreCallingIdentity(origId);
11601            }
11602            int res = result.get();
11603            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11604        }
11605    }
11606
11607    // Depending on the policy in effect, there could be a bunch of
11608    // these in quick succession so we try to batch these together to
11609    // minimize disk writes, number of dropbox entries, and maximize
11610    // compression, by having more fewer, larger records.
11611    private void logStrictModeViolationToDropBox(
11612            ProcessRecord process,
11613            StrictMode.ViolationInfo info) {
11614        if (info == null) {
11615            return;
11616        }
11617        final boolean isSystemApp = process == null ||
11618                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11619                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11620        final String processName = process == null ? "unknown" : process.processName;
11621        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11622        final DropBoxManager dbox = (DropBoxManager)
11623                mContext.getSystemService(Context.DROPBOX_SERVICE);
11624
11625        // Exit early if the dropbox isn't configured to accept this report type.
11626        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11627
11628        boolean bufferWasEmpty;
11629        boolean needsFlush;
11630        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11631        synchronized (sb) {
11632            bufferWasEmpty = sb.length() == 0;
11633            appendDropBoxProcessHeaders(process, processName, sb);
11634            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11635            sb.append("System-App: ").append(isSystemApp).append("\n");
11636            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11637            if (info.violationNumThisLoop != 0) {
11638                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11639            }
11640            if (info.numAnimationsRunning != 0) {
11641                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11642            }
11643            if (info.broadcastIntentAction != null) {
11644                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11645            }
11646            if (info.durationMillis != -1) {
11647                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11648            }
11649            if (info.numInstances != -1) {
11650                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11651            }
11652            if (info.tags != null) {
11653                for (String tag : info.tags) {
11654                    sb.append("Span-Tag: ").append(tag).append("\n");
11655                }
11656            }
11657            sb.append("\n");
11658            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11659                sb.append(info.crashInfo.stackTrace);
11660            }
11661            sb.append("\n");
11662
11663            // Only buffer up to ~64k.  Various logging bits truncate
11664            // things at 128k.
11665            needsFlush = (sb.length() > 64 * 1024);
11666        }
11667
11668        // Flush immediately if the buffer's grown too large, or this
11669        // is a non-system app.  Non-system apps are isolated with a
11670        // different tag & policy and not batched.
11671        //
11672        // Batching is useful during internal testing with
11673        // StrictMode settings turned up high.  Without batching,
11674        // thousands of separate files could be created on boot.
11675        if (!isSystemApp || needsFlush) {
11676            new Thread("Error dump: " + dropboxTag) {
11677                @Override
11678                public void run() {
11679                    String report;
11680                    synchronized (sb) {
11681                        report = sb.toString();
11682                        sb.delete(0, sb.length());
11683                        sb.trimToSize();
11684                    }
11685                    if (report.length() != 0) {
11686                        dbox.addText(dropboxTag, report);
11687                    }
11688                }
11689            }.start();
11690            return;
11691        }
11692
11693        // System app batching:
11694        if (!bufferWasEmpty) {
11695            // An existing dropbox-writing thread is outstanding, so
11696            // we don't need to start it up.  The existing thread will
11697            // catch the buffer appends we just did.
11698            return;
11699        }
11700
11701        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11702        // (After this point, we shouldn't access AMS internal data structures.)
11703        new Thread("Error dump: " + dropboxTag) {
11704            @Override
11705            public void run() {
11706                // 5 second sleep to let stacks arrive and be batched together
11707                try {
11708                    Thread.sleep(5000);  // 5 seconds
11709                } catch (InterruptedException e) {}
11710
11711                String errorReport;
11712                synchronized (mStrictModeBuffer) {
11713                    errorReport = mStrictModeBuffer.toString();
11714                    if (errorReport.length() == 0) {
11715                        return;
11716                    }
11717                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11718                    mStrictModeBuffer.trimToSize();
11719                }
11720                dbox.addText(dropboxTag, errorReport);
11721            }
11722        }.start();
11723    }
11724
11725    /**
11726     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11727     * @param app object of the crashing app, null for the system server
11728     * @param tag reported by the caller
11729     * @param system whether this wtf is coming from the system
11730     * @param crashInfo describing the context of the error
11731     * @return true if the process should exit immediately (WTF is fatal)
11732     */
11733    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11734            final ApplicationErrorReport.CrashInfo crashInfo) {
11735        final int callingUid = Binder.getCallingUid();
11736        final int callingPid = Binder.getCallingPid();
11737
11738        if (system) {
11739            // If this is coming from the system, we could very well have low-level
11740            // system locks held, so we want to do this all asynchronously.  And we
11741            // never want this to become fatal, so there is that too.
11742            mHandler.post(new Runnable() {
11743                @Override public void run() {
11744                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11745                }
11746            });
11747            return false;
11748        }
11749
11750        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11751                crashInfo);
11752
11753        if (r != null && r.pid != Process.myPid() &&
11754                Settings.Global.getInt(mContext.getContentResolver(),
11755                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11756            crashApplication(r, crashInfo);
11757            return true;
11758        } else {
11759            return false;
11760        }
11761    }
11762
11763    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11764            final ApplicationErrorReport.CrashInfo crashInfo) {
11765        final ProcessRecord r = findAppProcess(app, "WTF");
11766        final String processName = app == null ? "system_server"
11767                : (r == null ? "unknown" : r.processName);
11768
11769        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11770                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11771
11772        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11773
11774        return r;
11775    }
11776
11777    /**
11778     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11779     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11780     */
11781    private ProcessRecord findAppProcess(IBinder app, String reason) {
11782        if (app == null) {
11783            return null;
11784        }
11785
11786        synchronized (this) {
11787            final int NP = mProcessNames.getMap().size();
11788            for (int ip=0; ip<NP; ip++) {
11789                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11790                final int NA = apps.size();
11791                for (int ia=0; ia<NA; ia++) {
11792                    ProcessRecord p = apps.valueAt(ia);
11793                    if (p.thread != null && p.thread.asBinder() == app) {
11794                        return p;
11795                    }
11796                }
11797            }
11798
11799            Slog.w(TAG, "Can't find mystery application for " + reason
11800                    + " from pid=" + Binder.getCallingPid()
11801                    + " uid=" + Binder.getCallingUid() + ": " + app);
11802            return null;
11803        }
11804    }
11805
11806    /**
11807     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11808     * to append various headers to the dropbox log text.
11809     */
11810    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11811            StringBuilder sb) {
11812        // Watchdog thread ends up invoking this function (with
11813        // a null ProcessRecord) to add the stack file to dropbox.
11814        // Do not acquire a lock on this (am) in such cases, as it
11815        // could cause a potential deadlock, if and when watchdog
11816        // is invoked due to unavailability of lock on am and it
11817        // would prevent watchdog from killing system_server.
11818        if (process == null) {
11819            sb.append("Process: ").append(processName).append("\n");
11820            return;
11821        }
11822        // Note: ProcessRecord 'process' is guarded by the service
11823        // instance.  (notably process.pkgList, which could otherwise change
11824        // concurrently during execution of this method)
11825        synchronized (this) {
11826            sb.append("Process: ").append(processName).append("\n");
11827            int flags = process.info.flags;
11828            IPackageManager pm = AppGlobals.getPackageManager();
11829            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11830            for (int ip=0; ip<process.pkgList.size(); ip++) {
11831                String pkg = process.pkgList.keyAt(ip);
11832                sb.append("Package: ").append(pkg);
11833                try {
11834                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11835                    if (pi != null) {
11836                        sb.append(" v").append(pi.versionCode);
11837                        if (pi.versionName != null) {
11838                            sb.append(" (").append(pi.versionName).append(")");
11839                        }
11840                    }
11841                } catch (RemoteException e) {
11842                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11843                }
11844                sb.append("\n");
11845            }
11846        }
11847    }
11848
11849    private static String processClass(ProcessRecord process) {
11850        if (process == null || process.pid == MY_PID) {
11851            return "system_server";
11852        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11853            return "system_app";
11854        } else {
11855            return "data_app";
11856        }
11857    }
11858
11859    /**
11860     * Write a description of an error (crash, WTF, ANR) to the drop box.
11861     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11862     * @param process which caused the error, null means the system server
11863     * @param activity which triggered the error, null if unknown
11864     * @param parent activity related to the error, null if unknown
11865     * @param subject line related to the error, null if absent
11866     * @param report in long form describing the error, null if absent
11867     * @param logFile to include in the report, null if none
11868     * @param crashInfo giving an application stack trace, null if absent
11869     */
11870    public void addErrorToDropBox(String eventType,
11871            ProcessRecord process, String processName, ActivityRecord activity,
11872            ActivityRecord parent, String subject,
11873            final String report, final File logFile,
11874            final ApplicationErrorReport.CrashInfo crashInfo) {
11875        // NOTE -- this must never acquire the ActivityManagerService lock,
11876        // otherwise the watchdog may be prevented from resetting the system.
11877
11878        final String dropboxTag = processClass(process) + "_" + eventType;
11879        final DropBoxManager dbox = (DropBoxManager)
11880                mContext.getSystemService(Context.DROPBOX_SERVICE);
11881
11882        // Exit early if the dropbox isn't configured to accept this report type.
11883        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11884
11885        final StringBuilder sb = new StringBuilder(1024);
11886        appendDropBoxProcessHeaders(process, processName, sb);
11887        if (activity != null) {
11888            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11889        }
11890        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11891            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11892        }
11893        if (parent != null && parent != activity) {
11894            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11895        }
11896        if (subject != null) {
11897            sb.append("Subject: ").append(subject).append("\n");
11898        }
11899        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11900        if (Debug.isDebuggerConnected()) {
11901            sb.append("Debugger: Connected\n");
11902        }
11903        sb.append("\n");
11904
11905        // Do the rest in a worker thread to avoid blocking the caller on I/O
11906        // (After this point, we shouldn't access AMS internal data structures.)
11907        Thread worker = new Thread("Error dump: " + dropboxTag) {
11908            @Override
11909            public void run() {
11910                if (report != null) {
11911                    sb.append(report);
11912                }
11913                if (logFile != null) {
11914                    try {
11915                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11916                                    "\n\n[[TRUNCATED]]"));
11917                    } catch (IOException e) {
11918                        Slog.e(TAG, "Error reading " + logFile, e);
11919                    }
11920                }
11921                if (crashInfo != null && crashInfo.stackTrace != null) {
11922                    sb.append(crashInfo.stackTrace);
11923                }
11924
11925                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11926                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11927                if (lines > 0) {
11928                    sb.append("\n");
11929
11930                    // Merge several logcat streams, and take the last N lines
11931                    InputStreamReader input = null;
11932                    try {
11933                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11934                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11935                                "-b", "crash",
11936                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11937
11938                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11939                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11940                        input = new InputStreamReader(logcat.getInputStream());
11941
11942                        int num;
11943                        char[] buf = new char[8192];
11944                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11945                    } catch (IOException e) {
11946                        Slog.e(TAG, "Error running logcat", e);
11947                    } finally {
11948                        if (input != null) try { input.close(); } catch (IOException e) {}
11949                    }
11950                }
11951
11952                dbox.addText(dropboxTag, sb.toString());
11953            }
11954        };
11955
11956        if (process == null) {
11957            // If process is null, we are being called from some internal code
11958            // and may be about to die -- run this synchronously.
11959            worker.run();
11960        } else {
11961            worker.start();
11962        }
11963    }
11964
11965    /**
11966     * Bring up the "unexpected error" dialog box for a crashing app.
11967     * Deal with edge cases (intercepts from instrumented applications,
11968     * ActivityController, error intent receivers, that sort of thing).
11969     * @param r the application crashing
11970     * @param crashInfo describing the failure
11971     */
11972    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11973        long timeMillis = System.currentTimeMillis();
11974        String shortMsg = crashInfo.exceptionClassName;
11975        String longMsg = crashInfo.exceptionMessage;
11976        String stackTrace = crashInfo.stackTrace;
11977        if (shortMsg != null && longMsg != null) {
11978            longMsg = shortMsg + ": " + longMsg;
11979        } else if (shortMsg != null) {
11980            longMsg = shortMsg;
11981        }
11982
11983        AppErrorResult result = new AppErrorResult();
11984        synchronized (this) {
11985            if (mController != null) {
11986                try {
11987                    String name = r != null ? r.processName : null;
11988                    int pid = r != null ? r.pid : Binder.getCallingPid();
11989                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11990                    if (!mController.appCrashed(name, pid,
11991                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11992                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11993                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11994                            Slog.w(TAG, "Skip killing native crashed app " + name
11995                                    + "(" + pid + ") during testing");
11996                        } else {
11997                            Slog.w(TAG, "Force-killing crashed app " + name
11998                                    + " at watcher's request");
11999                            if (r != null) {
12000                                r.kill("crash", true);
12001                            } else {
12002                                // Huh.
12003                                Process.killProcess(pid);
12004                                Process.killProcessGroup(uid, pid);
12005                            }
12006                        }
12007                        return;
12008                    }
12009                } catch (RemoteException e) {
12010                    mController = null;
12011                    Watchdog.getInstance().setActivityController(null);
12012                }
12013            }
12014
12015            final long origId = Binder.clearCallingIdentity();
12016
12017            // If this process is running instrumentation, finish it.
12018            if (r != null && r.instrumentationClass != null) {
12019                Slog.w(TAG, "Error in app " + r.processName
12020                      + " running instrumentation " + r.instrumentationClass + ":");
12021                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12022                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12023                Bundle info = new Bundle();
12024                info.putString("shortMsg", shortMsg);
12025                info.putString("longMsg", longMsg);
12026                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12027                Binder.restoreCallingIdentity(origId);
12028                return;
12029            }
12030
12031            // If we can't identify the process or it's already exceeded its crash quota,
12032            // quit right away without showing a crash dialog.
12033            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12034                Binder.restoreCallingIdentity(origId);
12035                return;
12036            }
12037
12038            Message msg = Message.obtain();
12039            msg.what = SHOW_ERROR_MSG;
12040            HashMap data = new HashMap();
12041            data.put("result", result);
12042            data.put("app", r);
12043            msg.obj = data;
12044            mHandler.sendMessage(msg);
12045
12046            Binder.restoreCallingIdentity(origId);
12047        }
12048
12049        int res = result.get();
12050
12051        Intent appErrorIntent = null;
12052        synchronized (this) {
12053            if (r != null && !r.isolated) {
12054                // XXX Can't keep track of crash time for isolated processes,
12055                // since they don't have a persistent identity.
12056                mProcessCrashTimes.put(r.info.processName, r.uid,
12057                        SystemClock.uptimeMillis());
12058            }
12059            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12060                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12061            }
12062        }
12063
12064        if (appErrorIntent != null) {
12065            try {
12066                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12067            } catch (ActivityNotFoundException e) {
12068                Slog.w(TAG, "bug report receiver dissappeared", e);
12069            }
12070        }
12071    }
12072
12073    Intent createAppErrorIntentLocked(ProcessRecord r,
12074            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12075        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12076        if (report == null) {
12077            return null;
12078        }
12079        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12080        result.setComponent(r.errorReportReceiver);
12081        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12082        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12083        return result;
12084    }
12085
12086    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12087            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12088        if (r.errorReportReceiver == null) {
12089            return null;
12090        }
12091
12092        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12093            return null;
12094        }
12095
12096        ApplicationErrorReport report = new ApplicationErrorReport();
12097        report.packageName = r.info.packageName;
12098        report.installerPackageName = r.errorReportReceiver.getPackageName();
12099        report.processName = r.processName;
12100        report.time = timeMillis;
12101        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12102
12103        if (r.crashing || r.forceCrashReport) {
12104            report.type = ApplicationErrorReport.TYPE_CRASH;
12105            report.crashInfo = crashInfo;
12106        } else if (r.notResponding) {
12107            report.type = ApplicationErrorReport.TYPE_ANR;
12108            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12109
12110            report.anrInfo.activity = r.notRespondingReport.tag;
12111            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12112            report.anrInfo.info = r.notRespondingReport.longMsg;
12113        }
12114
12115        return report;
12116    }
12117
12118    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12119        enforceNotIsolatedCaller("getProcessesInErrorState");
12120        // assume our apps are happy - lazy create the list
12121        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12122
12123        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12124                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12125        int userId = UserHandle.getUserId(Binder.getCallingUid());
12126
12127        synchronized (this) {
12128
12129            // iterate across all processes
12130            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12131                ProcessRecord app = mLruProcesses.get(i);
12132                if (!allUsers && app.userId != userId) {
12133                    continue;
12134                }
12135                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12136                    // This one's in trouble, so we'll generate a report for it
12137                    // crashes are higher priority (in case there's a crash *and* an anr)
12138                    ActivityManager.ProcessErrorStateInfo report = null;
12139                    if (app.crashing) {
12140                        report = app.crashingReport;
12141                    } else if (app.notResponding) {
12142                        report = app.notRespondingReport;
12143                    }
12144
12145                    if (report != null) {
12146                        if (errList == null) {
12147                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12148                        }
12149                        errList.add(report);
12150                    } else {
12151                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12152                                " crashing = " + app.crashing +
12153                                " notResponding = " + app.notResponding);
12154                    }
12155                }
12156            }
12157        }
12158
12159        return errList;
12160    }
12161
12162    static int procStateToImportance(int procState, int memAdj,
12163            ActivityManager.RunningAppProcessInfo currApp) {
12164        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12165        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12166            currApp.lru = memAdj;
12167        } else {
12168            currApp.lru = 0;
12169        }
12170        return imp;
12171    }
12172
12173    private void fillInProcMemInfo(ProcessRecord app,
12174            ActivityManager.RunningAppProcessInfo outInfo) {
12175        outInfo.pid = app.pid;
12176        outInfo.uid = app.info.uid;
12177        if (mHeavyWeightProcess == app) {
12178            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12179        }
12180        if (app.persistent) {
12181            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12182        }
12183        if (app.activities.size() > 0) {
12184            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12185        }
12186        outInfo.lastTrimLevel = app.trimMemoryLevel;
12187        int adj = app.curAdj;
12188        int procState = app.curProcState;
12189        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12190        outInfo.importanceReasonCode = app.adjTypeCode;
12191        outInfo.processState = app.curProcState;
12192    }
12193
12194    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12195        enforceNotIsolatedCaller("getRunningAppProcesses");
12196        // Lazy instantiation of list
12197        List<ActivityManager.RunningAppProcessInfo> runList = null;
12198        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12199                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12200        int userId = UserHandle.getUserId(Binder.getCallingUid());
12201        synchronized (this) {
12202            // Iterate across all processes
12203            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12204                ProcessRecord app = mLruProcesses.get(i);
12205                if (!allUsers && app.userId != userId) {
12206                    continue;
12207                }
12208                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12209                    // Generate process state info for running application
12210                    ActivityManager.RunningAppProcessInfo currApp =
12211                        new ActivityManager.RunningAppProcessInfo(app.processName,
12212                                app.pid, app.getPackageList());
12213                    fillInProcMemInfo(app, currApp);
12214                    if (app.adjSource instanceof ProcessRecord) {
12215                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12216                        currApp.importanceReasonImportance =
12217                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12218                                        app.adjSourceProcState);
12219                    } else if (app.adjSource instanceof ActivityRecord) {
12220                        ActivityRecord r = (ActivityRecord)app.adjSource;
12221                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12222                    }
12223                    if (app.adjTarget instanceof ComponentName) {
12224                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12225                    }
12226                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12227                    //        + " lru=" + currApp.lru);
12228                    if (runList == null) {
12229                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12230                    }
12231                    runList.add(currApp);
12232                }
12233            }
12234        }
12235        return runList;
12236    }
12237
12238    public List<ApplicationInfo> getRunningExternalApplications() {
12239        enforceNotIsolatedCaller("getRunningExternalApplications");
12240        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12241        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12242        if (runningApps != null && runningApps.size() > 0) {
12243            Set<String> extList = new HashSet<String>();
12244            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12245                if (app.pkgList != null) {
12246                    for (String pkg : app.pkgList) {
12247                        extList.add(pkg);
12248                    }
12249                }
12250            }
12251            IPackageManager pm = AppGlobals.getPackageManager();
12252            for (String pkg : extList) {
12253                try {
12254                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12255                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12256                        retList.add(info);
12257                    }
12258                } catch (RemoteException e) {
12259                }
12260            }
12261        }
12262        return retList;
12263    }
12264
12265    @Override
12266    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12267        enforceNotIsolatedCaller("getMyMemoryState");
12268        synchronized (this) {
12269            ProcessRecord proc;
12270            synchronized (mPidsSelfLocked) {
12271                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12272            }
12273            fillInProcMemInfo(proc, outInfo);
12274        }
12275    }
12276
12277    @Override
12278    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12279        if (checkCallingPermission(android.Manifest.permission.DUMP)
12280                != PackageManager.PERMISSION_GRANTED) {
12281            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12282                    + Binder.getCallingPid()
12283                    + ", uid=" + Binder.getCallingUid()
12284                    + " without permission "
12285                    + android.Manifest.permission.DUMP);
12286            return;
12287        }
12288
12289        boolean dumpAll = false;
12290        boolean dumpClient = false;
12291        String dumpPackage = null;
12292
12293        int opti = 0;
12294        while (opti < args.length) {
12295            String opt = args[opti];
12296            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12297                break;
12298            }
12299            opti++;
12300            if ("-a".equals(opt)) {
12301                dumpAll = true;
12302            } else if ("-c".equals(opt)) {
12303                dumpClient = true;
12304            } else if ("-h".equals(opt)) {
12305                pw.println("Activity manager dump options:");
12306                pw.println("  [-a] [-c] [-h] [cmd] ...");
12307                pw.println("  cmd may be one of:");
12308                pw.println("    a[ctivities]: activity stack state");
12309                pw.println("    r[recents]: recent activities state");
12310                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12311                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12312                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12313                pw.println("    o[om]: out of memory management");
12314                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12315                pw.println("    provider [COMP_SPEC]: provider client-side state");
12316                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12317                pw.println("    service [COMP_SPEC]: service client-side state");
12318                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12319                pw.println("    all: dump all activities");
12320                pw.println("    top: dump the top activity");
12321                pw.println("    write: write all pending state to storage");
12322                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12323                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12324                pw.println("    a partial substring in a component name, a");
12325                pw.println("    hex object identifier.");
12326                pw.println("  -a: include all available server state.");
12327                pw.println("  -c: include client state.");
12328                return;
12329            } else {
12330                pw.println("Unknown argument: " + opt + "; use -h for help");
12331            }
12332        }
12333
12334        long origId = Binder.clearCallingIdentity();
12335        boolean more = false;
12336        // Is the caller requesting to dump a particular piece of data?
12337        if (opti < args.length) {
12338            String cmd = args[opti];
12339            opti++;
12340            if ("activities".equals(cmd) || "a".equals(cmd)) {
12341                synchronized (this) {
12342                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12343                }
12344            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12345                synchronized (this) {
12346                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12347                }
12348            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12349                String[] newArgs;
12350                String name;
12351                if (opti >= args.length) {
12352                    name = null;
12353                    newArgs = EMPTY_STRING_ARRAY;
12354                } else {
12355                    name = args[opti];
12356                    opti++;
12357                    newArgs = new String[args.length - opti];
12358                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12359                            args.length - opti);
12360                }
12361                synchronized (this) {
12362                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12363                }
12364            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12365                String[] newArgs;
12366                String name;
12367                if (opti >= args.length) {
12368                    name = null;
12369                    newArgs = EMPTY_STRING_ARRAY;
12370                } else {
12371                    name = args[opti];
12372                    opti++;
12373                    newArgs = new String[args.length - opti];
12374                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12375                            args.length - opti);
12376                }
12377                synchronized (this) {
12378                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12379                }
12380            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12381                String[] newArgs;
12382                String name;
12383                if (opti >= args.length) {
12384                    name = null;
12385                    newArgs = EMPTY_STRING_ARRAY;
12386                } else {
12387                    name = args[opti];
12388                    opti++;
12389                    newArgs = new String[args.length - opti];
12390                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12391                            args.length - opti);
12392                }
12393                synchronized (this) {
12394                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12395                }
12396            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12397                synchronized (this) {
12398                    dumpOomLocked(fd, pw, args, opti, true);
12399                }
12400            } else if ("provider".equals(cmd)) {
12401                String[] newArgs;
12402                String name;
12403                if (opti >= args.length) {
12404                    name = null;
12405                    newArgs = EMPTY_STRING_ARRAY;
12406                } else {
12407                    name = args[opti];
12408                    opti++;
12409                    newArgs = new String[args.length - opti];
12410                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12411                }
12412                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12413                    pw.println("No providers match: " + name);
12414                    pw.println("Use -h for help.");
12415                }
12416            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12417                synchronized (this) {
12418                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12419                }
12420            } else if ("service".equals(cmd)) {
12421                String[] newArgs;
12422                String name;
12423                if (opti >= args.length) {
12424                    name = null;
12425                    newArgs = EMPTY_STRING_ARRAY;
12426                } else {
12427                    name = args[opti];
12428                    opti++;
12429                    newArgs = new String[args.length - opti];
12430                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12431                            args.length - opti);
12432                }
12433                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12434                    pw.println("No services match: " + name);
12435                    pw.println("Use -h for help.");
12436                }
12437            } else if ("package".equals(cmd)) {
12438                String[] newArgs;
12439                if (opti >= args.length) {
12440                    pw.println("package: no package name specified");
12441                    pw.println("Use -h for help.");
12442                } else {
12443                    dumpPackage = args[opti];
12444                    opti++;
12445                    newArgs = new String[args.length - opti];
12446                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12447                            args.length - opti);
12448                    args = newArgs;
12449                    opti = 0;
12450                    more = true;
12451                }
12452            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12453                synchronized (this) {
12454                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12455                }
12456            } else if ("write".equals(cmd)) {
12457                mTaskPersister.flush();
12458                pw.println("All tasks persisted.");
12459                return;
12460            } else {
12461                // Dumping a single activity?
12462                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12463                    pw.println("Bad activity command, or no activities match: " + cmd);
12464                    pw.println("Use -h for help.");
12465                }
12466            }
12467            if (!more) {
12468                Binder.restoreCallingIdentity(origId);
12469                return;
12470            }
12471        }
12472
12473        // No piece of data specified, dump everything.
12474        synchronized (this) {
12475            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12476            pw.println();
12477            if (dumpAll) {
12478                pw.println("-------------------------------------------------------------------------------");
12479            }
12480            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12481            pw.println();
12482            if (dumpAll) {
12483                pw.println("-------------------------------------------------------------------------------");
12484            }
12485            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12486            pw.println();
12487            if (dumpAll) {
12488                pw.println("-------------------------------------------------------------------------------");
12489            }
12490            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12491            pw.println();
12492            if (dumpAll) {
12493                pw.println("-------------------------------------------------------------------------------");
12494            }
12495            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12496            pw.println();
12497            if (dumpAll) {
12498                pw.println("-------------------------------------------------------------------------------");
12499            }
12500            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12501            pw.println();
12502            if (dumpAll) {
12503                pw.println("-------------------------------------------------------------------------------");
12504            }
12505            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12506        }
12507        Binder.restoreCallingIdentity(origId);
12508    }
12509
12510    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12511            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12512        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12513
12514        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12515                dumpPackage);
12516        boolean needSep = printedAnything;
12517
12518        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12519                dumpPackage, needSep, "  mFocusedActivity: ");
12520        if (printed) {
12521            printedAnything = true;
12522            needSep = false;
12523        }
12524
12525        if (dumpPackage == null) {
12526            if (needSep) {
12527                pw.println();
12528            }
12529            needSep = true;
12530            printedAnything = true;
12531            mStackSupervisor.dump(pw, "  ");
12532        }
12533
12534        if (!printedAnything) {
12535            pw.println("  (nothing)");
12536        }
12537    }
12538
12539    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12540            int opti, boolean dumpAll, String dumpPackage) {
12541        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
12542
12543        boolean printedAnything = false;
12544
12545        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12546            boolean printedHeader = false;
12547
12548            final int N = mRecentTasks.size();
12549            for (int i=0; i<N; i++) {
12550                TaskRecord tr = mRecentTasks.get(i);
12551                if (dumpPackage != null) {
12552                    if (tr.realActivity == null ||
12553                            !dumpPackage.equals(tr.realActivity)) {
12554                        continue;
12555                    }
12556                }
12557                if (!printedHeader) {
12558                    pw.println("  Recent tasks:");
12559                    printedHeader = true;
12560                    printedAnything = true;
12561                }
12562                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12563                        pw.println(tr);
12564                if (dumpAll) {
12565                    mRecentTasks.get(i).dump(pw, "    ");
12566                }
12567            }
12568        }
12569
12570        if (!printedAnything) {
12571            pw.println("  (nothing)");
12572        }
12573    }
12574
12575    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12576            int opti, boolean dumpAll, String dumpPackage) {
12577        boolean needSep = false;
12578        boolean printedAnything = false;
12579        int numPers = 0;
12580
12581        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12582
12583        if (dumpAll) {
12584            final int NP = mProcessNames.getMap().size();
12585            for (int ip=0; ip<NP; ip++) {
12586                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12587                final int NA = procs.size();
12588                for (int ia=0; ia<NA; ia++) {
12589                    ProcessRecord r = procs.valueAt(ia);
12590                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12591                        continue;
12592                    }
12593                    if (!needSep) {
12594                        pw.println("  All known processes:");
12595                        needSep = true;
12596                        printedAnything = true;
12597                    }
12598                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12599                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12600                        pw.print(" "); pw.println(r);
12601                    r.dump(pw, "    ");
12602                    if (r.persistent) {
12603                        numPers++;
12604                    }
12605                }
12606            }
12607        }
12608
12609        if (mIsolatedProcesses.size() > 0) {
12610            boolean printed = false;
12611            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12612                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12613                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12614                    continue;
12615                }
12616                if (!printed) {
12617                    if (needSep) {
12618                        pw.println();
12619                    }
12620                    pw.println("  Isolated process list (sorted by uid):");
12621                    printedAnything = true;
12622                    printed = true;
12623                    needSep = true;
12624                }
12625                pw.println(String.format("%sIsolated #%2d: %s",
12626                        "    ", i, r.toString()));
12627            }
12628        }
12629
12630        if (mLruProcesses.size() > 0) {
12631            if (needSep) {
12632                pw.println();
12633            }
12634            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12635                    pw.print(" total, non-act at ");
12636                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12637                    pw.print(", non-svc at ");
12638                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12639                    pw.println("):");
12640            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12641            needSep = true;
12642            printedAnything = true;
12643        }
12644
12645        if (dumpAll || dumpPackage != null) {
12646            synchronized (mPidsSelfLocked) {
12647                boolean printed = false;
12648                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12649                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12650                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12651                        continue;
12652                    }
12653                    if (!printed) {
12654                        if (needSep) pw.println();
12655                        needSep = true;
12656                        pw.println("  PID mappings:");
12657                        printed = true;
12658                        printedAnything = true;
12659                    }
12660                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12661                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12662                }
12663            }
12664        }
12665
12666        if (mForegroundProcesses.size() > 0) {
12667            synchronized (mPidsSelfLocked) {
12668                boolean printed = false;
12669                for (int i=0; i<mForegroundProcesses.size(); i++) {
12670                    ProcessRecord r = mPidsSelfLocked.get(
12671                            mForegroundProcesses.valueAt(i).pid);
12672                    if (dumpPackage != null && (r == null
12673                            || !r.pkgList.containsKey(dumpPackage))) {
12674                        continue;
12675                    }
12676                    if (!printed) {
12677                        if (needSep) pw.println();
12678                        needSep = true;
12679                        pw.println("  Foreground Processes:");
12680                        printed = true;
12681                        printedAnything = true;
12682                    }
12683                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12684                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12685                }
12686            }
12687        }
12688
12689        if (mPersistentStartingProcesses.size() > 0) {
12690            if (needSep) pw.println();
12691            needSep = true;
12692            printedAnything = true;
12693            pw.println("  Persisent processes that are starting:");
12694            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12695                    "Starting Norm", "Restarting PERS", dumpPackage);
12696        }
12697
12698        if (mRemovedProcesses.size() > 0) {
12699            if (needSep) pw.println();
12700            needSep = true;
12701            printedAnything = true;
12702            pw.println("  Processes that are being removed:");
12703            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12704                    "Removed Norm", "Removed PERS", dumpPackage);
12705        }
12706
12707        if (mProcessesOnHold.size() > 0) {
12708            if (needSep) pw.println();
12709            needSep = true;
12710            printedAnything = true;
12711            pw.println("  Processes that are on old until the system is ready:");
12712            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12713                    "OnHold Norm", "OnHold PERS", dumpPackage);
12714        }
12715
12716        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12717
12718        if (mProcessCrashTimes.getMap().size() > 0) {
12719            boolean printed = false;
12720            long now = SystemClock.uptimeMillis();
12721            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12722            final int NP = pmap.size();
12723            for (int ip=0; ip<NP; ip++) {
12724                String pname = pmap.keyAt(ip);
12725                SparseArray<Long> uids = pmap.valueAt(ip);
12726                final int N = uids.size();
12727                for (int i=0; i<N; i++) {
12728                    int puid = uids.keyAt(i);
12729                    ProcessRecord r = mProcessNames.get(pname, puid);
12730                    if (dumpPackage != null && (r == null
12731                            || !r.pkgList.containsKey(dumpPackage))) {
12732                        continue;
12733                    }
12734                    if (!printed) {
12735                        if (needSep) pw.println();
12736                        needSep = true;
12737                        pw.println("  Time since processes crashed:");
12738                        printed = true;
12739                        printedAnything = true;
12740                    }
12741                    pw.print("    Process "); pw.print(pname);
12742                            pw.print(" uid "); pw.print(puid);
12743                            pw.print(": last crashed ");
12744                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12745                            pw.println(" ago");
12746                }
12747            }
12748        }
12749
12750        if (mBadProcesses.getMap().size() > 0) {
12751            boolean printed = false;
12752            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12753            final int NP = pmap.size();
12754            for (int ip=0; ip<NP; ip++) {
12755                String pname = pmap.keyAt(ip);
12756                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12757                final int N = uids.size();
12758                for (int i=0; i<N; i++) {
12759                    int puid = uids.keyAt(i);
12760                    ProcessRecord r = mProcessNames.get(pname, puid);
12761                    if (dumpPackage != null && (r == null
12762                            || !r.pkgList.containsKey(dumpPackage))) {
12763                        continue;
12764                    }
12765                    if (!printed) {
12766                        if (needSep) pw.println();
12767                        needSep = true;
12768                        pw.println("  Bad processes:");
12769                        printedAnything = true;
12770                    }
12771                    BadProcessInfo info = uids.valueAt(i);
12772                    pw.print("    Bad process "); pw.print(pname);
12773                            pw.print(" uid "); pw.print(puid);
12774                            pw.print(": crashed at time "); pw.println(info.time);
12775                    if (info.shortMsg != null) {
12776                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12777                    }
12778                    if (info.longMsg != null) {
12779                        pw.print("      Long msg: "); pw.println(info.longMsg);
12780                    }
12781                    if (info.stack != null) {
12782                        pw.println("      Stack:");
12783                        int lastPos = 0;
12784                        for (int pos=0; pos<info.stack.length(); pos++) {
12785                            if (info.stack.charAt(pos) == '\n') {
12786                                pw.print("        ");
12787                                pw.write(info.stack, lastPos, pos-lastPos);
12788                                pw.println();
12789                                lastPos = pos+1;
12790                            }
12791                        }
12792                        if (lastPos < info.stack.length()) {
12793                            pw.print("        ");
12794                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12795                            pw.println();
12796                        }
12797                    }
12798                }
12799            }
12800        }
12801
12802        if (dumpPackage == null) {
12803            pw.println();
12804            needSep = false;
12805            pw.println("  mStartedUsers:");
12806            for (int i=0; i<mStartedUsers.size(); i++) {
12807                UserStartedState uss = mStartedUsers.valueAt(i);
12808                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12809                        pw.print(": "); uss.dump("", pw);
12810            }
12811            pw.print("  mStartedUserArray: [");
12812            for (int i=0; i<mStartedUserArray.length; i++) {
12813                if (i > 0) pw.print(", ");
12814                pw.print(mStartedUserArray[i]);
12815            }
12816            pw.println("]");
12817            pw.print("  mUserLru: [");
12818            for (int i=0; i<mUserLru.size(); i++) {
12819                if (i > 0) pw.print(", ");
12820                pw.print(mUserLru.get(i));
12821            }
12822            pw.println("]");
12823            if (dumpAll) {
12824                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12825            }
12826            synchronized (mUserProfileGroupIdsSelfLocked) {
12827                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12828                    pw.println("  mUserProfileGroupIds:");
12829                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12830                        pw.print("    User #");
12831                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12832                        pw.print(" -> profile #");
12833                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12834                    }
12835                }
12836            }
12837        }
12838        if (mHomeProcess != null && (dumpPackage == null
12839                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12840            if (needSep) {
12841                pw.println();
12842                needSep = false;
12843            }
12844            pw.println("  mHomeProcess: " + mHomeProcess);
12845        }
12846        if (mPreviousProcess != null && (dumpPackage == null
12847                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12848            if (needSep) {
12849                pw.println();
12850                needSep = false;
12851            }
12852            pw.println("  mPreviousProcess: " + mPreviousProcess);
12853        }
12854        if (dumpAll) {
12855            StringBuilder sb = new StringBuilder(128);
12856            sb.append("  mPreviousProcessVisibleTime: ");
12857            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12858            pw.println(sb);
12859        }
12860        if (mHeavyWeightProcess != null && (dumpPackage == null
12861                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12862            if (needSep) {
12863                pw.println();
12864                needSep = false;
12865            }
12866            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12867        }
12868        if (dumpPackage == null) {
12869            pw.println("  mConfiguration: " + mConfiguration);
12870        }
12871        if (dumpAll) {
12872            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12873            if (mCompatModePackages.getPackages().size() > 0) {
12874                boolean printed = false;
12875                for (Map.Entry<String, Integer> entry
12876                        : mCompatModePackages.getPackages().entrySet()) {
12877                    String pkg = entry.getKey();
12878                    int mode = entry.getValue();
12879                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12880                        continue;
12881                    }
12882                    if (!printed) {
12883                        pw.println("  mScreenCompatPackages:");
12884                        printed = true;
12885                    }
12886                    pw.print("    "); pw.print(pkg); pw.print(": ");
12887                            pw.print(mode); pw.println();
12888                }
12889            }
12890        }
12891        if (dumpPackage == null) {
12892            if (mSleeping || mWentToSleep || mLockScreenShown) {
12893                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12894                        + " mLockScreenShown " + mLockScreenShown);
12895            }
12896            if (mShuttingDown || mRunningVoice) {
12897                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12898            }
12899        }
12900        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12901                || mOrigWaitForDebugger) {
12902            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12903                    || dumpPackage.equals(mOrigDebugApp)) {
12904                if (needSep) {
12905                    pw.println();
12906                    needSep = false;
12907                }
12908                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12909                        + " mDebugTransient=" + mDebugTransient
12910                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12911            }
12912        }
12913        if (mOpenGlTraceApp != null) {
12914            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12915                if (needSep) {
12916                    pw.println();
12917                    needSep = false;
12918                }
12919                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12920            }
12921        }
12922        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12923                || mProfileFd != null) {
12924            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12925                if (needSep) {
12926                    pw.println();
12927                    needSep = false;
12928                }
12929                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12930                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12931                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12932                        + mAutoStopProfiler);
12933                pw.println("  mProfileType=" + mProfileType);
12934            }
12935        }
12936        if (dumpPackage == null) {
12937            if (mAlwaysFinishActivities || mController != null) {
12938                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12939                        + " mController=" + mController);
12940            }
12941            if (dumpAll) {
12942                pw.println("  Total persistent processes: " + numPers);
12943                pw.println("  mProcessesReady=" + mProcessesReady
12944                        + " mSystemReady=" + mSystemReady
12945                        + " mBooted=" + mBooted
12946                        + " mFactoryTest=" + mFactoryTest);
12947                pw.println("  mBooting=" + mBooting
12948                        + " mCallFinishBooting=" + mCallFinishBooting
12949                        + " mBootAnimationComplete=" + mBootAnimationComplete);
12950                pw.print("  mLastPowerCheckRealtime=");
12951                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12952                        pw.println("");
12953                pw.print("  mLastPowerCheckUptime=");
12954                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12955                        pw.println("");
12956                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12957                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12958                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12959                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12960                        + " (" + mLruProcesses.size() + " total)"
12961                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12962                        + " mNumServiceProcs=" + mNumServiceProcs
12963                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12964                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12965                        + " mLastMemoryLevel" + mLastMemoryLevel
12966                        + " mLastNumProcesses" + mLastNumProcesses);
12967                long now = SystemClock.uptimeMillis();
12968                pw.print("  mLastIdleTime=");
12969                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12970                        pw.print(" mLowRamSinceLastIdle=");
12971                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12972                        pw.println();
12973            }
12974        }
12975
12976        if (!printedAnything) {
12977            pw.println("  (nothing)");
12978        }
12979    }
12980
12981    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12982            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12983        if (mProcessesToGc.size() > 0) {
12984            boolean printed = false;
12985            long now = SystemClock.uptimeMillis();
12986            for (int i=0; i<mProcessesToGc.size(); i++) {
12987                ProcessRecord proc = mProcessesToGc.get(i);
12988                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12989                    continue;
12990                }
12991                if (!printed) {
12992                    if (needSep) pw.println();
12993                    needSep = true;
12994                    pw.println("  Processes that are waiting to GC:");
12995                    printed = true;
12996                }
12997                pw.print("    Process "); pw.println(proc);
12998                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12999                        pw.print(", last gced=");
13000                        pw.print(now-proc.lastRequestedGc);
13001                        pw.print(" ms ago, last lowMem=");
13002                        pw.print(now-proc.lastLowMemory);
13003                        pw.println(" ms ago");
13004
13005            }
13006        }
13007        return needSep;
13008    }
13009
13010    void printOomLevel(PrintWriter pw, String name, int adj) {
13011        pw.print("    ");
13012        if (adj >= 0) {
13013            pw.print(' ');
13014            if (adj < 10) pw.print(' ');
13015        } else {
13016            if (adj > -10) pw.print(' ');
13017        }
13018        pw.print(adj);
13019        pw.print(": ");
13020        pw.print(name);
13021        pw.print(" (");
13022        pw.print(mProcessList.getMemLevel(adj)/1024);
13023        pw.println(" kB)");
13024    }
13025
13026    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13027            int opti, boolean dumpAll) {
13028        boolean needSep = false;
13029
13030        if (mLruProcesses.size() > 0) {
13031            if (needSep) pw.println();
13032            needSep = true;
13033            pw.println("  OOM levels:");
13034            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13035            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13036            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13037            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13038            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13039            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13040            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13041            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13042            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13043            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13044            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13045            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13046            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13047
13048            if (needSep) pw.println();
13049            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13050                    pw.print(" total, non-act at ");
13051                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13052                    pw.print(", non-svc at ");
13053                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13054                    pw.println("):");
13055            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13056            needSep = true;
13057        }
13058
13059        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13060
13061        pw.println();
13062        pw.println("  mHomeProcess: " + mHomeProcess);
13063        pw.println("  mPreviousProcess: " + mPreviousProcess);
13064        if (mHeavyWeightProcess != null) {
13065            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13066        }
13067
13068        return true;
13069    }
13070
13071    /**
13072     * There are three ways to call this:
13073     *  - no provider specified: dump all the providers
13074     *  - a flattened component name that matched an existing provider was specified as the
13075     *    first arg: dump that one provider
13076     *  - the first arg isn't the flattened component name of an existing provider:
13077     *    dump all providers whose component contains the first arg as a substring
13078     */
13079    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13080            int opti, boolean dumpAll) {
13081        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13082    }
13083
13084    static class ItemMatcher {
13085        ArrayList<ComponentName> components;
13086        ArrayList<String> strings;
13087        ArrayList<Integer> objects;
13088        boolean all;
13089
13090        ItemMatcher() {
13091            all = true;
13092        }
13093
13094        void build(String name) {
13095            ComponentName componentName = ComponentName.unflattenFromString(name);
13096            if (componentName != null) {
13097                if (components == null) {
13098                    components = new ArrayList<ComponentName>();
13099                }
13100                components.add(componentName);
13101                all = false;
13102            } else {
13103                int objectId = 0;
13104                // Not a '/' separated full component name; maybe an object ID?
13105                try {
13106                    objectId = Integer.parseInt(name, 16);
13107                    if (objects == null) {
13108                        objects = new ArrayList<Integer>();
13109                    }
13110                    objects.add(objectId);
13111                    all = false;
13112                } catch (RuntimeException e) {
13113                    // Not an integer; just do string match.
13114                    if (strings == null) {
13115                        strings = new ArrayList<String>();
13116                    }
13117                    strings.add(name);
13118                    all = false;
13119                }
13120            }
13121        }
13122
13123        int build(String[] args, int opti) {
13124            for (; opti<args.length; opti++) {
13125                String name = args[opti];
13126                if ("--".equals(name)) {
13127                    return opti+1;
13128                }
13129                build(name);
13130            }
13131            return opti;
13132        }
13133
13134        boolean match(Object object, ComponentName comp) {
13135            if (all) {
13136                return true;
13137            }
13138            if (components != null) {
13139                for (int i=0; i<components.size(); i++) {
13140                    if (components.get(i).equals(comp)) {
13141                        return true;
13142                    }
13143                }
13144            }
13145            if (objects != null) {
13146                for (int i=0; i<objects.size(); i++) {
13147                    if (System.identityHashCode(object) == objects.get(i)) {
13148                        return true;
13149                    }
13150                }
13151            }
13152            if (strings != null) {
13153                String flat = comp.flattenToString();
13154                for (int i=0; i<strings.size(); i++) {
13155                    if (flat.contains(strings.get(i))) {
13156                        return true;
13157                    }
13158                }
13159            }
13160            return false;
13161        }
13162    }
13163
13164    /**
13165     * There are three things that cmd can be:
13166     *  - a flattened component name that matches an existing activity
13167     *  - the cmd arg isn't the flattened component name of an existing activity:
13168     *    dump all activity whose component contains the cmd as a substring
13169     *  - A hex number of the ActivityRecord object instance.
13170     */
13171    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13172            int opti, boolean dumpAll) {
13173        ArrayList<ActivityRecord> activities;
13174
13175        synchronized (this) {
13176            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13177        }
13178
13179        if (activities.size() <= 0) {
13180            return false;
13181        }
13182
13183        String[] newArgs = new String[args.length - opti];
13184        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13185
13186        TaskRecord lastTask = null;
13187        boolean needSep = false;
13188        for (int i=activities.size()-1; i>=0; i--) {
13189            ActivityRecord r = activities.get(i);
13190            if (needSep) {
13191                pw.println();
13192            }
13193            needSep = true;
13194            synchronized (this) {
13195                if (lastTask != r.task) {
13196                    lastTask = r.task;
13197                    pw.print("TASK "); pw.print(lastTask.affinity);
13198                            pw.print(" id="); pw.println(lastTask.taskId);
13199                    if (dumpAll) {
13200                        lastTask.dump(pw, "  ");
13201                    }
13202                }
13203            }
13204            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13205        }
13206        return true;
13207    }
13208
13209    /**
13210     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13211     * there is a thread associated with the activity.
13212     */
13213    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13214            final ActivityRecord r, String[] args, boolean dumpAll) {
13215        String innerPrefix = prefix + "  ";
13216        synchronized (this) {
13217            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13218                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13219                    pw.print(" pid=");
13220                    if (r.app != null) pw.println(r.app.pid);
13221                    else pw.println("(not running)");
13222            if (dumpAll) {
13223                r.dump(pw, innerPrefix);
13224            }
13225        }
13226        if (r.app != null && r.app.thread != null) {
13227            // flush anything that is already in the PrintWriter since the thread is going
13228            // to write to the file descriptor directly
13229            pw.flush();
13230            try {
13231                TransferPipe tp = new TransferPipe();
13232                try {
13233                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13234                            r.appToken, innerPrefix, args);
13235                    tp.go(fd);
13236                } finally {
13237                    tp.kill();
13238                }
13239            } catch (IOException e) {
13240                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13241            } catch (RemoteException e) {
13242                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13243            }
13244        }
13245    }
13246
13247    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13248            int opti, boolean dumpAll, String dumpPackage) {
13249        boolean needSep = false;
13250        boolean onlyHistory = false;
13251        boolean printedAnything = false;
13252
13253        if ("history".equals(dumpPackage)) {
13254            if (opti < args.length && "-s".equals(args[opti])) {
13255                dumpAll = false;
13256            }
13257            onlyHistory = true;
13258            dumpPackage = null;
13259        }
13260
13261        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13262        if (!onlyHistory && dumpAll) {
13263            if (mRegisteredReceivers.size() > 0) {
13264                boolean printed = false;
13265                Iterator it = mRegisteredReceivers.values().iterator();
13266                while (it.hasNext()) {
13267                    ReceiverList r = (ReceiverList)it.next();
13268                    if (dumpPackage != null && (r.app == null ||
13269                            !dumpPackage.equals(r.app.info.packageName))) {
13270                        continue;
13271                    }
13272                    if (!printed) {
13273                        pw.println("  Registered Receivers:");
13274                        needSep = true;
13275                        printed = true;
13276                        printedAnything = true;
13277                    }
13278                    pw.print("  * "); pw.println(r);
13279                    r.dump(pw, "    ");
13280                }
13281            }
13282
13283            if (mReceiverResolver.dump(pw, needSep ?
13284                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13285                    "    ", dumpPackage, false)) {
13286                needSep = true;
13287                printedAnything = true;
13288            }
13289        }
13290
13291        for (BroadcastQueue q : mBroadcastQueues) {
13292            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13293            printedAnything |= needSep;
13294        }
13295
13296        needSep = true;
13297
13298        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13299            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13300                if (needSep) {
13301                    pw.println();
13302                }
13303                needSep = true;
13304                printedAnything = true;
13305                pw.print("  Sticky broadcasts for user ");
13306                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13307                StringBuilder sb = new StringBuilder(128);
13308                for (Map.Entry<String, ArrayList<Intent>> ent
13309                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13310                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13311                    if (dumpAll) {
13312                        pw.println(":");
13313                        ArrayList<Intent> intents = ent.getValue();
13314                        final int N = intents.size();
13315                        for (int i=0; i<N; i++) {
13316                            sb.setLength(0);
13317                            sb.append("    Intent: ");
13318                            intents.get(i).toShortString(sb, false, true, false, false);
13319                            pw.println(sb.toString());
13320                            Bundle bundle = intents.get(i).getExtras();
13321                            if (bundle != null) {
13322                                pw.print("      ");
13323                                pw.println(bundle.toString());
13324                            }
13325                        }
13326                    } else {
13327                        pw.println("");
13328                    }
13329                }
13330            }
13331        }
13332
13333        if (!onlyHistory && dumpAll) {
13334            pw.println();
13335            for (BroadcastQueue queue : mBroadcastQueues) {
13336                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13337                        + queue.mBroadcastsScheduled);
13338            }
13339            pw.println("  mHandler:");
13340            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13341            needSep = true;
13342            printedAnything = true;
13343        }
13344
13345        if (!printedAnything) {
13346            pw.println("  (nothing)");
13347        }
13348    }
13349
13350    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13351            int opti, boolean dumpAll, String dumpPackage) {
13352        boolean needSep;
13353        boolean printedAnything = false;
13354
13355        ItemMatcher matcher = new ItemMatcher();
13356        matcher.build(args, opti);
13357
13358        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13359
13360        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13361        printedAnything |= needSep;
13362
13363        if (mLaunchingProviders.size() > 0) {
13364            boolean printed = false;
13365            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13366                ContentProviderRecord r = mLaunchingProviders.get(i);
13367                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13368                    continue;
13369                }
13370                if (!printed) {
13371                    if (needSep) pw.println();
13372                    needSep = true;
13373                    pw.println("  Launching content providers:");
13374                    printed = true;
13375                    printedAnything = true;
13376                }
13377                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13378                        pw.println(r);
13379            }
13380        }
13381
13382        if (mGrantedUriPermissions.size() > 0) {
13383            boolean printed = false;
13384            int dumpUid = -2;
13385            if (dumpPackage != null) {
13386                try {
13387                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13388                } catch (NameNotFoundException e) {
13389                    dumpUid = -1;
13390                }
13391            }
13392            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13393                int uid = mGrantedUriPermissions.keyAt(i);
13394                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13395                    continue;
13396                }
13397                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13398                if (!printed) {
13399                    if (needSep) pw.println();
13400                    needSep = true;
13401                    pw.println("  Granted Uri Permissions:");
13402                    printed = true;
13403                    printedAnything = true;
13404                }
13405                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13406                for (UriPermission perm : perms.values()) {
13407                    pw.print("    "); pw.println(perm);
13408                    if (dumpAll) {
13409                        perm.dump(pw, "      ");
13410                    }
13411                }
13412            }
13413        }
13414
13415        if (!printedAnything) {
13416            pw.println("  (nothing)");
13417        }
13418    }
13419
13420    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13421            int opti, boolean dumpAll, String dumpPackage) {
13422        boolean printed = false;
13423
13424        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13425
13426        if (mIntentSenderRecords.size() > 0) {
13427            Iterator<WeakReference<PendingIntentRecord>> it
13428                    = mIntentSenderRecords.values().iterator();
13429            while (it.hasNext()) {
13430                WeakReference<PendingIntentRecord> ref = it.next();
13431                PendingIntentRecord rec = ref != null ? ref.get(): null;
13432                if (dumpPackage != null && (rec == null
13433                        || !dumpPackage.equals(rec.key.packageName))) {
13434                    continue;
13435                }
13436                printed = true;
13437                if (rec != null) {
13438                    pw.print("  * "); pw.println(rec);
13439                    if (dumpAll) {
13440                        rec.dump(pw, "    ");
13441                    }
13442                } else {
13443                    pw.print("  * "); pw.println(ref);
13444                }
13445            }
13446        }
13447
13448        if (!printed) {
13449            pw.println("  (nothing)");
13450        }
13451    }
13452
13453    private static final int dumpProcessList(PrintWriter pw,
13454            ActivityManagerService service, List list,
13455            String prefix, String normalLabel, String persistentLabel,
13456            String dumpPackage) {
13457        int numPers = 0;
13458        final int N = list.size()-1;
13459        for (int i=N; i>=0; i--) {
13460            ProcessRecord r = (ProcessRecord)list.get(i);
13461            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13462                continue;
13463            }
13464            pw.println(String.format("%s%s #%2d: %s",
13465                    prefix, (r.persistent ? persistentLabel : normalLabel),
13466                    i, r.toString()));
13467            if (r.persistent) {
13468                numPers++;
13469            }
13470        }
13471        return numPers;
13472    }
13473
13474    private static final boolean dumpProcessOomList(PrintWriter pw,
13475            ActivityManagerService service, List<ProcessRecord> origList,
13476            String prefix, String normalLabel, String persistentLabel,
13477            boolean inclDetails, String dumpPackage) {
13478
13479        ArrayList<Pair<ProcessRecord, Integer>> list
13480                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13481        for (int i=0; i<origList.size(); i++) {
13482            ProcessRecord r = origList.get(i);
13483            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13484                continue;
13485            }
13486            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13487        }
13488
13489        if (list.size() <= 0) {
13490            return false;
13491        }
13492
13493        Comparator<Pair<ProcessRecord, Integer>> comparator
13494                = new Comparator<Pair<ProcessRecord, Integer>>() {
13495            @Override
13496            public int compare(Pair<ProcessRecord, Integer> object1,
13497                    Pair<ProcessRecord, Integer> object2) {
13498                if (object1.first.setAdj != object2.first.setAdj) {
13499                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13500                }
13501                if (object1.second.intValue() != object2.second.intValue()) {
13502                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13503                }
13504                return 0;
13505            }
13506        };
13507
13508        Collections.sort(list, comparator);
13509
13510        final long curRealtime = SystemClock.elapsedRealtime();
13511        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13512        final long curUptime = SystemClock.uptimeMillis();
13513        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13514
13515        for (int i=list.size()-1; i>=0; i--) {
13516            ProcessRecord r = list.get(i).first;
13517            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13518            char schedGroup;
13519            switch (r.setSchedGroup) {
13520                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13521                    schedGroup = 'B';
13522                    break;
13523                case Process.THREAD_GROUP_DEFAULT:
13524                    schedGroup = 'F';
13525                    break;
13526                default:
13527                    schedGroup = '?';
13528                    break;
13529            }
13530            char foreground;
13531            if (r.foregroundActivities) {
13532                foreground = 'A';
13533            } else if (r.foregroundServices) {
13534                foreground = 'S';
13535            } else {
13536                foreground = ' ';
13537            }
13538            String procState = ProcessList.makeProcStateString(r.curProcState);
13539            pw.print(prefix);
13540            pw.print(r.persistent ? persistentLabel : normalLabel);
13541            pw.print(" #");
13542            int num = (origList.size()-1)-list.get(i).second;
13543            if (num < 10) pw.print(' ');
13544            pw.print(num);
13545            pw.print(": ");
13546            pw.print(oomAdj);
13547            pw.print(' ');
13548            pw.print(schedGroup);
13549            pw.print('/');
13550            pw.print(foreground);
13551            pw.print('/');
13552            pw.print(procState);
13553            pw.print(" trm:");
13554            if (r.trimMemoryLevel < 10) pw.print(' ');
13555            pw.print(r.trimMemoryLevel);
13556            pw.print(' ');
13557            pw.print(r.toShortString());
13558            pw.print(" (");
13559            pw.print(r.adjType);
13560            pw.println(')');
13561            if (r.adjSource != null || r.adjTarget != null) {
13562                pw.print(prefix);
13563                pw.print("    ");
13564                if (r.adjTarget instanceof ComponentName) {
13565                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13566                } else if (r.adjTarget != null) {
13567                    pw.print(r.adjTarget.toString());
13568                } else {
13569                    pw.print("{null}");
13570                }
13571                pw.print("<=");
13572                if (r.adjSource instanceof ProcessRecord) {
13573                    pw.print("Proc{");
13574                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13575                    pw.println("}");
13576                } else if (r.adjSource != null) {
13577                    pw.println(r.adjSource.toString());
13578                } else {
13579                    pw.println("{null}");
13580                }
13581            }
13582            if (inclDetails) {
13583                pw.print(prefix);
13584                pw.print("    ");
13585                pw.print("oom: max="); pw.print(r.maxAdj);
13586                pw.print(" curRaw="); pw.print(r.curRawAdj);
13587                pw.print(" setRaw="); pw.print(r.setRawAdj);
13588                pw.print(" cur="); pw.print(r.curAdj);
13589                pw.print(" set="); pw.println(r.setAdj);
13590                pw.print(prefix);
13591                pw.print("    ");
13592                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13593                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13594                pw.print(" lastPss="); pw.print(r.lastPss);
13595                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13596                pw.print(prefix);
13597                pw.print("    ");
13598                pw.print("cached="); pw.print(r.cached);
13599                pw.print(" empty="); pw.print(r.empty);
13600                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13601
13602                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13603                    if (r.lastWakeTime != 0) {
13604                        long wtime;
13605                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13606                        synchronized (stats) {
13607                            wtime = stats.getProcessWakeTime(r.info.uid,
13608                                    r.pid, curRealtime);
13609                        }
13610                        long timeUsed = wtime - r.lastWakeTime;
13611                        pw.print(prefix);
13612                        pw.print("    ");
13613                        pw.print("keep awake over ");
13614                        TimeUtils.formatDuration(realtimeSince, pw);
13615                        pw.print(" used ");
13616                        TimeUtils.formatDuration(timeUsed, pw);
13617                        pw.print(" (");
13618                        pw.print((timeUsed*100)/realtimeSince);
13619                        pw.println("%)");
13620                    }
13621                    if (r.lastCpuTime != 0) {
13622                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13623                        pw.print(prefix);
13624                        pw.print("    ");
13625                        pw.print("run cpu over ");
13626                        TimeUtils.formatDuration(uptimeSince, pw);
13627                        pw.print(" used ");
13628                        TimeUtils.formatDuration(timeUsed, pw);
13629                        pw.print(" (");
13630                        pw.print((timeUsed*100)/uptimeSince);
13631                        pw.println("%)");
13632                    }
13633                }
13634            }
13635        }
13636        return true;
13637    }
13638
13639    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
13640        ArrayList<ProcessRecord> procs;
13641        synchronized (this) {
13642            if (args != null && args.length > start
13643                    && args[start].charAt(0) != '-') {
13644                procs = new ArrayList<ProcessRecord>();
13645                int pid = -1;
13646                try {
13647                    pid = Integer.parseInt(args[start]);
13648                } catch (NumberFormatException e) {
13649                }
13650                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13651                    ProcessRecord proc = mLruProcesses.get(i);
13652                    if (proc.pid == pid) {
13653                        procs.add(proc);
13654                    } else if (proc.processName.equals(args[start])) {
13655                        procs.add(proc);
13656                    }
13657                }
13658                if (procs.size() <= 0) {
13659                    return null;
13660                }
13661            } else {
13662                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13663            }
13664        }
13665        return procs;
13666    }
13667
13668    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13669            PrintWriter pw, String[] args) {
13670        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13671        if (procs == null) {
13672            pw.println("No process found for: " + args[0]);
13673            return;
13674        }
13675
13676        long uptime = SystemClock.uptimeMillis();
13677        long realtime = SystemClock.elapsedRealtime();
13678        pw.println("Applications Graphics Acceleration Info:");
13679        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13680
13681        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13682            ProcessRecord r = procs.get(i);
13683            if (r.thread != null) {
13684                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13685                pw.flush();
13686                try {
13687                    TransferPipe tp = new TransferPipe();
13688                    try {
13689                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13690                        tp.go(fd);
13691                    } finally {
13692                        tp.kill();
13693                    }
13694                } catch (IOException e) {
13695                    pw.println("Failure while dumping the app: " + r);
13696                    pw.flush();
13697                } catch (RemoteException e) {
13698                    pw.println("Got a RemoteException while dumping the app " + r);
13699                    pw.flush();
13700                }
13701            }
13702        }
13703    }
13704
13705    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13706        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13707        if (procs == null) {
13708            pw.println("No process found for: " + args[0]);
13709            return;
13710        }
13711
13712        pw.println("Applications Database Info:");
13713
13714        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13715            ProcessRecord r = procs.get(i);
13716            if (r.thread != null) {
13717                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13718                pw.flush();
13719                try {
13720                    TransferPipe tp = new TransferPipe();
13721                    try {
13722                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13723                        tp.go(fd);
13724                    } finally {
13725                        tp.kill();
13726                    }
13727                } catch (IOException e) {
13728                    pw.println("Failure while dumping the app: " + r);
13729                    pw.flush();
13730                } catch (RemoteException e) {
13731                    pw.println("Got a RemoteException while dumping the app " + r);
13732                    pw.flush();
13733                }
13734            }
13735        }
13736    }
13737
13738    final static class MemItem {
13739        final boolean isProc;
13740        final String label;
13741        final String shortLabel;
13742        final long pss;
13743        final int id;
13744        final boolean hasActivities;
13745        ArrayList<MemItem> subitems;
13746
13747        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13748                boolean _hasActivities) {
13749            isProc = true;
13750            label = _label;
13751            shortLabel = _shortLabel;
13752            pss = _pss;
13753            id = _id;
13754            hasActivities = _hasActivities;
13755        }
13756
13757        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13758            isProc = false;
13759            label = _label;
13760            shortLabel = _shortLabel;
13761            pss = _pss;
13762            id = _id;
13763            hasActivities = false;
13764        }
13765    }
13766
13767    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13768            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13769        if (sort && !isCompact) {
13770            Collections.sort(items, new Comparator<MemItem>() {
13771                @Override
13772                public int compare(MemItem lhs, MemItem rhs) {
13773                    if (lhs.pss < rhs.pss) {
13774                        return 1;
13775                    } else if (lhs.pss > rhs.pss) {
13776                        return -1;
13777                    }
13778                    return 0;
13779                }
13780            });
13781        }
13782
13783        for (int i=0; i<items.size(); i++) {
13784            MemItem mi = items.get(i);
13785            if (!isCompact) {
13786                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13787            } else if (mi.isProc) {
13788                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13789                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13790                pw.println(mi.hasActivities ? ",a" : ",e");
13791            } else {
13792                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13793                pw.println(mi.pss);
13794            }
13795            if (mi.subitems != null) {
13796                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13797                        true, isCompact);
13798            }
13799        }
13800    }
13801
13802    // These are in KB.
13803    static final long[] DUMP_MEM_BUCKETS = new long[] {
13804        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13805        120*1024, 160*1024, 200*1024,
13806        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13807        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13808    };
13809
13810    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13811            boolean stackLike) {
13812        int start = label.lastIndexOf('.');
13813        if (start >= 0) start++;
13814        else start = 0;
13815        int end = label.length();
13816        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13817            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13818                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13819                out.append(bucket);
13820                out.append(stackLike ? "MB." : "MB ");
13821                out.append(label, start, end);
13822                return;
13823            }
13824        }
13825        out.append(memKB/1024);
13826        out.append(stackLike ? "MB." : "MB ");
13827        out.append(label, start, end);
13828    }
13829
13830    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13831            ProcessList.NATIVE_ADJ,
13832            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13833            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13834            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13835            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13836            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13837    };
13838    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13839            "Native",
13840            "System", "Persistent", "Foreground",
13841            "Visible", "Perceptible",
13842            "Heavy Weight", "Backup",
13843            "A Services", "Home",
13844            "Previous", "B Services", "Cached"
13845    };
13846    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13847            "native",
13848            "sys", "pers", "fore",
13849            "vis", "percept",
13850            "heavy", "backup",
13851            "servicea", "home",
13852            "prev", "serviceb", "cached"
13853    };
13854
13855    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13856            long realtime, boolean isCheckinRequest, boolean isCompact) {
13857        if (isCheckinRequest || isCompact) {
13858            // short checkin version
13859            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13860        } else {
13861            pw.println("Applications Memory Usage (kB):");
13862            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13863        }
13864    }
13865
13866    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13867            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13868        boolean dumpDetails = false;
13869        boolean dumpFullDetails = false;
13870        boolean dumpDalvik = false;
13871        boolean oomOnly = false;
13872        boolean isCompact = false;
13873        boolean localOnly = false;
13874
13875        int opti = 0;
13876        while (opti < args.length) {
13877            String opt = args[opti];
13878            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13879                break;
13880            }
13881            opti++;
13882            if ("-a".equals(opt)) {
13883                dumpDetails = true;
13884                dumpFullDetails = true;
13885                dumpDalvik = true;
13886            } else if ("-d".equals(opt)) {
13887                dumpDalvik = true;
13888            } else if ("-c".equals(opt)) {
13889                isCompact = true;
13890            } else if ("--oom".equals(opt)) {
13891                oomOnly = true;
13892            } else if ("--local".equals(opt)) {
13893                localOnly = true;
13894            } else if ("-h".equals(opt)) {
13895                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13896                pw.println("  -a: include all available information for each process.");
13897                pw.println("  -d: include dalvik details when dumping process details.");
13898                pw.println("  -c: dump in a compact machine-parseable representation.");
13899                pw.println("  --oom: only show processes organized by oom adj.");
13900                pw.println("  --local: only collect details locally, don't call process.");
13901                pw.println("If [process] is specified it can be the name or ");
13902                pw.println("pid of a specific process to dump.");
13903                return;
13904            } else {
13905                pw.println("Unknown argument: " + opt + "; use -h for help");
13906            }
13907        }
13908
13909        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13910        long uptime = SystemClock.uptimeMillis();
13911        long realtime = SystemClock.elapsedRealtime();
13912        final long[] tmpLong = new long[1];
13913
13914        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13915        if (procs == null) {
13916            // No Java processes.  Maybe they want to print a native process.
13917            if (args != null && args.length > opti
13918                    && args[opti].charAt(0) != '-') {
13919                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13920                        = new ArrayList<ProcessCpuTracker.Stats>();
13921                updateCpuStatsNow();
13922                int findPid = -1;
13923                try {
13924                    findPid = Integer.parseInt(args[opti]);
13925                } catch (NumberFormatException e) {
13926                }
13927                synchronized (mProcessCpuTracker) {
13928                    final int N = mProcessCpuTracker.countStats();
13929                    for (int i=0; i<N; i++) {
13930                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13931                        if (st.pid == findPid || (st.baseName != null
13932                                && st.baseName.equals(args[opti]))) {
13933                            nativeProcs.add(st);
13934                        }
13935                    }
13936                }
13937                if (nativeProcs.size() > 0) {
13938                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13939                            isCompact);
13940                    Debug.MemoryInfo mi = null;
13941                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13942                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13943                        final int pid = r.pid;
13944                        if (!isCheckinRequest && dumpDetails) {
13945                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13946                        }
13947                        if (mi == null) {
13948                            mi = new Debug.MemoryInfo();
13949                        }
13950                        if (dumpDetails || (!brief && !oomOnly)) {
13951                            Debug.getMemoryInfo(pid, mi);
13952                        } else {
13953                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13954                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13955                        }
13956                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13957                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13958                        if (isCheckinRequest) {
13959                            pw.println();
13960                        }
13961                    }
13962                    return;
13963                }
13964            }
13965            pw.println("No process found for: " + args[opti]);
13966            return;
13967        }
13968
13969        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13970            dumpDetails = true;
13971        }
13972
13973        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13974
13975        String[] innerArgs = new String[args.length-opti];
13976        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13977
13978        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13979        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13980        long nativePss=0, dalvikPss=0, otherPss=0;
13981        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13982
13983        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13984        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13985                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13986
13987        long totalPss = 0;
13988        long cachedPss = 0;
13989
13990        Debug.MemoryInfo mi = null;
13991        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13992            final ProcessRecord r = procs.get(i);
13993            final IApplicationThread thread;
13994            final int pid;
13995            final int oomAdj;
13996            final boolean hasActivities;
13997            synchronized (this) {
13998                thread = r.thread;
13999                pid = r.pid;
14000                oomAdj = r.getSetAdjWithServices();
14001                hasActivities = r.activities.size() > 0;
14002            }
14003            if (thread != null) {
14004                if (!isCheckinRequest && dumpDetails) {
14005                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14006                }
14007                if (mi == null) {
14008                    mi = new Debug.MemoryInfo();
14009                }
14010                if (dumpDetails || (!brief && !oomOnly)) {
14011                    Debug.getMemoryInfo(pid, mi);
14012                } else {
14013                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
14014                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14015                }
14016                if (dumpDetails) {
14017                    if (localOnly) {
14018                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14019                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14020                        if (isCheckinRequest) {
14021                            pw.println();
14022                        }
14023                    } else {
14024                        try {
14025                            pw.flush();
14026                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14027                                    dumpDalvik, innerArgs);
14028                        } catch (RemoteException e) {
14029                            if (!isCheckinRequest) {
14030                                pw.println("Got RemoteException!");
14031                                pw.flush();
14032                            }
14033                        }
14034                    }
14035                }
14036
14037                final long myTotalPss = mi.getTotalPss();
14038                final long myTotalUss = mi.getTotalUss();
14039
14040                synchronized (this) {
14041                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14042                        // Record this for posterity if the process has been stable.
14043                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14044                    }
14045                }
14046
14047                if (!isCheckinRequest && mi != null) {
14048                    totalPss += myTotalPss;
14049                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14050                            (hasActivities ? " / activities)" : ")"),
14051                            r.processName, myTotalPss, pid, hasActivities);
14052                    procMems.add(pssItem);
14053                    procMemsMap.put(pid, pssItem);
14054
14055                    nativePss += mi.nativePss;
14056                    dalvikPss += mi.dalvikPss;
14057                    otherPss += mi.otherPss;
14058                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14059                        long mem = mi.getOtherPss(j);
14060                        miscPss[j] += mem;
14061                        otherPss -= mem;
14062                    }
14063
14064                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14065                        cachedPss += myTotalPss;
14066                    }
14067
14068                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14069                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14070                                || oomIndex == (oomPss.length-1)) {
14071                            oomPss[oomIndex] += myTotalPss;
14072                            if (oomProcs[oomIndex] == null) {
14073                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14074                            }
14075                            oomProcs[oomIndex].add(pssItem);
14076                            break;
14077                        }
14078                    }
14079                }
14080            }
14081        }
14082
14083        long nativeProcTotalPss = 0;
14084
14085        if (!isCheckinRequest && procs.size() > 1) {
14086            // If we are showing aggregations, also look for native processes to
14087            // include so that our aggregations are more accurate.
14088            updateCpuStatsNow();
14089            synchronized (mProcessCpuTracker) {
14090                final int N = mProcessCpuTracker.countStats();
14091                for (int i=0; i<N; i++) {
14092                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14093                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14094                        if (mi == null) {
14095                            mi = new Debug.MemoryInfo();
14096                        }
14097                        if (!brief && !oomOnly) {
14098                            Debug.getMemoryInfo(st.pid, mi);
14099                        } else {
14100                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14101                            mi.nativePrivateDirty = (int)tmpLong[0];
14102                        }
14103
14104                        final long myTotalPss = mi.getTotalPss();
14105                        totalPss += myTotalPss;
14106                        nativeProcTotalPss += myTotalPss;
14107
14108                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14109                                st.name, myTotalPss, st.pid, false);
14110                        procMems.add(pssItem);
14111
14112                        nativePss += mi.nativePss;
14113                        dalvikPss += mi.dalvikPss;
14114                        otherPss += mi.otherPss;
14115                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14116                            long mem = mi.getOtherPss(j);
14117                            miscPss[j] += mem;
14118                            otherPss -= mem;
14119                        }
14120                        oomPss[0] += myTotalPss;
14121                        if (oomProcs[0] == null) {
14122                            oomProcs[0] = new ArrayList<MemItem>();
14123                        }
14124                        oomProcs[0].add(pssItem);
14125                    }
14126                }
14127            }
14128
14129            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14130
14131            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14132            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14133            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14134            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14135                String label = Debug.MemoryInfo.getOtherLabel(j);
14136                catMems.add(new MemItem(label, label, miscPss[j], j));
14137            }
14138
14139            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14140            for (int j=0; j<oomPss.length; j++) {
14141                if (oomPss[j] != 0) {
14142                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14143                            : DUMP_MEM_OOM_LABEL[j];
14144                    MemItem item = new MemItem(label, label, oomPss[j],
14145                            DUMP_MEM_OOM_ADJ[j]);
14146                    item.subitems = oomProcs[j];
14147                    oomMems.add(item);
14148                }
14149            }
14150
14151            if (!brief && !oomOnly && !isCompact) {
14152                pw.println();
14153                pw.println("Total PSS by process:");
14154                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14155                pw.println();
14156            }
14157            if (!isCompact) {
14158                pw.println("Total PSS by OOM adjustment:");
14159            }
14160            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14161            if (!brief && !oomOnly) {
14162                PrintWriter out = categoryPw != null ? categoryPw : pw;
14163                if (!isCompact) {
14164                    out.println();
14165                    out.println("Total PSS by category:");
14166                }
14167                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14168            }
14169            if (!isCompact) {
14170                pw.println();
14171            }
14172            MemInfoReader memInfo = new MemInfoReader();
14173            memInfo.readMemInfo();
14174            if (nativeProcTotalPss > 0) {
14175                synchronized (this) {
14176                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14177                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14178                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
14179                            nativeProcTotalPss);
14180                }
14181            }
14182            if (!brief) {
14183                if (!isCompact) {
14184                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14185                    pw.print(" kB (status ");
14186                    switch (mLastMemoryLevel) {
14187                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14188                            pw.println("normal)");
14189                            break;
14190                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14191                            pw.println("moderate)");
14192                            break;
14193                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14194                            pw.println("low)");
14195                            break;
14196                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14197                            pw.println("critical)");
14198                            break;
14199                        default:
14200                            pw.print(mLastMemoryLevel);
14201                            pw.println(")");
14202                            break;
14203                    }
14204                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14205                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14206                            pw.print(cachedPss); pw.print(" cached pss + ");
14207                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
14208                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14209                } else {
14210                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14211                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14212                            + memInfo.getFreeSizeKb()); pw.print(",");
14213                    pw.println(totalPss - cachedPss);
14214                }
14215            }
14216            if (!isCompact) {
14217                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14218                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
14219                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
14220                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14221                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
14222                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
14223                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
14224                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14225                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14226                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
14227                        - memInfo.getSlabSizeKb()); pw.println(" kB");
14228            }
14229            if (!brief) {
14230                if (memInfo.getZramTotalSizeKb() != 0) {
14231                    if (!isCompact) {
14232                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14233                                pw.print(" kB physical used for ");
14234                                pw.print(memInfo.getSwapTotalSizeKb()
14235                                        - memInfo.getSwapFreeSizeKb());
14236                                pw.print(" kB in swap (");
14237                                pw.print(memInfo.getSwapTotalSizeKb());
14238                                pw.println(" kB total swap)");
14239                    } else {
14240                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14241                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14242                                pw.println(memInfo.getSwapFreeSizeKb());
14243                    }
14244                }
14245                final int[] SINGLE_LONG_FORMAT = new int[] {
14246                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14247                };
14248                long[] longOut = new long[1];
14249                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14250                        SINGLE_LONG_FORMAT, null, longOut, null);
14251                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14252                longOut[0] = 0;
14253                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14254                        SINGLE_LONG_FORMAT, null, longOut, null);
14255                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14256                longOut[0] = 0;
14257                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14258                        SINGLE_LONG_FORMAT, null, longOut, null);
14259                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14260                longOut[0] = 0;
14261                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14262                        SINGLE_LONG_FORMAT, null, longOut, null);
14263                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14264                if (!isCompact) {
14265                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
14266                        pw.print("      KSM: "); pw.print(sharing);
14267                                pw.print(" kB saved from shared ");
14268                                pw.print(shared); pw.println(" kB");
14269                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
14270                                pw.print(voltile); pw.println(" kB volatile");
14271                    }
14272                    pw.print("   Tuning: ");
14273                    pw.print(ActivityManager.staticGetMemoryClass());
14274                    pw.print(" (large ");
14275                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14276                    pw.print("), oom ");
14277                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14278                    pw.print(" kB");
14279                    pw.print(", restore limit ");
14280                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14281                    pw.print(" kB");
14282                    if (ActivityManager.isLowRamDeviceStatic()) {
14283                        pw.print(" (low-ram)");
14284                    }
14285                    if (ActivityManager.isHighEndGfx()) {
14286                        pw.print(" (high-end-gfx)");
14287                    }
14288                    pw.println();
14289                } else {
14290                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
14291                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
14292                    pw.println(voltile);
14293                    pw.print("tuning,");
14294                    pw.print(ActivityManager.staticGetMemoryClass());
14295                    pw.print(',');
14296                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14297                    pw.print(',');
14298                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14299                    if (ActivityManager.isLowRamDeviceStatic()) {
14300                        pw.print(",low-ram");
14301                    }
14302                    if (ActivityManager.isHighEndGfx()) {
14303                        pw.print(",high-end-gfx");
14304                    }
14305                    pw.println();
14306                }
14307            }
14308        }
14309    }
14310
14311    /**
14312     * Searches array of arguments for the specified string
14313     * @param args array of argument strings
14314     * @param value value to search for
14315     * @return true if the value is contained in the array
14316     */
14317    private static boolean scanArgs(String[] args, String value) {
14318        if (args != null) {
14319            for (String arg : args) {
14320                if (value.equals(arg)) {
14321                    return true;
14322                }
14323            }
14324        }
14325        return false;
14326    }
14327
14328    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14329            ContentProviderRecord cpr, boolean always) {
14330        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14331
14332        if (!inLaunching || always) {
14333            synchronized (cpr) {
14334                cpr.launchingApp = null;
14335                cpr.notifyAll();
14336            }
14337            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14338            String names[] = cpr.info.authority.split(";");
14339            for (int j = 0; j < names.length; j++) {
14340                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14341            }
14342        }
14343
14344        for (int i=0; i<cpr.connections.size(); i++) {
14345            ContentProviderConnection conn = cpr.connections.get(i);
14346            if (conn.waiting) {
14347                // If this connection is waiting for the provider, then we don't
14348                // need to mess with its process unless we are always removing
14349                // or for some reason the provider is not currently launching.
14350                if (inLaunching && !always) {
14351                    continue;
14352                }
14353            }
14354            ProcessRecord capp = conn.client;
14355            conn.dead = true;
14356            if (conn.stableCount > 0) {
14357                if (!capp.persistent && capp.thread != null
14358                        && capp.pid != 0
14359                        && capp.pid != MY_PID) {
14360                    capp.kill("depends on provider "
14361                            + cpr.name.flattenToShortString()
14362                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14363                }
14364            } else if (capp.thread != null && conn.provider.provider != null) {
14365                try {
14366                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14367                } catch (RemoteException e) {
14368                }
14369                // In the protocol here, we don't expect the client to correctly
14370                // clean up this connection, we'll just remove it.
14371                cpr.connections.remove(i);
14372                conn.client.conProviders.remove(conn);
14373            }
14374        }
14375
14376        if (inLaunching && always) {
14377            mLaunchingProviders.remove(cpr);
14378        }
14379        return inLaunching;
14380    }
14381
14382    /**
14383     * Main code for cleaning up a process when it has gone away.  This is
14384     * called both as a result of the process dying, or directly when stopping
14385     * a process when running in single process mode.
14386     *
14387     * @return Returns true if the given process has been restarted, so the
14388     * app that was passed in must remain on the process lists.
14389     */
14390    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14391            boolean restarting, boolean allowRestart, int index) {
14392        if (index >= 0) {
14393            removeLruProcessLocked(app);
14394            ProcessList.remove(app.pid);
14395        }
14396
14397        mProcessesToGc.remove(app);
14398        mPendingPssProcesses.remove(app);
14399
14400        // Dismiss any open dialogs.
14401        if (app.crashDialog != null && !app.forceCrashReport) {
14402            app.crashDialog.dismiss();
14403            app.crashDialog = null;
14404        }
14405        if (app.anrDialog != null) {
14406            app.anrDialog.dismiss();
14407            app.anrDialog = null;
14408        }
14409        if (app.waitDialog != null) {
14410            app.waitDialog.dismiss();
14411            app.waitDialog = null;
14412        }
14413
14414        app.crashing = false;
14415        app.notResponding = false;
14416
14417        app.resetPackageList(mProcessStats);
14418        app.unlinkDeathRecipient();
14419        app.makeInactive(mProcessStats);
14420        app.waitingToKill = null;
14421        app.forcingToForeground = null;
14422        updateProcessForegroundLocked(app, false, false);
14423        app.foregroundActivities = false;
14424        app.hasShownUi = false;
14425        app.treatLikeActivity = false;
14426        app.hasAboveClient = false;
14427        app.hasClientActivities = false;
14428
14429        mServices.killServicesLocked(app, allowRestart);
14430
14431        boolean restart = false;
14432
14433        // Remove published content providers.
14434        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14435            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14436            final boolean always = app.bad || !allowRestart;
14437            if (removeDyingProviderLocked(app, cpr, always) || always) {
14438                // We left the provider in the launching list, need to
14439                // restart it.
14440                restart = true;
14441            }
14442
14443            cpr.provider = null;
14444            cpr.proc = null;
14445        }
14446        app.pubProviders.clear();
14447
14448        // Take care of any launching providers waiting for this process.
14449        if (checkAppInLaunchingProvidersLocked(app, false)) {
14450            restart = true;
14451        }
14452
14453        // Unregister from connected content providers.
14454        if (!app.conProviders.isEmpty()) {
14455            for (int i=0; i<app.conProviders.size(); i++) {
14456                ContentProviderConnection conn = app.conProviders.get(i);
14457                conn.provider.connections.remove(conn);
14458            }
14459            app.conProviders.clear();
14460        }
14461
14462        // At this point there may be remaining entries in mLaunchingProviders
14463        // where we were the only one waiting, so they are no longer of use.
14464        // Look for these and clean up if found.
14465        // XXX Commented out for now.  Trying to figure out a way to reproduce
14466        // the actual situation to identify what is actually going on.
14467        if (false) {
14468            for (int i=0; i<mLaunchingProviders.size(); i++) {
14469                ContentProviderRecord cpr = (ContentProviderRecord)
14470                        mLaunchingProviders.get(i);
14471                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14472                    synchronized (cpr) {
14473                        cpr.launchingApp = null;
14474                        cpr.notifyAll();
14475                    }
14476                }
14477            }
14478        }
14479
14480        skipCurrentReceiverLocked(app);
14481
14482        // Unregister any receivers.
14483        for (int i=app.receivers.size()-1; i>=0; i--) {
14484            removeReceiverLocked(app.receivers.valueAt(i));
14485        }
14486        app.receivers.clear();
14487
14488        // If the app is undergoing backup, tell the backup manager about it
14489        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14490            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14491                    + mBackupTarget.appInfo + " died during backup");
14492            try {
14493                IBackupManager bm = IBackupManager.Stub.asInterface(
14494                        ServiceManager.getService(Context.BACKUP_SERVICE));
14495                bm.agentDisconnected(app.info.packageName);
14496            } catch (RemoteException e) {
14497                // can't happen; backup manager is local
14498            }
14499        }
14500
14501        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14502            ProcessChangeItem item = mPendingProcessChanges.get(i);
14503            if (item.pid == app.pid) {
14504                mPendingProcessChanges.remove(i);
14505                mAvailProcessChanges.add(item);
14506            }
14507        }
14508        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14509
14510        // If the caller is restarting this app, then leave it in its
14511        // current lists and let the caller take care of it.
14512        if (restarting) {
14513            return false;
14514        }
14515
14516        if (!app.persistent || app.isolated) {
14517            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14518                    "Removing non-persistent process during cleanup: " + app);
14519            mProcessNames.remove(app.processName, app.uid);
14520            mIsolatedProcesses.remove(app.uid);
14521            if (mHeavyWeightProcess == app) {
14522                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14523                        mHeavyWeightProcess.userId, 0));
14524                mHeavyWeightProcess = null;
14525            }
14526        } else if (!app.removed) {
14527            // This app is persistent, so we need to keep its record around.
14528            // If it is not already on the pending app list, add it there
14529            // and start a new process for it.
14530            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14531                mPersistentStartingProcesses.add(app);
14532                restart = true;
14533            }
14534        }
14535        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14536                "Clean-up removing on hold: " + app);
14537        mProcessesOnHold.remove(app);
14538
14539        if (app == mHomeProcess) {
14540            mHomeProcess = null;
14541        }
14542        if (app == mPreviousProcess) {
14543            mPreviousProcess = null;
14544        }
14545
14546        if (restart && !app.isolated) {
14547            // We have components that still need to be running in the
14548            // process, so re-launch it.
14549            if (index < 0) {
14550                ProcessList.remove(app.pid);
14551            }
14552            mProcessNames.put(app.processName, app.uid, app);
14553            startProcessLocked(app, "restart", app.processName);
14554            return true;
14555        } else if (app.pid > 0 && app.pid != MY_PID) {
14556            // Goodbye!
14557            boolean removed;
14558            synchronized (mPidsSelfLocked) {
14559                mPidsSelfLocked.remove(app.pid);
14560                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14561            }
14562            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14563            if (app.isolated) {
14564                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14565            }
14566            app.setPid(0);
14567        }
14568        return false;
14569    }
14570
14571    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14572        // Look through the content providers we are waiting to have launched,
14573        // and if any run in this process then either schedule a restart of
14574        // the process or kill the client waiting for it if this process has
14575        // gone bad.
14576        int NL = mLaunchingProviders.size();
14577        boolean restart = false;
14578        for (int i=0; i<NL; i++) {
14579            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14580            if (cpr.launchingApp == app) {
14581                if (!alwaysBad && !app.bad) {
14582                    restart = true;
14583                } else {
14584                    removeDyingProviderLocked(app, cpr, true);
14585                    // cpr should have been removed from mLaunchingProviders
14586                    NL = mLaunchingProviders.size();
14587                    i--;
14588                }
14589            }
14590        }
14591        return restart;
14592    }
14593
14594    // =========================================================
14595    // SERVICES
14596    // =========================================================
14597
14598    @Override
14599    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14600            int flags) {
14601        enforceNotIsolatedCaller("getServices");
14602        synchronized (this) {
14603            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14604        }
14605    }
14606
14607    @Override
14608    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14609        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14610        synchronized (this) {
14611            return mServices.getRunningServiceControlPanelLocked(name);
14612        }
14613    }
14614
14615    @Override
14616    public ComponentName startService(IApplicationThread caller, Intent service,
14617            String resolvedType, int userId) {
14618        enforceNotIsolatedCaller("startService");
14619        // Refuse possible leaked file descriptors
14620        if (service != null && service.hasFileDescriptors() == true) {
14621            throw new IllegalArgumentException("File descriptors passed in Intent");
14622        }
14623
14624        if (DEBUG_SERVICE)
14625            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14626        synchronized(this) {
14627            final int callingPid = Binder.getCallingPid();
14628            final int callingUid = Binder.getCallingUid();
14629            final long origId = Binder.clearCallingIdentity();
14630            ComponentName res = mServices.startServiceLocked(caller, service,
14631                    resolvedType, callingPid, callingUid, userId);
14632            Binder.restoreCallingIdentity(origId);
14633            return res;
14634        }
14635    }
14636
14637    ComponentName startServiceInPackage(int uid,
14638            Intent service, String resolvedType, int userId) {
14639        synchronized(this) {
14640            if (DEBUG_SERVICE)
14641                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14642            final long origId = Binder.clearCallingIdentity();
14643            ComponentName res = mServices.startServiceLocked(null, service,
14644                    resolvedType, -1, uid, userId);
14645            Binder.restoreCallingIdentity(origId);
14646            return res;
14647        }
14648    }
14649
14650    @Override
14651    public int stopService(IApplicationThread caller, Intent service,
14652            String resolvedType, int userId) {
14653        enforceNotIsolatedCaller("stopService");
14654        // Refuse possible leaked file descriptors
14655        if (service != null && service.hasFileDescriptors() == true) {
14656            throw new IllegalArgumentException("File descriptors passed in Intent");
14657        }
14658
14659        synchronized(this) {
14660            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14661        }
14662    }
14663
14664    @Override
14665    public IBinder peekService(Intent service, String resolvedType) {
14666        enforceNotIsolatedCaller("peekService");
14667        // Refuse possible leaked file descriptors
14668        if (service != null && service.hasFileDescriptors() == true) {
14669            throw new IllegalArgumentException("File descriptors passed in Intent");
14670        }
14671        synchronized(this) {
14672            return mServices.peekServiceLocked(service, resolvedType);
14673        }
14674    }
14675
14676    @Override
14677    public boolean stopServiceToken(ComponentName className, IBinder token,
14678            int startId) {
14679        synchronized(this) {
14680            return mServices.stopServiceTokenLocked(className, token, startId);
14681        }
14682    }
14683
14684    @Override
14685    public void setServiceForeground(ComponentName className, IBinder token,
14686            int id, Notification notification, boolean removeNotification) {
14687        synchronized(this) {
14688            mServices.setServiceForegroundLocked(className, token, id, notification,
14689                    removeNotification);
14690        }
14691    }
14692
14693    @Override
14694    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14695            boolean requireFull, String name, String callerPackage) {
14696        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14697                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14698    }
14699
14700    int unsafeConvertIncomingUser(int userId) {
14701        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14702                ? mCurrentUserId : userId;
14703    }
14704
14705    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14706            int allowMode, String name, String callerPackage) {
14707        final int callingUserId = UserHandle.getUserId(callingUid);
14708        if (callingUserId == userId) {
14709            return userId;
14710        }
14711
14712        // Note that we may be accessing mCurrentUserId outside of a lock...
14713        // shouldn't be a big deal, if this is being called outside
14714        // of a locked context there is intrinsically a race with
14715        // the value the caller will receive and someone else changing it.
14716        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14717        // we will switch to the calling user if access to the current user fails.
14718        int targetUserId = unsafeConvertIncomingUser(userId);
14719
14720        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14721            final boolean allow;
14722            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14723                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14724                // If the caller has this permission, they always pass go.  And collect $200.
14725                allow = true;
14726            } else if (allowMode == ALLOW_FULL_ONLY) {
14727                // We require full access, sucks to be you.
14728                allow = false;
14729            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14730                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14731                // If the caller does not have either permission, they are always doomed.
14732                allow = false;
14733            } else if (allowMode == ALLOW_NON_FULL) {
14734                // We are blanket allowing non-full access, you lucky caller!
14735                allow = true;
14736            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14737                // We may or may not allow this depending on whether the two users are
14738                // in the same profile.
14739                synchronized (mUserProfileGroupIdsSelfLocked) {
14740                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14741                            UserInfo.NO_PROFILE_GROUP_ID);
14742                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14743                            UserInfo.NO_PROFILE_GROUP_ID);
14744                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14745                            && callingProfile == targetProfile;
14746                }
14747            } else {
14748                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14749            }
14750            if (!allow) {
14751                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14752                    // In this case, they would like to just execute as their
14753                    // owner user instead of failing.
14754                    targetUserId = callingUserId;
14755                } else {
14756                    StringBuilder builder = new StringBuilder(128);
14757                    builder.append("Permission Denial: ");
14758                    builder.append(name);
14759                    if (callerPackage != null) {
14760                        builder.append(" from ");
14761                        builder.append(callerPackage);
14762                    }
14763                    builder.append(" asks to run as user ");
14764                    builder.append(userId);
14765                    builder.append(" but is calling from user ");
14766                    builder.append(UserHandle.getUserId(callingUid));
14767                    builder.append("; this requires ");
14768                    builder.append(INTERACT_ACROSS_USERS_FULL);
14769                    if (allowMode != ALLOW_FULL_ONLY) {
14770                        builder.append(" or ");
14771                        builder.append(INTERACT_ACROSS_USERS);
14772                    }
14773                    String msg = builder.toString();
14774                    Slog.w(TAG, msg);
14775                    throw new SecurityException(msg);
14776                }
14777            }
14778        }
14779        if (!allowAll && targetUserId < 0) {
14780            throw new IllegalArgumentException(
14781                    "Call does not support special user #" + targetUserId);
14782        }
14783        // Check shell permission
14784        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14785            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14786                    targetUserId)) {
14787                throw new SecurityException("Shell does not have permission to access user "
14788                        + targetUserId + "\n " + Debug.getCallers(3));
14789            }
14790        }
14791        return targetUserId;
14792    }
14793
14794    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14795            String className, int flags) {
14796        boolean result = false;
14797        // For apps that don't have pre-defined UIDs, check for permission
14798        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14799            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14800                if (ActivityManager.checkUidPermission(
14801                        INTERACT_ACROSS_USERS,
14802                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14803                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14804                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14805                            + " requests FLAG_SINGLE_USER, but app does not hold "
14806                            + INTERACT_ACROSS_USERS;
14807                    Slog.w(TAG, msg);
14808                    throw new SecurityException(msg);
14809                }
14810                // Permission passed
14811                result = true;
14812            }
14813        } else if ("system".equals(componentProcessName)) {
14814            result = true;
14815        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14816            // Phone app and persistent apps are allowed to export singleuser providers.
14817            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14818                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14819        }
14820        if (DEBUG_MU) {
14821            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14822                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14823        }
14824        return result;
14825    }
14826
14827    /**
14828     * Checks to see if the caller is in the same app as the singleton
14829     * component, or the component is in a special app. It allows special apps
14830     * to export singleton components but prevents exporting singleton
14831     * components for regular apps.
14832     */
14833    boolean isValidSingletonCall(int callingUid, int componentUid) {
14834        int componentAppId = UserHandle.getAppId(componentUid);
14835        return UserHandle.isSameApp(callingUid, componentUid)
14836                || componentAppId == Process.SYSTEM_UID
14837                || componentAppId == Process.PHONE_UID
14838                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14839                        == PackageManager.PERMISSION_GRANTED;
14840    }
14841
14842    public int bindService(IApplicationThread caller, IBinder token,
14843            Intent service, String resolvedType,
14844            IServiceConnection connection, int flags, int userId) {
14845        enforceNotIsolatedCaller("bindService");
14846
14847        // Refuse possible leaked file descriptors
14848        if (service != null && service.hasFileDescriptors() == true) {
14849            throw new IllegalArgumentException("File descriptors passed in Intent");
14850        }
14851
14852        synchronized(this) {
14853            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14854                    connection, flags, userId);
14855        }
14856    }
14857
14858    public boolean unbindService(IServiceConnection connection) {
14859        synchronized (this) {
14860            return mServices.unbindServiceLocked(connection);
14861        }
14862    }
14863
14864    public void publishService(IBinder token, Intent intent, IBinder service) {
14865        // Refuse possible leaked file descriptors
14866        if (intent != null && intent.hasFileDescriptors() == true) {
14867            throw new IllegalArgumentException("File descriptors passed in Intent");
14868        }
14869
14870        synchronized(this) {
14871            if (!(token instanceof ServiceRecord)) {
14872                throw new IllegalArgumentException("Invalid service token");
14873            }
14874            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14875        }
14876    }
14877
14878    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14879        // Refuse possible leaked file descriptors
14880        if (intent != null && intent.hasFileDescriptors() == true) {
14881            throw new IllegalArgumentException("File descriptors passed in Intent");
14882        }
14883
14884        synchronized(this) {
14885            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14886        }
14887    }
14888
14889    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14890        synchronized(this) {
14891            if (!(token instanceof ServiceRecord)) {
14892                throw new IllegalArgumentException("Invalid service token");
14893            }
14894            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14895        }
14896    }
14897
14898    // =========================================================
14899    // BACKUP AND RESTORE
14900    // =========================================================
14901
14902    // Cause the target app to be launched if necessary and its backup agent
14903    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14904    // activity manager to announce its creation.
14905    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14906        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14907        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14908
14909        synchronized(this) {
14910            // !!! TODO: currently no check here that we're already bound
14911            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14912            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14913            synchronized (stats) {
14914                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14915            }
14916
14917            // Backup agent is now in use, its package can't be stopped.
14918            try {
14919                AppGlobals.getPackageManager().setPackageStoppedState(
14920                        app.packageName, false, UserHandle.getUserId(app.uid));
14921            } catch (RemoteException e) {
14922            } catch (IllegalArgumentException e) {
14923                Slog.w(TAG, "Failed trying to unstop package "
14924                        + app.packageName + ": " + e);
14925            }
14926
14927            BackupRecord r = new BackupRecord(ss, app, backupMode);
14928            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14929                    ? new ComponentName(app.packageName, app.backupAgentName)
14930                    : new ComponentName("android", "FullBackupAgent");
14931            // startProcessLocked() returns existing proc's record if it's already running
14932            ProcessRecord proc = startProcessLocked(app.processName, app,
14933                    false, 0, "backup", hostingName, false, false, false);
14934            if (proc == null) {
14935                Slog.e(TAG, "Unable to start backup agent process " + r);
14936                return false;
14937            }
14938
14939            r.app = proc;
14940            mBackupTarget = r;
14941            mBackupAppName = app.packageName;
14942
14943            // Try not to kill the process during backup
14944            updateOomAdjLocked(proc);
14945
14946            // If the process is already attached, schedule the creation of the backup agent now.
14947            // If it is not yet live, this will be done when it attaches to the framework.
14948            if (proc.thread != null) {
14949                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14950                try {
14951                    proc.thread.scheduleCreateBackupAgent(app,
14952                            compatibilityInfoForPackageLocked(app), backupMode);
14953                } catch (RemoteException e) {
14954                    // Will time out on the backup manager side
14955                }
14956            } else {
14957                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14958            }
14959            // Invariants: at this point, the target app process exists and the application
14960            // is either already running or in the process of coming up.  mBackupTarget and
14961            // mBackupAppName describe the app, so that when it binds back to the AM we
14962            // know that it's scheduled for a backup-agent operation.
14963        }
14964
14965        return true;
14966    }
14967
14968    @Override
14969    public void clearPendingBackup() {
14970        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14971        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14972
14973        synchronized (this) {
14974            mBackupTarget = null;
14975            mBackupAppName = null;
14976        }
14977    }
14978
14979    // A backup agent has just come up
14980    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14981        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14982                + " = " + agent);
14983
14984        synchronized(this) {
14985            if (!agentPackageName.equals(mBackupAppName)) {
14986                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14987                return;
14988            }
14989        }
14990
14991        long oldIdent = Binder.clearCallingIdentity();
14992        try {
14993            IBackupManager bm = IBackupManager.Stub.asInterface(
14994                    ServiceManager.getService(Context.BACKUP_SERVICE));
14995            bm.agentConnected(agentPackageName, agent);
14996        } catch (RemoteException e) {
14997            // can't happen; the backup manager service is local
14998        } catch (Exception e) {
14999            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15000            e.printStackTrace();
15001        } finally {
15002            Binder.restoreCallingIdentity(oldIdent);
15003        }
15004    }
15005
15006    // done with this agent
15007    public void unbindBackupAgent(ApplicationInfo appInfo) {
15008        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15009        if (appInfo == null) {
15010            Slog.w(TAG, "unbind backup agent for null app");
15011            return;
15012        }
15013
15014        synchronized(this) {
15015            try {
15016                if (mBackupAppName == null) {
15017                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15018                    return;
15019                }
15020
15021                if (!mBackupAppName.equals(appInfo.packageName)) {
15022                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15023                    return;
15024                }
15025
15026                // Not backing this app up any more; reset its OOM adjustment
15027                final ProcessRecord proc = mBackupTarget.app;
15028                updateOomAdjLocked(proc);
15029
15030                // If the app crashed during backup, 'thread' will be null here
15031                if (proc.thread != null) {
15032                    try {
15033                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15034                                compatibilityInfoForPackageLocked(appInfo));
15035                    } catch (Exception e) {
15036                        Slog.e(TAG, "Exception when unbinding backup agent:");
15037                        e.printStackTrace();
15038                    }
15039                }
15040            } finally {
15041                mBackupTarget = null;
15042                mBackupAppName = null;
15043            }
15044        }
15045    }
15046    // =========================================================
15047    // BROADCASTS
15048    // =========================================================
15049
15050    private final List getStickiesLocked(String action, IntentFilter filter,
15051            List cur, int userId) {
15052        final ContentResolver resolver = mContext.getContentResolver();
15053        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15054        if (stickies == null) {
15055            return cur;
15056        }
15057        final ArrayList<Intent> list = stickies.get(action);
15058        if (list == null) {
15059            return cur;
15060        }
15061        int N = list.size();
15062        for (int i=0; i<N; i++) {
15063            Intent intent = list.get(i);
15064            if (filter.match(resolver, intent, true, TAG) >= 0) {
15065                if (cur == null) {
15066                    cur = new ArrayList<Intent>();
15067                }
15068                cur.add(intent);
15069            }
15070        }
15071        return cur;
15072    }
15073
15074    boolean isPendingBroadcastProcessLocked(int pid) {
15075        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15076                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15077    }
15078
15079    void skipPendingBroadcastLocked(int pid) {
15080            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15081            for (BroadcastQueue queue : mBroadcastQueues) {
15082                queue.skipPendingBroadcastLocked(pid);
15083            }
15084    }
15085
15086    // The app just attached; send any pending broadcasts that it should receive
15087    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15088        boolean didSomething = false;
15089        for (BroadcastQueue queue : mBroadcastQueues) {
15090            didSomething |= queue.sendPendingBroadcastsLocked(app);
15091        }
15092        return didSomething;
15093    }
15094
15095    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15096            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15097        enforceNotIsolatedCaller("registerReceiver");
15098        int callingUid;
15099        int callingPid;
15100        synchronized(this) {
15101            ProcessRecord callerApp = null;
15102            if (caller != null) {
15103                callerApp = getRecordForAppLocked(caller);
15104                if (callerApp == null) {
15105                    throw new SecurityException(
15106                            "Unable to find app for caller " + caller
15107                            + " (pid=" + Binder.getCallingPid()
15108                            + ") when registering receiver " + receiver);
15109                }
15110                if (callerApp.info.uid != Process.SYSTEM_UID &&
15111                        !callerApp.pkgList.containsKey(callerPackage) &&
15112                        !"android".equals(callerPackage)) {
15113                    throw new SecurityException("Given caller package " + callerPackage
15114                            + " is not running in process " + callerApp);
15115                }
15116                callingUid = callerApp.info.uid;
15117                callingPid = callerApp.pid;
15118            } else {
15119                callerPackage = null;
15120                callingUid = Binder.getCallingUid();
15121                callingPid = Binder.getCallingPid();
15122            }
15123
15124            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15125                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15126
15127            List allSticky = null;
15128
15129            // Look for any matching sticky broadcasts...
15130            Iterator actions = filter.actionsIterator();
15131            if (actions != null) {
15132                while (actions.hasNext()) {
15133                    String action = (String)actions.next();
15134                    allSticky = getStickiesLocked(action, filter, allSticky,
15135                            UserHandle.USER_ALL);
15136                    allSticky = getStickiesLocked(action, filter, allSticky,
15137                            UserHandle.getUserId(callingUid));
15138                }
15139            } else {
15140                allSticky = getStickiesLocked(null, filter, allSticky,
15141                        UserHandle.USER_ALL);
15142                allSticky = getStickiesLocked(null, filter, allSticky,
15143                        UserHandle.getUserId(callingUid));
15144            }
15145
15146            // The first sticky in the list is returned directly back to
15147            // the client.
15148            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15149
15150            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15151                    + ": " + sticky);
15152
15153            if (receiver == null) {
15154                return sticky;
15155            }
15156
15157            ReceiverList rl
15158                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15159            if (rl == null) {
15160                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15161                        userId, receiver);
15162                if (rl.app != null) {
15163                    rl.app.receivers.add(rl);
15164                } else {
15165                    try {
15166                        receiver.asBinder().linkToDeath(rl, 0);
15167                    } catch (RemoteException e) {
15168                        return sticky;
15169                    }
15170                    rl.linkedToDeath = true;
15171                }
15172                mRegisteredReceivers.put(receiver.asBinder(), rl);
15173            } else if (rl.uid != callingUid) {
15174                throw new IllegalArgumentException(
15175                        "Receiver requested to register for uid " + callingUid
15176                        + " was previously registered for uid " + rl.uid);
15177            } else if (rl.pid != callingPid) {
15178                throw new IllegalArgumentException(
15179                        "Receiver requested to register for pid " + callingPid
15180                        + " was previously registered for pid " + rl.pid);
15181            } else if (rl.userId != userId) {
15182                throw new IllegalArgumentException(
15183                        "Receiver requested to register for user " + userId
15184                        + " was previously registered for user " + rl.userId);
15185            }
15186            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15187                    permission, callingUid, userId);
15188            rl.add(bf);
15189            if (!bf.debugCheck()) {
15190                Slog.w(TAG, "==> For Dynamic broadast");
15191            }
15192            mReceiverResolver.addFilter(bf);
15193
15194            // Enqueue broadcasts for all existing stickies that match
15195            // this filter.
15196            if (allSticky != null) {
15197                ArrayList receivers = new ArrayList();
15198                receivers.add(bf);
15199
15200                int N = allSticky.size();
15201                for (int i=0; i<N; i++) {
15202                    Intent intent = (Intent)allSticky.get(i);
15203                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15204                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15205                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15206                            null, null, false, true, true, -1);
15207                    queue.enqueueParallelBroadcastLocked(r);
15208                    queue.scheduleBroadcastsLocked();
15209                }
15210            }
15211
15212            return sticky;
15213        }
15214    }
15215
15216    public void unregisterReceiver(IIntentReceiver receiver) {
15217        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15218
15219        final long origId = Binder.clearCallingIdentity();
15220        try {
15221            boolean doTrim = false;
15222
15223            synchronized(this) {
15224                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15225                if (rl != null) {
15226                    if (rl.curBroadcast != null) {
15227                        BroadcastRecord r = rl.curBroadcast;
15228                        final boolean doNext = finishReceiverLocked(
15229                                receiver.asBinder(), r.resultCode, r.resultData,
15230                                r.resultExtras, r.resultAbort);
15231                        if (doNext) {
15232                            doTrim = true;
15233                            r.queue.processNextBroadcast(false);
15234                        }
15235                    }
15236
15237                    if (rl.app != null) {
15238                        rl.app.receivers.remove(rl);
15239                    }
15240                    removeReceiverLocked(rl);
15241                    if (rl.linkedToDeath) {
15242                        rl.linkedToDeath = false;
15243                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15244                    }
15245                }
15246            }
15247
15248            // If we actually concluded any broadcasts, we might now be able
15249            // to trim the recipients' apps from our working set
15250            if (doTrim) {
15251                trimApplications();
15252                return;
15253            }
15254
15255        } finally {
15256            Binder.restoreCallingIdentity(origId);
15257        }
15258    }
15259
15260    void removeReceiverLocked(ReceiverList rl) {
15261        mRegisteredReceivers.remove(rl.receiver.asBinder());
15262        int N = rl.size();
15263        for (int i=0; i<N; i++) {
15264            mReceiverResolver.removeFilter(rl.get(i));
15265        }
15266    }
15267
15268    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15269        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15270            ProcessRecord r = mLruProcesses.get(i);
15271            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15272                try {
15273                    r.thread.dispatchPackageBroadcast(cmd, packages);
15274                } catch (RemoteException ex) {
15275                }
15276            }
15277        }
15278    }
15279
15280    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15281            int callingUid, int[] users) {
15282        List<ResolveInfo> receivers = null;
15283        try {
15284            HashSet<ComponentName> singleUserReceivers = null;
15285            boolean scannedFirstReceivers = false;
15286            for (int user : users) {
15287                // Skip users that have Shell restrictions
15288                if (callingUid == Process.SHELL_UID
15289                        && getUserManagerLocked().hasUserRestriction(
15290                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15291                    continue;
15292                }
15293                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15294                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15295                if (user != 0 && newReceivers != null) {
15296                    // If this is not the primary user, we need to check for
15297                    // any receivers that should be filtered out.
15298                    for (int i=0; i<newReceivers.size(); i++) {
15299                        ResolveInfo ri = newReceivers.get(i);
15300                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15301                            newReceivers.remove(i);
15302                            i--;
15303                        }
15304                    }
15305                }
15306                if (newReceivers != null && newReceivers.size() == 0) {
15307                    newReceivers = null;
15308                }
15309                if (receivers == null) {
15310                    receivers = newReceivers;
15311                } else if (newReceivers != null) {
15312                    // We need to concatenate the additional receivers
15313                    // found with what we have do far.  This would be easy,
15314                    // but we also need to de-dup any receivers that are
15315                    // singleUser.
15316                    if (!scannedFirstReceivers) {
15317                        // Collect any single user receivers we had already retrieved.
15318                        scannedFirstReceivers = true;
15319                        for (int i=0; i<receivers.size(); i++) {
15320                            ResolveInfo ri = receivers.get(i);
15321                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15322                                ComponentName cn = new ComponentName(
15323                                        ri.activityInfo.packageName, ri.activityInfo.name);
15324                                if (singleUserReceivers == null) {
15325                                    singleUserReceivers = new HashSet<ComponentName>();
15326                                }
15327                                singleUserReceivers.add(cn);
15328                            }
15329                        }
15330                    }
15331                    // Add the new results to the existing results, tracking
15332                    // and de-dupping single user receivers.
15333                    for (int i=0; i<newReceivers.size(); i++) {
15334                        ResolveInfo ri = newReceivers.get(i);
15335                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15336                            ComponentName cn = new ComponentName(
15337                                    ri.activityInfo.packageName, ri.activityInfo.name);
15338                            if (singleUserReceivers == null) {
15339                                singleUserReceivers = new HashSet<ComponentName>();
15340                            }
15341                            if (!singleUserReceivers.contains(cn)) {
15342                                singleUserReceivers.add(cn);
15343                                receivers.add(ri);
15344                            }
15345                        } else {
15346                            receivers.add(ri);
15347                        }
15348                    }
15349                }
15350            }
15351        } catch (RemoteException ex) {
15352            // pm is in same process, this will never happen.
15353        }
15354        return receivers;
15355    }
15356
15357    private final int broadcastIntentLocked(ProcessRecord callerApp,
15358            String callerPackage, Intent intent, String resolvedType,
15359            IIntentReceiver resultTo, int resultCode, String resultData,
15360            Bundle map, String requiredPermission, int appOp,
15361            boolean ordered, boolean sticky, int callingPid, int callingUid,
15362            int userId) {
15363        intent = new Intent(intent);
15364
15365        // By default broadcasts do not go to stopped apps.
15366        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15367
15368        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15369            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15370            + " ordered=" + ordered + " userid=" + userId);
15371        if ((resultTo != null) && !ordered) {
15372            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15373        }
15374
15375        userId = handleIncomingUser(callingPid, callingUid, userId,
15376                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15377
15378        // Make sure that the user who is receiving this broadcast is started.
15379        // If not, we will just skip it.
15380
15381        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15382            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15383                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15384                Slog.w(TAG, "Skipping broadcast of " + intent
15385                        + ": user " + userId + " is stopped");
15386                return ActivityManager.BROADCAST_SUCCESS;
15387            }
15388        }
15389
15390        /*
15391         * Prevent non-system code (defined here to be non-persistent
15392         * processes) from sending protected broadcasts.
15393         */
15394        int callingAppId = UserHandle.getAppId(callingUid);
15395        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15396            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15397            || callingAppId == Process.NFC_UID || callingUid == 0) {
15398            // Always okay.
15399        } else if (callerApp == null || !callerApp.persistent) {
15400            try {
15401                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15402                        intent.getAction())) {
15403                    String msg = "Permission Denial: not allowed to send broadcast "
15404                            + intent.getAction() + " from pid="
15405                            + callingPid + ", uid=" + callingUid;
15406                    Slog.w(TAG, msg);
15407                    throw new SecurityException(msg);
15408                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15409                    // Special case for compatibility: we don't want apps to send this,
15410                    // but historically it has not been protected and apps may be using it
15411                    // to poke their own app widget.  So, instead of making it protected,
15412                    // just limit it to the caller.
15413                    if (callerApp == null) {
15414                        String msg = "Permission Denial: not allowed to send broadcast "
15415                                + intent.getAction() + " from unknown caller.";
15416                        Slog.w(TAG, msg);
15417                        throw new SecurityException(msg);
15418                    } else if (intent.getComponent() != null) {
15419                        // They are good enough to send to an explicit component...  verify
15420                        // it is being sent to the calling app.
15421                        if (!intent.getComponent().getPackageName().equals(
15422                                callerApp.info.packageName)) {
15423                            String msg = "Permission Denial: not allowed to send broadcast "
15424                                    + intent.getAction() + " to "
15425                                    + intent.getComponent().getPackageName() + " from "
15426                                    + callerApp.info.packageName;
15427                            Slog.w(TAG, msg);
15428                            throw new SecurityException(msg);
15429                        }
15430                    } else {
15431                        // Limit broadcast to their own package.
15432                        intent.setPackage(callerApp.info.packageName);
15433                    }
15434                }
15435            } catch (RemoteException e) {
15436                Slog.w(TAG, "Remote exception", e);
15437                return ActivityManager.BROADCAST_SUCCESS;
15438            }
15439        }
15440
15441        // Handle special intents: if this broadcast is from the package
15442        // manager about a package being removed, we need to remove all of
15443        // its activities from the history stack.
15444        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15445                intent.getAction());
15446        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15447                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15448                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15449                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15450                || uidRemoved) {
15451            if (checkComponentPermission(
15452                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15453                    callingPid, callingUid, -1, true)
15454                    == PackageManager.PERMISSION_GRANTED) {
15455                if (uidRemoved) {
15456                    final Bundle intentExtras = intent.getExtras();
15457                    final int uid = intentExtras != null
15458                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15459                    if (uid >= 0) {
15460                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15461                        synchronized (bs) {
15462                            bs.removeUidStatsLocked(uid);
15463                        }
15464                        mAppOpsService.uidRemoved(uid);
15465                    }
15466                } else {
15467                    // If resources are unavailable just force stop all
15468                    // those packages and flush the attribute cache as well.
15469                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15470                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15471                        if (list != null && (list.length > 0)) {
15472                            for (String pkg : list) {
15473                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15474                                        "storage unmount");
15475                            }
15476                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15477                            sendPackageBroadcastLocked(
15478                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15479                        }
15480                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15481                            intent.getAction())) {
15482                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15483                    } else {
15484                        Uri data = intent.getData();
15485                        String ssp;
15486                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15487                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15488                                    intent.getAction());
15489                            boolean fullUninstall = removed &&
15490                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15491                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15492                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15493                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15494                                        false, fullUninstall, userId,
15495                                        removed ? "pkg removed" : "pkg changed");
15496                            }
15497                            if (removed) {
15498                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15499                                        new String[] {ssp}, userId);
15500                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15501                                    mAppOpsService.packageRemoved(
15502                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15503
15504                                    // Remove all permissions granted from/to this package
15505                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15506                                }
15507                            }
15508                        }
15509                    }
15510                }
15511            } else {
15512                String msg = "Permission Denial: " + intent.getAction()
15513                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15514                        + ", uid=" + callingUid + ")"
15515                        + " requires "
15516                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15517                Slog.w(TAG, msg);
15518                throw new SecurityException(msg);
15519            }
15520
15521        // Special case for adding a package: by default turn on compatibility
15522        // mode.
15523        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15524            Uri data = intent.getData();
15525            String ssp;
15526            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15527                mCompatModePackages.handlePackageAddedLocked(ssp,
15528                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15529            }
15530        }
15531
15532        /*
15533         * If this is the time zone changed action, queue up a message that will reset the timezone
15534         * of all currently running processes. This message will get queued up before the broadcast
15535         * happens.
15536         */
15537        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15538            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15539        }
15540
15541        /*
15542         * If the user set the time, let all running processes know.
15543         */
15544        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15545            final int is24Hour = intent.getBooleanExtra(
15546                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15547            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15548            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15549            synchronized (stats) {
15550                stats.noteCurrentTimeChangedLocked();
15551            }
15552        }
15553
15554        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15555            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15556        }
15557
15558        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15559            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15560            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15561        }
15562
15563        // Add to the sticky list if requested.
15564        if (sticky) {
15565            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15566                    callingPid, callingUid)
15567                    != PackageManager.PERMISSION_GRANTED) {
15568                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15569                        + callingPid + ", uid=" + callingUid
15570                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15571                Slog.w(TAG, msg);
15572                throw new SecurityException(msg);
15573            }
15574            if (requiredPermission != null) {
15575                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15576                        + " and enforce permission " + requiredPermission);
15577                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15578            }
15579            if (intent.getComponent() != null) {
15580                throw new SecurityException(
15581                        "Sticky broadcasts can't target a specific component");
15582            }
15583            // We use userId directly here, since the "all" target is maintained
15584            // as a separate set of sticky broadcasts.
15585            if (userId != UserHandle.USER_ALL) {
15586                // But first, if this is not a broadcast to all users, then
15587                // make sure it doesn't conflict with an existing broadcast to
15588                // all users.
15589                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15590                        UserHandle.USER_ALL);
15591                if (stickies != null) {
15592                    ArrayList<Intent> list = stickies.get(intent.getAction());
15593                    if (list != null) {
15594                        int N = list.size();
15595                        int i;
15596                        for (i=0; i<N; i++) {
15597                            if (intent.filterEquals(list.get(i))) {
15598                                throw new IllegalArgumentException(
15599                                        "Sticky broadcast " + intent + " for user "
15600                                        + userId + " conflicts with existing global broadcast");
15601                            }
15602                        }
15603                    }
15604                }
15605            }
15606            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15607            if (stickies == null) {
15608                stickies = new ArrayMap<String, ArrayList<Intent>>();
15609                mStickyBroadcasts.put(userId, stickies);
15610            }
15611            ArrayList<Intent> list = stickies.get(intent.getAction());
15612            if (list == null) {
15613                list = new ArrayList<Intent>();
15614                stickies.put(intent.getAction(), list);
15615            }
15616            int N = list.size();
15617            int i;
15618            for (i=0; i<N; i++) {
15619                if (intent.filterEquals(list.get(i))) {
15620                    // This sticky already exists, replace it.
15621                    list.set(i, new Intent(intent));
15622                    break;
15623                }
15624            }
15625            if (i >= N) {
15626                list.add(new Intent(intent));
15627            }
15628        }
15629
15630        int[] users;
15631        if (userId == UserHandle.USER_ALL) {
15632            // Caller wants broadcast to go to all started users.
15633            users = mStartedUserArray;
15634        } else {
15635            // Caller wants broadcast to go to one specific user.
15636            users = new int[] {userId};
15637        }
15638
15639        // Figure out who all will receive this broadcast.
15640        List receivers = null;
15641        List<BroadcastFilter> registeredReceivers = null;
15642        // Need to resolve the intent to interested receivers...
15643        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15644                 == 0) {
15645            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15646        }
15647        if (intent.getComponent() == null) {
15648            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15649                // Query one target user at a time, excluding shell-restricted users
15650                UserManagerService ums = getUserManagerLocked();
15651                for (int i = 0; i < users.length; i++) {
15652                    if (ums.hasUserRestriction(
15653                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15654                        continue;
15655                    }
15656                    List<BroadcastFilter> registeredReceiversForUser =
15657                            mReceiverResolver.queryIntent(intent,
15658                                    resolvedType, false, users[i]);
15659                    if (registeredReceivers == null) {
15660                        registeredReceivers = registeredReceiversForUser;
15661                    } else if (registeredReceiversForUser != null) {
15662                        registeredReceivers.addAll(registeredReceiversForUser);
15663                    }
15664                }
15665            } else {
15666                registeredReceivers = mReceiverResolver.queryIntent(intent,
15667                        resolvedType, false, userId);
15668            }
15669        }
15670
15671        final boolean replacePending =
15672                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15673
15674        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15675                + " replacePending=" + replacePending);
15676
15677        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15678        if (!ordered && NR > 0) {
15679            // If we are not serializing this broadcast, then send the
15680            // registered receivers separately so they don't wait for the
15681            // components to be launched.
15682            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15683            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15684                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15685                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15686                    ordered, sticky, false, userId);
15687            if (DEBUG_BROADCAST) Slog.v(
15688                    TAG, "Enqueueing parallel broadcast " + r);
15689            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15690            if (!replaced) {
15691                queue.enqueueParallelBroadcastLocked(r);
15692                queue.scheduleBroadcastsLocked();
15693            }
15694            registeredReceivers = null;
15695            NR = 0;
15696        }
15697
15698        // Merge into one list.
15699        int ir = 0;
15700        if (receivers != null) {
15701            // A special case for PACKAGE_ADDED: do not allow the package
15702            // being added to see this broadcast.  This prevents them from
15703            // using this as a back door to get run as soon as they are
15704            // installed.  Maybe in the future we want to have a special install
15705            // broadcast or such for apps, but we'd like to deliberately make
15706            // this decision.
15707            String skipPackages[] = null;
15708            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15709                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15710                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15711                Uri data = intent.getData();
15712                if (data != null) {
15713                    String pkgName = data.getSchemeSpecificPart();
15714                    if (pkgName != null) {
15715                        skipPackages = new String[] { pkgName };
15716                    }
15717                }
15718            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15719                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15720            }
15721            if (skipPackages != null && (skipPackages.length > 0)) {
15722                for (String skipPackage : skipPackages) {
15723                    if (skipPackage != null) {
15724                        int NT = receivers.size();
15725                        for (int it=0; it<NT; it++) {
15726                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15727                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15728                                receivers.remove(it);
15729                                it--;
15730                                NT--;
15731                            }
15732                        }
15733                    }
15734                }
15735            }
15736
15737            int NT = receivers != null ? receivers.size() : 0;
15738            int it = 0;
15739            ResolveInfo curt = null;
15740            BroadcastFilter curr = null;
15741            while (it < NT && ir < NR) {
15742                if (curt == null) {
15743                    curt = (ResolveInfo)receivers.get(it);
15744                }
15745                if (curr == null) {
15746                    curr = registeredReceivers.get(ir);
15747                }
15748                if (curr.getPriority() >= curt.priority) {
15749                    // Insert this broadcast record into the final list.
15750                    receivers.add(it, curr);
15751                    ir++;
15752                    curr = null;
15753                    it++;
15754                    NT++;
15755                } else {
15756                    // Skip to the next ResolveInfo in the final list.
15757                    it++;
15758                    curt = null;
15759                }
15760            }
15761        }
15762        while (ir < NR) {
15763            if (receivers == null) {
15764                receivers = new ArrayList();
15765            }
15766            receivers.add(registeredReceivers.get(ir));
15767            ir++;
15768        }
15769
15770        if ((receivers != null && receivers.size() > 0)
15771                || resultTo != null) {
15772            BroadcastQueue queue = broadcastQueueForIntent(intent);
15773            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15774                    callerPackage, callingPid, callingUid, resolvedType,
15775                    requiredPermission, appOp, receivers, resultTo, resultCode,
15776                    resultData, map, ordered, sticky, false, userId);
15777            if (DEBUG_BROADCAST) Slog.v(
15778                    TAG, "Enqueueing ordered broadcast " + r
15779                    + ": prev had " + queue.mOrderedBroadcasts.size());
15780            if (DEBUG_BROADCAST) {
15781                int seq = r.intent.getIntExtra("seq", -1);
15782                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15783            }
15784            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15785            if (!replaced) {
15786                queue.enqueueOrderedBroadcastLocked(r);
15787                queue.scheduleBroadcastsLocked();
15788            }
15789        }
15790
15791        return ActivityManager.BROADCAST_SUCCESS;
15792    }
15793
15794    final Intent verifyBroadcastLocked(Intent intent) {
15795        // Refuse possible leaked file descriptors
15796        if (intent != null && intent.hasFileDescriptors() == true) {
15797            throw new IllegalArgumentException("File descriptors passed in Intent");
15798        }
15799
15800        int flags = intent.getFlags();
15801
15802        if (!mProcessesReady) {
15803            // if the caller really truly claims to know what they're doing, go
15804            // ahead and allow the broadcast without launching any receivers
15805            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15806                intent = new Intent(intent);
15807                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15808            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15809                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15810                        + " before boot completion");
15811                throw new IllegalStateException("Cannot broadcast before boot completed");
15812            }
15813        }
15814
15815        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15816            throw new IllegalArgumentException(
15817                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15818        }
15819
15820        return intent;
15821    }
15822
15823    public final int broadcastIntent(IApplicationThread caller,
15824            Intent intent, String resolvedType, IIntentReceiver resultTo,
15825            int resultCode, String resultData, Bundle map,
15826            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15827        enforceNotIsolatedCaller("broadcastIntent");
15828        synchronized(this) {
15829            intent = verifyBroadcastLocked(intent);
15830
15831            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15832            final int callingPid = Binder.getCallingPid();
15833            final int callingUid = Binder.getCallingUid();
15834            final long origId = Binder.clearCallingIdentity();
15835            int res = broadcastIntentLocked(callerApp,
15836                    callerApp != null ? callerApp.info.packageName : null,
15837                    intent, resolvedType, resultTo,
15838                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15839                    callingPid, callingUid, userId);
15840            Binder.restoreCallingIdentity(origId);
15841            return res;
15842        }
15843    }
15844
15845    int broadcastIntentInPackage(String packageName, int uid,
15846            Intent intent, String resolvedType, IIntentReceiver resultTo,
15847            int resultCode, String resultData, Bundle map,
15848            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15849        synchronized(this) {
15850            intent = verifyBroadcastLocked(intent);
15851
15852            final long origId = Binder.clearCallingIdentity();
15853            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15854                    resultTo, resultCode, resultData, map, requiredPermission,
15855                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15856            Binder.restoreCallingIdentity(origId);
15857            return res;
15858        }
15859    }
15860
15861    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15862        // Refuse possible leaked file descriptors
15863        if (intent != null && intent.hasFileDescriptors() == true) {
15864            throw new IllegalArgumentException("File descriptors passed in Intent");
15865        }
15866
15867        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15868                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15869
15870        synchronized(this) {
15871            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15872                    != PackageManager.PERMISSION_GRANTED) {
15873                String msg = "Permission Denial: unbroadcastIntent() from pid="
15874                        + Binder.getCallingPid()
15875                        + ", uid=" + Binder.getCallingUid()
15876                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15877                Slog.w(TAG, msg);
15878                throw new SecurityException(msg);
15879            }
15880            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15881            if (stickies != null) {
15882                ArrayList<Intent> list = stickies.get(intent.getAction());
15883                if (list != null) {
15884                    int N = list.size();
15885                    int i;
15886                    for (i=0; i<N; i++) {
15887                        if (intent.filterEquals(list.get(i))) {
15888                            list.remove(i);
15889                            break;
15890                        }
15891                    }
15892                    if (list.size() <= 0) {
15893                        stickies.remove(intent.getAction());
15894                    }
15895                }
15896                if (stickies.size() <= 0) {
15897                    mStickyBroadcasts.remove(userId);
15898                }
15899            }
15900        }
15901    }
15902
15903    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15904            String resultData, Bundle resultExtras, boolean resultAbort) {
15905        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15906        if (r == null) {
15907            Slog.w(TAG, "finishReceiver called but not found on queue");
15908            return false;
15909        }
15910
15911        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15912    }
15913
15914    void backgroundServicesFinishedLocked(int userId) {
15915        for (BroadcastQueue queue : mBroadcastQueues) {
15916            queue.backgroundServicesFinishedLocked(userId);
15917        }
15918    }
15919
15920    public void finishReceiver(IBinder who, int resultCode, String resultData,
15921            Bundle resultExtras, boolean resultAbort) {
15922        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15923
15924        // Refuse possible leaked file descriptors
15925        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15926            throw new IllegalArgumentException("File descriptors passed in Bundle");
15927        }
15928
15929        final long origId = Binder.clearCallingIdentity();
15930        try {
15931            boolean doNext = false;
15932            BroadcastRecord r;
15933
15934            synchronized(this) {
15935                r = broadcastRecordForReceiverLocked(who);
15936                if (r != null) {
15937                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15938                        resultData, resultExtras, resultAbort, true);
15939                }
15940            }
15941
15942            if (doNext) {
15943                r.queue.processNextBroadcast(false);
15944            }
15945            trimApplications();
15946        } finally {
15947            Binder.restoreCallingIdentity(origId);
15948        }
15949    }
15950
15951    // =========================================================
15952    // INSTRUMENTATION
15953    // =========================================================
15954
15955    public boolean startInstrumentation(ComponentName className,
15956            String profileFile, int flags, Bundle arguments,
15957            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15958            int userId, String abiOverride) {
15959        enforceNotIsolatedCaller("startInstrumentation");
15960        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15961                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15962        // Refuse possible leaked file descriptors
15963        if (arguments != null && arguments.hasFileDescriptors()) {
15964            throw new IllegalArgumentException("File descriptors passed in Bundle");
15965        }
15966
15967        synchronized(this) {
15968            InstrumentationInfo ii = null;
15969            ApplicationInfo ai = null;
15970            try {
15971                ii = mContext.getPackageManager().getInstrumentationInfo(
15972                    className, STOCK_PM_FLAGS);
15973                ai = AppGlobals.getPackageManager().getApplicationInfo(
15974                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15975            } catch (PackageManager.NameNotFoundException e) {
15976            } catch (RemoteException e) {
15977            }
15978            if (ii == null) {
15979                reportStartInstrumentationFailure(watcher, className,
15980                        "Unable to find instrumentation info for: " + className);
15981                return false;
15982            }
15983            if (ai == null) {
15984                reportStartInstrumentationFailure(watcher, className,
15985                        "Unable to find instrumentation target package: " + ii.targetPackage);
15986                return false;
15987            }
15988
15989            int match = mContext.getPackageManager().checkSignatures(
15990                    ii.targetPackage, ii.packageName);
15991            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15992                String msg = "Permission Denial: starting instrumentation "
15993                        + className + " from pid="
15994                        + Binder.getCallingPid()
15995                        + ", uid=" + Binder.getCallingPid()
15996                        + " not allowed because package " + ii.packageName
15997                        + " does not have a signature matching the target "
15998                        + ii.targetPackage;
15999                reportStartInstrumentationFailure(watcher, className, msg);
16000                throw new SecurityException(msg);
16001            }
16002
16003            final long origId = Binder.clearCallingIdentity();
16004            // Instrumentation can kill and relaunch even persistent processes
16005            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16006                    "start instr");
16007            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16008            app.instrumentationClass = className;
16009            app.instrumentationInfo = ai;
16010            app.instrumentationProfileFile = profileFile;
16011            app.instrumentationArguments = arguments;
16012            app.instrumentationWatcher = watcher;
16013            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16014            app.instrumentationResultClass = className;
16015            Binder.restoreCallingIdentity(origId);
16016        }
16017
16018        return true;
16019    }
16020
16021    /**
16022     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16023     * error to the logs, but if somebody is watching, send the report there too.  This enables
16024     * the "am" command to report errors with more information.
16025     *
16026     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16027     * @param cn The component name of the instrumentation.
16028     * @param report The error report.
16029     */
16030    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16031            ComponentName cn, String report) {
16032        Slog.w(TAG, report);
16033        try {
16034            if (watcher != null) {
16035                Bundle results = new Bundle();
16036                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16037                results.putString("Error", report);
16038                watcher.instrumentationStatus(cn, -1, results);
16039            }
16040        } catch (RemoteException e) {
16041            Slog.w(TAG, e);
16042        }
16043    }
16044
16045    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16046        if (app.instrumentationWatcher != null) {
16047            try {
16048                // NOTE:  IInstrumentationWatcher *must* be oneway here
16049                app.instrumentationWatcher.instrumentationFinished(
16050                    app.instrumentationClass,
16051                    resultCode,
16052                    results);
16053            } catch (RemoteException e) {
16054            }
16055        }
16056        if (app.instrumentationUiAutomationConnection != null) {
16057            try {
16058                app.instrumentationUiAutomationConnection.shutdown();
16059            } catch (RemoteException re) {
16060                /* ignore */
16061            }
16062            // Only a UiAutomation can set this flag and now that
16063            // it is finished we make sure it is reset to its default.
16064            mUserIsMonkey = false;
16065        }
16066        app.instrumentationWatcher = null;
16067        app.instrumentationUiAutomationConnection = null;
16068        app.instrumentationClass = null;
16069        app.instrumentationInfo = null;
16070        app.instrumentationProfileFile = null;
16071        app.instrumentationArguments = null;
16072
16073        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16074                "finished inst");
16075    }
16076
16077    public void finishInstrumentation(IApplicationThread target,
16078            int resultCode, Bundle results) {
16079        int userId = UserHandle.getCallingUserId();
16080        // Refuse possible leaked file descriptors
16081        if (results != null && results.hasFileDescriptors()) {
16082            throw new IllegalArgumentException("File descriptors passed in Intent");
16083        }
16084
16085        synchronized(this) {
16086            ProcessRecord app = getRecordForAppLocked(target);
16087            if (app == null) {
16088                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16089                return;
16090            }
16091            final long origId = Binder.clearCallingIdentity();
16092            finishInstrumentationLocked(app, resultCode, results);
16093            Binder.restoreCallingIdentity(origId);
16094        }
16095    }
16096
16097    // =========================================================
16098    // CONFIGURATION
16099    // =========================================================
16100
16101    public ConfigurationInfo getDeviceConfigurationInfo() {
16102        ConfigurationInfo config = new ConfigurationInfo();
16103        synchronized (this) {
16104            config.reqTouchScreen = mConfiguration.touchscreen;
16105            config.reqKeyboardType = mConfiguration.keyboard;
16106            config.reqNavigation = mConfiguration.navigation;
16107            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16108                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16109                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16110            }
16111            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16112                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16113                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16114            }
16115            config.reqGlEsVersion = GL_ES_VERSION;
16116        }
16117        return config;
16118    }
16119
16120    ActivityStack getFocusedStack() {
16121        return mStackSupervisor.getFocusedStack();
16122    }
16123
16124    public Configuration getConfiguration() {
16125        Configuration ci;
16126        synchronized(this) {
16127            ci = new Configuration(mConfiguration);
16128        }
16129        return ci;
16130    }
16131
16132    public void updatePersistentConfiguration(Configuration values) {
16133        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16134                "updateConfiguration()");
16135        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16136                "updateConfiguration()");
16137        if (values == null) {
16138            throw new NullPointerException("Configuration must not be null");
16139        }
16140
16141        synchronized(this) {
16142            final long origId = Binder.clearCallingIdentity();
16143            updateConfigurationLocked(values, null, true, false);
16144            Binder.restoreCallingIdentity(origId);
16145        }
16146    }
16147
16148    public void updateConfiguration(Configuration values) {
16149        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16150                "updateConfiguration()");
16151
16152        synchronized(this) {
16153            if (values == null && mWindowManager != null) {
16154                // sentinel: fetch the current configuration from the window manager
16155                values = mWindowManager.computeNewConfiguration();
16156            }
16157
16158            if (mWindowManager != null) {
16159                mProcessList.applyDisplaySize(mWindowManager);
16160            }
16161
16162            final long origId = Binder.clearCallingIdentity();
16163            if (values != null) {
16164                Settings.System.clearConfiguration(values);
16165            }
16166            updateConfigurationLocked(values, null, false, false);
16167            Binder.restoreCallingIdentity(origId);
16168        }
16169    }
16170
16171    /**
16172     * Do either or both things: (1) change the current configuration, and (2)
16173     * make sure the given activity is running with the (now) current
16174     * configuration.  Returns true if the activity has been left running, or
16175     * false if <var>starting</var> is being destroyed to match the new
16176     * configuration.
16177     * @param persistent TODO
16178     */
16179    boolean updateConfigurationLocked(Configuration values,
16180            ActivityRecord starting, boolean persistent, boolean initLocale) {
16181        int changes = 0;
16182
16183        if (values != null) {
16184            Configuration newConfig = new Configuration(mConfiguration);
16185            changes = newConfig.updateFrom(values);
16186            if (changes != 0) {
16187                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16188                    Slog.i(TAG, "Updating configuration to: " + values);
16189                }
16190
16191                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16192
16193                if (values.locale != null && !initLocale) {
16194                    saveLocaleLocked(values.locale,
16195                                     !values.locale.equals(mConfiguration.locale),
16196                                     values.userSetLocale);
16197                }
16198
16199                mConfigurationSeq++;
16200                if (mConfigurationSeq <= 0) {
16201                    mConfigurationSeq = 1;
16202                }
16203                newConfig.seq = mConfigurationSeq;
16204                mConfiguration = newConfig;
16205                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16206                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16207                //mUsageStatsService.noteStartConfig(newConfig);
16208
16209                final Configuration configCopy = new Configuration(mConfiguration);
16210
16211                // TODO: If our config changes, should we auto dismiss any currently
16212                // showing dialogs?
16213                mShowDialogs = shouldShowDialogs(newConfig);
16214
16215                AttributeCache ac = AttributeCache.instance();
16216                if (ac != null) {
16217                    ac.updateConfiguration(configCopy);
16218                }
16219
16220                // Make sure all resources in our process are updated
16221                // right now, so that anyone who is going to retrieve
16222                // resource values after we return will be sure to get
16223                // the new ones.  This is especially important during
16224                // boot, where the first config change needs to guarantee
16225                // all resources have that config before following boot
16226                // code is executed.
16227                mSystemThread.applyConfigurationToResources(configCopy);
16228
16229                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16230                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16231                    msg.obj = new Configuration(configCopy);
16232                    mHandler.sendMessage(msg);
16233                }
16234
16235                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16236                    ProcessRecord app = mLruProcesses.get(i);
16237                    try {
16238                        if (app.thread != null) {
16239                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16240                                    + app.processName + " new config " + mConfiguration);
16241                            app.thread.scheduleConfigurationChanged(configCopy);
16242                        }
16243                    } catch (Exception e) {
16244                    }
16245                }
16246                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16247                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16248                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16249                        | Intent.FLAG_RECEIVER_FOREGROUND);
16250                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16251                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16252                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16253                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16254                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16255                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16256                    broadcastIntentLocked(null, null, intent,
16257                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16258                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16259                }
16260            }
16261        }
16262
16263        boolean kept = true;
16264        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16265        // mainStack is null during startup.
16266        if (mainStack != null) {
16267            if (changes != 0 && starting == null) {
16268                // If the configuration changed, and the caller is not already
16269                // in the process of starting an activity, then find the top
16270                // activity to check if its configuration needs to change.
16271                starting = mainStack.topRunningActivityLocked(null);
16272            }
16273
16274            if (starting != null) {
16275                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16276                // And we need to make sure at this point that all other activities
16277                // are made visible with the correct configuration.
16278                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16279            }
16280        }
16281
16282        if (values != null && mWindowManager != null) {
16283            mWindowManager.setNewConfiguration(mConfiguration);
16284        }
16285
16286        return kept;
16287    }
16288
16289    /**
16290     * Decide based on the configuration whether we should shouw the ANR,
16291     * crash, etc dialogs.  The idea is that if there is no affordnace to
16292     * press the on-screen buttons, we shouldn't show the dialog.
16293     *
16294     * A thought: SystemUI might also want to get told about this, the Power
16295     * dialog / global actions also might want different behaviors.
16296     */
16297    private static final boolean shouldShowDialogs(Configuration config) {
16298        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16299                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16300    }
16301
16302    /**
16303     * Save the locale.  You must be inside a synchronized (this) block.
16304     */
16305    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16306        if(isDiff) {
16307            SystemProperties.set("user.language", l.getLanguage());
16308            SystemProperties.set("user.region", l.getCountry());
16309        }
16310
16311        if(isPersist) {
16312            SystemProperties.set("persist.sys.language", l.getLanguage());
16313            SystemProperties.set("persist.sys.country", l.getCountry());
16314            SystemProperties.set("persist.sys.localevar", l.getVariant());
16315
16316            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16317        }
16318    }
16319
16320    @Override
16321    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16322        synchronized (this) {
16323            ActivityRecord srec = ActivityRecord.forToken(token);
16324            if (srec.task != null && srec.task.stack != null) {
16325                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16326            }
16327        }
16328        return false;
16329    }
16330
16331    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16332            Intent resultData) {
16333
16334        synchronized (this) {
16335            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16336            if (stack != null) {
16337                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16338            }
16339            return false;
16340        }
16341    }
16342
16343    public int getLaunchedFromUid(IBinder activityToken) {
16344        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16345        if (srec == null) {
16346            return -1;
16347        }
16348        return srec.launchedFromUid;
16349    }
16350
16351    public String getLaunchedFromPackage(IBinder activityToken) {
16352        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16353        if (srec == null) {
16354            return null;
16355        }
16356        return srec.launchedFromPackage;
16357    }
16358
16359    // =========================================================
16360    // LIFETIME MANAGEMENT
16361    // =========================================================
16362
16363    // Returns which broadcast queue the app is the current [or imminent] receiver
16364    // on, or 'null' if the app is not an active broadcast recipient.
16365    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16366        BroadcastRecord r = app.curReceiver;
16367        if (r != null) {
16368            return r.queue;
16369        }
16370
16371        // It's not the current receiver, but it might be starting up to become one
16372        synchronized (this) {
16373            for (BroadcastQueue queue : mBroadcastQueues) {
16374                r = queue.mPendingBroadcast;
16375                if (r != null && r.curApp == app) {
16376                    // found it; report which queue it's in
16377                    return queue;
16378                }
16379            }
16380        }
16381
16382        return null;
16383    }
16384
16385    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16386            boolean doingAll, long now) {
16387        if (mAdjSeq == app.adjSeq) {
16388            // This adjustment has already been computed.
16389            return app.curRawAdj;
16390        }
16391
16392        if (app.thread == null) {
16393            app.adjSeq = mAdjSeq;
16394            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16395            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16396            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16397        }
16398
16399        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16400        app.adjSource = null;
16401        app.adjTarget = null;
16402        app.empty = false;
16403        app.cached = false;
16404
16405        final int activitiesSize = app.activities.size();
16406
16407        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16408            // The max adjustment doesn't allow this app to be anything
16409            // below foreground, so it is not worth doing work for it.
16410            app.adjType = "fixed";
16411            app.adjSeq = mAdjSeq;
16412            app.curRawAdj = app.maxAdj;
16413            app.foregroundActivities = false;
16414            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16415            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16416            // System processes can do UI, and when they do we want to have
16417            // them trim their memory after the user leaves the UI.  To
16418            // facilitate this, here we need to determine whether or not it
16419            // is currently showing UI.
16420            app.systemNoUi = true;
16421            if (app == TOP_APP) {
16422                app.systemNoUi = false;
16423            } else if (activitiesSize > 0) {
16424                for (int j = 0; j < activitiesSize; j++) {
16425                    final ActivityRecord r = app.activities.get(j);
16426                    if (r.visible) {
16427                        app.systemNoUi = false;
16428                    }
16429                }
16430            }
16431            if (!app.systemNoUi) {
16432                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16433            }
16434            return (app.curAdj=app.maxAdj);
16435        }
16436
16437        app.systemNoUi = false;
16438
16439        // Determine the importance of the process, starting with most
16440        // important to least, and assign an appropriate OOM adjustment.
16441        int adj;
16442        int schedGroup;
16443        int procState;
16444        boolean foregroundActivities = false;
16445        BroadcastQueue queue;
16446        if (app == TOP_APP) {
16447            // The last app on the list is the foreground app.
16448            adj = ProcessList.FOREGROUND_APP_ADJ;
16449            schedGroup = Process.THREAD_GROUP_DEFAULT;
16450            app.adjType = "top-activity";
16451            foregroundActivities = true;
16452            procState = ActivityManager.PROCESS_STATE_TOP;
16453        } else if (app.instrumentationClass != null) {
16454            // Don't want to kill running instrumentation.
16455            adj = ProcessList.FOREGROUND_APP_ADJ;
16456            schedGroup = Process.THREAD_GROUP_DEFAULT;
16457            app.adjType = "instrumentation";
16458            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16459        } else if ((queue = isReceivingBroadcast(app)) != null) {
16460            // An app that is currently receiving a broadcast also
16461            // counts as being in the foreground for OOM killer purposes.
16462            // It's placed in a sched group based on the nature of the
16463            // broadcast as reflected by which queue it's active in.
16464            adj = ProcessList.FOREGROUND_APP_ADJ;
16465            schedGroup = (queue == mFgBroadcastQueue)
16466                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16467            app.adjType = "broadcast";
16468            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16469        } else if (app.executingServices.size() > 0) {
16470            // An app that is currently executing a service callback also
16471            // counts as being in the foreground.
16472            adj = ProcessList.FOREGROUND_APP_ADJ;
16473            schedGroup = app.execServicesFg ?
16474                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16475            app.adjType = "exec-service";
16476            procState = ActivityManager.PROCESS_STATE_SERVICE;
16477            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16478        } else {
16479            // As far as we know the process is empty.  We may change our mind later.
16480            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16481            // At this point we don't actually know the adjustment.  Use the cached adj
16482            // value that the caller wants us to.
16483            adj = cachedAdj;
16484            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16485            app.cached = true;
16486            app.empty = true;
16487            app.adjType = "cch-empty";
16488        }
16489
16490        // Examine all activities if not already foreground.
16491        if (!foregroundActivities && activitiesSize > 0) {
16492            for (int j = 0; j < activitiesSize; j++) {
16493                final ActivityRecord r = app.activities.get(j);
16494                if (r.app != app) {
16495                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16496                            + app + "?!?");
16497                    continue;
16498                }
16499                if (r.visible) {
16500                    // App has a visible activity; only upgrade adjustment.
16501                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16502                        adj = ProcessList.VISIBLE_APP_ADJ;
16503                        app.adjType = "visible";
16504                    }
16505                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16506                        procState = ActivityManager.PROCESS_STATE_TOP;
16507                    }
16508                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16509                    app.cached = false;
16510                    app.empty = false;
16511                    foregroundActivities = true;
16512                    break;
16513                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16514                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16515                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16516                        app.adjType = "pausing";
16517                    }
16518                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16519                        procState = ActivityManager.PROCESS_STATE_TOP;
16520                    }
16521                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16522                    app.cached = false;
16523                    app.empty = false;
16524                    foregroundActivities = true;
16525                } else if (r.state == ActivityState.STOPPING) {
16526                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16527                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16528                        app.adjType = "stopping";
16529                    }
16530                    // For the process state, we will at this point consider the
16531                    // process to be cached.  It will be cached either as an activity
16532                    // or empty depending on whether the activity is finishing.  We do
16533                    // this so that we can treat the process as cached for purposes of
16534                    // memory trimming (determing current memory level, trim command to
16535                    // send to process) since there can be an arbitrary number of stopping
16536                    // processes and they should soon all go into the cached state.
16537                    if (!r.finishing) {
16538                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16539                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16540                        }
16541                    }
16542                    app.cached = false;
16543                    app.empty = false;
16544                    foregroundActivities = true;
16545                } else {
16546                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16547                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16548                        app.adjType = "cch-act";
16549                    }
16550                }
16551            }
16552        }
16553
16554        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16555            if (app.foregroundServices) {
16556                // The user is aware of this app, so make it visible.
16557                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16558                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16559                app.cached = false;
16560                app.adjType = "fg-service";
16561                schedGroup = Process.THREAD_GROUP_DEFAULT;
16562            } else if (app.forcingToForeground != null) {
16563                // The user is aware of this app, so make it visible.
16564                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16565                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16566                app.cached = false;
16567                app.adjType = "force-fg";
16568                app.adjSource = app.forcingToForeground;
16569                schedGroup = Process.THREAD_GROUP_DEFAULT;
16570            }
16571        }
16572
16573        if (app == mHeavyWeightProcess) {
16574            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16575                // We don't want to kill the current heavy-weight process.
16576                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16577                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16578                app.cached = false;
16579                app.adjType = "heavy";
16580            }
16581            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16582                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16583            }
16584        }
16585
16586        if (app == mHomeProcess) {
16587            if (adj > ProcessList.HOME_APP_ADJ) {
16588                // This process is hosting what we currently consider to be the
16589                // home app, so we don't want to let it go into the background.
16590                adj = ProcessList.HOME_APP_ADJ;
16591                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16592                app.cached = false;
16593                app.adjType = "home";
16594            }
16595            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16596                procState = ActivityManager.PROCESS_STATE_HOME;
16597            }
16598        }
16599
16600        if (app == mPreviousProcess && app.activities.size() > 0) {
16601            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16602                // This was the previous process that showed UI to the user.
16603                // We want to try to keep it around more aggressively, to give
16604                // a good experience around switching between two apps.
16605                adj = ProcessList.PREVIOUS_APP_ADJ;
16606                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16607                app.cached = false;
16608                app.adjType = "previous";
16609            }
16610            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16611                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16612            }
16613        }
16614
16615        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16616                + " reason=" + app.adjType);
16617
16618        // By default, we use the computed adjustment.  It may be changed if
16619        // there are applications dependent on our services or providers, but
16620        // this gives us a baseline and makes sure we don't get into an
16621        // infinite recursion.
16622        app.adjSeq = mAdjSeq;
16623        app.curRawAdj = adj;
16624        app.hasStartedServices = false;
16625
16626        if (mBackupTarget != null && app == mBackupTarget.app) {
16627            // If possible we want to avoid killing apps while they're being backed up
16628            if (adj > ProcessList.BACKUP_APP_ADJ) {
16629                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16630                adj = ProcessList.BACKUP_APP_ADJ;
16631                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16632                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16633                }
16634                app.adjType = "backup";
16635                app.cached = false;
16636            }
16637            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16638                procState = ActivityManager.PROCESS_STATE_BACKUP;
16639            }
16640        }
16641
16642        boolean mayBeTop = false;
16643
16644        for (int is = app.services.size()-1;
16645                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16646                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16647                        || procState > ActivityManager.PROCESS_STATE_TOP);
16648                is--) {
16649            ServiceRecord s = app.services.valueAt(is);
16650            if (s.startRequested) {
16651                app.hasStartedServices = true;
16652                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16653                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16654                }
16655                if (app.hasShownUi && app != mHomeProcess) {
16656                    // If this process has shown some UI, let it immediately
16657                    // go to the LRU list because it may be pretty heavy with
16658                    // UI stuff.  We'll tag it with a label just to help
16659                    // debug and understand what is going on.
16660                    if (adj > ProcessList.SERVICE_ADJ) {
16661                        app.adjType = "cch-started-ui-services";
16662                    }
16663                } else {
16664                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16665                        // This service has seen some activity within
16666                        // recent memory, so we will keep its process ahead
16667                        // of the background processes.
16668                        if (adj > ProcessList.SERVICE_ADJ) {
16669                            adj = ProcessList.SERVICE_ADJ;
16670                            app.adjType = "started-services";
16671                            app.cached = false;
16672                        }
16673                    }
16674                    // If we have let the service slide into the background
16675                    // state, still have some text describing what it is doing
16676                    // even though the service no longer has an impact.
16677                    if (adj > ProcessList.SERVICE_ADJ) {
16678                        app.adjType = "cch-started-services";
16679                    }
16680                }
16681            }
16682            for (int conni = s.connections.size()-1;
16683                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16684                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16685                            || procState > ActivityManager.PROCESS_STATE_TOP);
16686                    conni--) {
16687                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16688                for (int i = 0;
16689                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16690                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16691                                || procState > ActivityManager.PROCESS_STATE_TOP);
16692                        i++) {
16693                    // XXX should compute this based on the max of
16694                    // all connected clients.
16695                    ConnectionRecord cr = clist.get(i);
16696                    if (cr.binding.client == app) {
16697                        // Binding to ourself is not interesting.
16698                        continue;
16699                    }
16700                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16701                        ProcessRecord client = cr.binding.client;
16702                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16703                                TOP_APP, doingAll, now);
16704                        int clientProcState = client.curProcState;
16705                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16706                            // If the other app is cached for any reason, for purposes here
16707                            // we are going to consider it empty.  The specific cached state
16708                            // doesn't propagate except under certain conditions.
16709                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16710                        }
16711                        String adjType = null;
16712                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16713                            // Not doing bind OOM management, so treat
16714                            // this guy more like a started service.
16715                            if (app.hasShownUi && app != mHomeProcess) {
16716                                // If this process has shown some UI, let it immediately
16717                                // go to the LRU list because it may be pretty heavy with
16718                                // UI stuff.  We'll tag it with a label just to help
16719                                // debug and understand what is going on.
16720                                if (adj > clientAdj) {
16721                                    adjType = "cch-bound-ui-services";
16722                                }
16723                                app.cached = false;
16724                                clientAdj = adj;
16725                                clientProcState = procState;
16726                            } else {
16727                                if (now >= (s.lastActivity
16728                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16729                                    // This service has not seen activity within
16730                                    // recent memory, so allow it to drop to the
16731                                    // LRU list if there is no other reason to keep
16732                                    // it around.  We'll also tag it with a label just
16733                                    // to help debug and undertand what is going on.
16734                                    if (adj > clientAdj) {
16735                                        adjType = "cch-bound-services";
16736                                    }
16737                                    clientAdj = adj;
16738                                }
16739                            }
16740                        }
16741                        if (adj > clientAdj) {
16742                            // If this process has recently shown UI, and
16743                            // the process that is binding to it is less
16744                            // important than being visible, then we don't
16745                            // care about the binding as much as we care
16746                            // about letting this process get into the LRU
16747                            // list to be killed and restarted if needed for
16748                            // memory.
16749                            if (app.hasShownUi && app != mHomeProcess
16750                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16751                                adjType = "cch-bound-ui-services";
16752                            } else {
16753                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16754                                        |Context.BIND_IMPORTANT)) != 0) {
16755                                    adj = clientAdj;
16756                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16757                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16758                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16759                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16760                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16761                                    adj = clientAdj;
16762                                } else {
16763                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16764                                        adj = ProcessList.VISIBLE_APP_ADJ;
16765                                    }
16766                                }
16767                                if (!client.cached) {
16768                                    app.cached = false;
16769                                }
16770                                adjType = "service";
16771                            }
16772                        }
16773                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16774                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16775                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16776                            }
16777                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16778                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16779                                    // Special handling of clients who are in the top state.
16780                                    // We *may* want to consider this process to be in the
16781                                    // top state as well, but only if there is not another
16782                                    // reason for it to be running.  Being on the top is a
16783                                    // special state, meaning you are specifically running
16784                                    // for the current top app.  If the process is already
16785                                    // running in the background for some other reason, it
16786                                    // is more important to continue considering it to be
16787                                    // in the background state.
16788                                    mayBeTop = true;
16789                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16790                                } else {
16791                                    // Special handling for above-top states (persistent
16792                                    // processes).  These should not bring the current process
16793                                    // into the top state, since they are not on top.  Instead
16794                                    // give them the best state after that.
16795                                    clientProcState =
16796                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16797                                }
16798                            }
16799                        } else {
16800                            if (clientProcState <
16801                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16802                                clientProcState =
16803                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16804                            }
16805                        }
16806                        if (procState > clientProcState) {
16807                            procState = clientProcState;
16808                        }
16809                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16810                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16811                            app.pendingUiClean = true;
16812                        }
16813                        if (adjType != null) {
16814                            app.adjType = adjType;
16815                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16816                                    .REASON_SERVICE_IN_USE;
16817                            app.adjSource = cr.binding.client;
16818                            app.adjSourceProcState = clientProcState;
16819                            app.adjTarget = s.name;
16820                        }
16821                    }
16822                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16823                        app.treatLikeActivity = true;
16824                    }
16825                    final ActivityRecord a = cr.activity;
16826                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16827                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16828                                (a.visible || a.state == ActivityState.RESUMED
16829                                 || a.state == ActivityState.PAUSING)) {
16830                            adj = ProcessList.FOREGROUND_APP_ADJ;
16831                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16832                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16833                            }
16834                            app.cached = false;
16835                            app.adjType = "service";
16836                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16837                                    .REASON_SERVICE_IN_USE;
16838                            app.adjSource = a;
16839                            app.adjSourceProcState = procState;
16840                            app.adjTarget = s.name;
16841                        }
16842                    }
16843                }
16844            }
16845        }
16846
16847        for (int provi = app.pubProviders.size()-1;
16848                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16849                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16850                        || procState > ActivityManager.PROCESS_STATE_TOP);
16851                provi--) {
16852            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16853            for (int i = cpr.connections.size()-1;
16854                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16855                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16856                            || procState > ActivityManager.PROCESS_STATE_TOP);
16857                    i--) {
16858                ContentProviderConnection conn = cpr.connections.get(i);
16859                ProcessRecord client = conn.client;
16860                if (client == app) {
16861                    // Being our own client is not interesting.
16862                    continue;
16863                }
16864                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16865                int clientProcState = client.curProcState;
16866                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16867                    // If the other app is cached for any reason, for purposes here
16868                    // we are going to consider it empty.
16869                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16870                }
16871                if (adj > clientAdj) {
16872                    if (app.hasShownUi && app != mHomeProcess
16873                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16874                        app.adjType = "cch-ui-provider";
16875                    } else {
16876                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16877                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16878                        app.adjType = "provider";
16879                    }
16880                    app.cached &= client.cached;
16881                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16882                            .REASON_PROVIDER_IN_USE;
16883                    app.adjSource = client;
16884                    app.adjSourceProcState = clientProcState;
16885                    app.adjTarget = cpr.name;
16886                }
16887                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16888                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16889                        // Special handling of clients who are in the top state.
16890                        // We *may* want to consider this process to be in the
16891                        // top state as well, but only if there is not another
16892                        // reason for it to be running.  Being on the top is a
16893                        // special state, meaning you are specifically running
16894                        // for the current top app.  If the process is already
16895                        // running in the background for some other reason, it
16896                        // is more important to continue considering it to be
16897                        // in the background state.
16898                        mayBeTop = true;
16899                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16900                    } else {
16901                        // Special handling for above-top states (persistent
16902                        // processes).  These should not bring the current process
16903                        // into the top state, since they are not on top.  Instead
16904                        // give them the best state after that.
16905                        clientProcState =
16906                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16907                    }
16908                }
16909                if (procState > clientProcState) {
16910                    procState = clientProcState;
16911                }
16912                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16913                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16914                }
16915            }
16916            // If the provider has external (non-framework) process
16917            // dependencies, ensure that its adjustment is at least
16918            // FOREGROUND_APP_ADJ.
16919            if (cpr.hasExternalProcessHandles()) {
16920                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16921                    adj = ProcessList.FOREGROUND_APP_ADJ;
16922                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16923                    app.cached = false;
16924                    app.adjType = "provider";
16925                    app.adjTarget = cpr.name;
16926                }
16927                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16928                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16929                }
16930            }
16931        }
16932
16933        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16934            // A client of one of our services or providers is in the top state.  We
16935            // *may* want to be in the top state, but not if we are already running in
16936            // the background for some other reason.  For the decision here, we are going
16937            // to pick out a few specific states that we want to remain in when a client
16938            // is top (states that tend to be longer-term) and otherwise allow it to go
16939            // to the top state.
16940            switch (procState) {
16941                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16942                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16943                case ActivityManager.PROCESS_STATE_SERVICE:
16944                    // These all are longer-term states, so pull them up to the top
16945                    // of the background states, but not all the way to the top state.
16946                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16947                    break;
16948                default:
16949                    // Otherwise, top is a better choice, so take it.
16950                    procState = ActivityManager.PROCESS_STATE_TOP;
16951                    break;
16952            }
16953        }
16954
16955        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16956            if (app.hasClientActivities) {
16957                // This is a cached process, but with client activities.  Mark it so.
16958                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16959                app.adjType = "cch-client-act";
16960            } else if (app.treatLikeActivity) {
16961                // This is a cached process, but somebody wants us to treat it like it has
16962                // an activity, okay!
16963                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16964                app.adjType = "cch-as-act";
16965            }
16966        }
16967
16968        if (adj == ProcessList.SERVICE_ADJ) {
16969            if (doingAll) {
16970                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16971                mNewNumServiceProcs++;
16972                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16973                if (!app.serviceb) {
16974                    // This service isn't far enough down on the LRU list to
16975                    // normally be a B service, but if we are low on RAM and it
16976                    // is large we want to force it down since we would prefer to
16977                    // keep launcher over it.
16978                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16979                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16980                        app.serviceHighRam = true;
16981                        app.serviceb = true;
16982                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16983                    } else {
16984                        mNewNumAServiceProcs++;
16985                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16986                    }
16987                } else {
16988                    app.serviceHighRam = false;
16989                }
16990            }
16991            if (app.serviceb) {
16992                adj = ProcessList.SERVICE_B_ADJ;
16993            }
16994        }
16995
16996        app.curRawAdj = adj;
16997
16998        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16999        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17000        if (adj > app.maxAdj) {
17001            adj = app.maxAdj;
17002            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17003                schedGroup = Process.THREAD_GROUP_DEFAULT;
17004            }
17005        }
17006
17007        // Do final modification to adj.  Everything we do between here and applying
17008        // the final setAdj must be done in this function, because we will also use
17009        // it when computing the final cached adj later.  Note that we don't need to
17010        // worry about this for max adj above, since max adj will always be used to
17011        // keep it out of the cached vaues.
17012        app.curAdj = app.modifyRawOomAdj(adj);
17013        app.curSchedGroup = schedGroup;
17014        app.curProcState = procState;
17015        app.foregroundActivities = foregroundActivities;
17016
17017        return app.curRawAdj;
17018    }
17019
17020    /**
17021     * Schedule PSS collection of a process.
17022     */
17023    void requestPssLocked(ProcessRecord proc, int procState) {
17024        if (mPendingPssProcesses.contains(proc)) {
17025            return;
17026        }
17027        if (mPendingPssProcesses.size() == 0) {
17028            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17029        }
17030        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17031        proc.pssProcState = procState;
17032        mPendingPssProcesses.add(proc);
17033    }
17034
17035    /**
17036     * Schedule PSS collection of all processes.
17037     */
17038    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17039        if (!always) {
17040            if (now < (mLastFullPssTime +
17041                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17042                return;
17043            }
17044        }
17045        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17046        mLastFullPssTime = now;
17047        mFullPssPending = true;
17048        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17049        mPendingPssProcesses.clear();
17050        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17051            ProcessRecord app = mLruProcesses.get(i);
17052            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17053                app.pssProcState = app.setProcState;
17054                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17055                        isSleeping(), now);
17056                mPendingPssProcesses.add(app);
17057            }
17058        }
17059        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17060    }
17061
17062    /**
17063     * Ask a given process to GC right now.
17064     */
17065    final void performAppGcLocked(ProcessRecord app) {
17066        try {
17067            app.lastRequestedGc = SystemClock.uptimeMillis();
17068            if (app.thread != null) {
17069                if (app.reportLowMemory) {
17070                    app.reportLowMemory = false;
17071                    app.thread.scheduleLowMemory();
17072                } else {
17073                    app.thread.processInBackground();
17074                }
17075            }
17076        } catch (Exception e) {
17077            // whatever.
17078        }
17079    }
17080
17081    /**
17082     * Returns true if things are idle enough to perform GCs.
17083     */
17084    private final boolean canGcNowLocked() {
17085        boolean processingBroadcasts = false;
17086        for (BroadcastQueue q : mBroadcastQueues) {
17087            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17088                processingBroadcasts = true;
17089            }
17090        }
17091        return !processingBroadcasts
17092                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17093    }
17094
17095    /**
17096     * Perform GCs on all processes that are waiting for it, but only
17097     * if things are idle.
17098     */
17099    final void performAppGcsLocked() {
17100        final int N = mProcessesToGc.size();
17101        if (N <= 0) {
17102            return;
17103        }
17104        if (canGcNowLocked()) {
17105            while (mProcessesToGc.size() > 0) {
17106                ProcessRecord proc = mProcessesToGc.remove(0);
17107                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17108                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17109                            <= SystemClock.uptimeMillis()) {
17110                        // To avoid spamming the system, we will GC processes one
17111                        // at a time, waiting a few seconds between each.
17112                        performAppGcLocked(proc);
17113                        scheduleAppGcsLocked();
17114                        return;
17115                    } else {
17116                        // It hasn't been long enough since we last GCed this
17117                        // process...  put it in the list to wait for its time.
17118                        addProcessToGcListLocked(proc);
17119                        break;
17120                    }
17121                }
17122            }
17123
17124            scheduleAppGcsLocked();
17125        }
17126    }
17127
17128    /**
17129     * If all looks good, perform GCs on all processes waiting for them.
17130     */
17131    final void performAppGcsIfAppropriateLocked() {
17132        if (canGcNowLocked()) {
17133            performAppGcsLocked();
17134            return;
17135        }
17136        // Still not idle, wait some more.
17137        scheduleAppGcsLocked();
17138    }
17139
17140    /**
17141     * Schedule the execution of all pending app GCs.
17142     */
17143    final void scheduleAppGcsLocked() {
17144        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17145
17146        if (mProcessesToGc.size() > 0) {
17147            // Schedule a GC for the time to the next process.
17148            ProcessRecord proc = mProcessesToGc.get(0);
17149            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17150
17151            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17152            long now = SystemClock.uptimeMillis();
17153            if (when < (now+GC_TIMEOUT)) {
17154                when = now + GC_TIMEOUT;
17155            }
17156            mHandler.sendMessageAtTime(msg, when);
17157        }
17158    }
17159
17160    /**
17161     * Add a process to the array of processes waiting to be GCed.  Keeps the
17162     * list in sorted order by the last GC time.  The process can't already be
17163     * on the list.
17164     */
17165    final void addProcessToGcListLocked(ProcessRecord proc) {
17166        boolean added = false;
17167        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17168            if (mProcessesToGc.get(i).lastRequestedGc <
17169                    proc.lastRequestedGc) {
17170                added = true;
17171                mProcessesToGc.add(i+1, proc);
17172                break;
17173            }
17174        }
17175        if (!added) {
17176            mProcessesToGc.add(0, proc);
17177        }
17178    }
17179
17180    /**
17181     * Set up to ask a process to GC itself.  This will either do it
17182     * immediately, or put it on the list of processes to gc the next
17183     * time things are idle.
17184     */
17185    final void scheduleAppGcLocked(ProcessRecord app) {
17186        long now = SystemClock.uptimeMillis();
17187        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17188            return;
17189        }
17190        if (!mProcessesToGc.contains(app)) {
17191            addProcessToGcListLocked(app);
17192            scheduleAppGcsLocked();
17193        }
17194    }
17195
17196    final void checkExcessivePowerUsageLocked(boolean doKills) {
17197        updateCpuStatsNow();
17198
17199        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17200        boolean doWakeKills = doKills;
17201        boolean doCpuKills = doKills;
17202        if (mLastPowerCheckRealtime == 0) {
17203            doWakeKills = false;
17204        }
17205        if (mLastPowerCheckUptime == 0) {
17206            doCpuKills = false;
17207        }
17208        if (stats.isScreenOn()) {
17209            doWakeKills = false;
17210        }
17211        final long curRealtime = SystemClock.elapsedRealtime();
17212        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17213        final long curUptime = SystemClock.uptimeMillis();
17214        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17215        mLastPowerCheckRealtime = curRealtime;
17216        mLastPowerCheckUptime = curUptime;
17217        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17218            doWakeKills = false;
17219        }
17220        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17221            doCpuKills = false;
17222        }
17223        int i = mLruProcesses.size();
17224        while (i > 0) {
17225            i--;
17226            ProcessRecord app = mLruProcesses.get(i);
17227            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17228                long wtime;
17229                synchronized (stats) {
17230                    wtime = stats.getProcessWakeTime(app.info.uid,
17231                            app.pid, curRealtime);
17232                }
17233                long wtimeUsed = wtime - app.lastWakeTime;
17234                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17235                if (DEBUG_POWER) {
17236                    StringBuilder sb = new StringBuilder(128);
17237                    sb.append("Wake for ");
17238                    app.toShortString(sb);
17239                    sb.append(": over ");
17240                    TimeUtils.formatDuration(realtimeSince, sb);
17241                    sb.append(" used ");
17242                    TimeUtils.formatDuration(wtimeUsed, sb);
17243                    sb.append(" (");
17244                    sb.append((wtimeUsed*100)/realtimeSince);
17245                    sb.append("%)");
17246                    Slog.i(TAG, sb.toString());
17247                    sb.setLength(0);
17248                    sb.append("CPU for ");
17249                    app.toShortString(sb);
17250                    sb.append(": over ");
17251                    TimeUtils.formatDuration(uptimeSince, sb);
17252                    sb.append(" used ");
17253                    TimeUtils.formatDuration(cputimeUsed, sb);
17254                    sb.append(" (");
17255                    sb.append((cputimeUsed*100)/uptimeSince);
17256                    sb.append("%)");
17257                    Slog.i(TAG, sb.toString());
17258                }
17259                // If a process has held a wake lock for more
17260                // than 50% of the time during this period,
17261                // that sounds bad.  Kill!
17262                if (doWakeKills && realtimeSince > 0
17263                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17264                    synchronized (stats) {
17265                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17266                                realtimeSince, wtimeUsed);
17267                    }
17268                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17269                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17270                } else if (doCpuKills && uptimeSince > 0
17271                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17272                    synchronized (stats) {
17273                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17274                                uptimeSince, cputimeUsed);
17275                    }
17276                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17277                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17278                } else {
17279                    app.lastWakeTime = wtime;
17280                    app.lastCpuTime = app.curCpuTime;
17281                }
17282            }
17283        }
17284    }
17285
17286    private final boolean applyOomAdjLocked(ProcessRecord app,
17287            ProcessRecord TOP_APP, boolean doingAll, long now) {
17288        boolean success = true;
17289
17290        if (app.curRawAdj != app.setRawAdj) {
17291            app.setRawAdj = app.curRawAdj;
17292        }
17293
17294        int changes = 0;
17295
17296        if (app.curAdj != app.setAdj) {
17297            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17298            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17299                TAG, "Set " + app.pid + " " + app.processName +
17300                " adj " + app.curAdj + ": " + app.adjType);
17301            app.setAdj = app.curAdj;
17302        }
17303
17304        if (app.setSchedGroup != app.curSchedGroup) {
17305            app.setSchedGroup = app.curSchedGroup;
17306            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17307                    "Setting process group of " + app.processName
17308                    + " to " + app.curSchedGroup);
17309            if (app.waitingToKill != null &&
17310                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17311                app.kill(app.waitingToKill, true);
17312                success = false;
17313            } else {
17314                if (true) {
17315                    long oldId = Binder.clearCallingIdentity();
17316                    try {
17317                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17318                    } catch (Exception e) {
17319                        Slog.w(TAG, "Failed setting process group of " + app.pid
17320                                + " to " + app.curSchedGroup);
17321                        e.printStackTrace();
17322                    } finally {
17323                        Binder.restoreCallingIdentity(oldId);
17324                    }
17325                } else {
17326                    if (app.thread != null) {
17327                        try {
17328                            app.thread.setSchedulingGroup(app.curSchedGroup);
17329                        } catch (RemoteException e) {
17330                        }
17331                    }
17332                }
17333                Process.setSwappiness(app.pid,
17334                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17335            }
17336        }
17337        if (app.repForegroundActivities != app.foregroundActivities) {
17338            app.repForegroundActivities = app.foregroundActivities;
17339            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17340        }
17341        if (app.repProcState != app.curProcState) {
17342            app.repProcState = app.curProcState;
17343            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17344            if (app.thread != null) {
17345                try {
17346                    if (false) {
17347                        //RuntimeException h = new RuntimeException("here");
17348                        Slog.i(TAG, "Sending new process state " + app.repProcState
17349                                + " to " + app /*, h*/);
17350                    }
17351                    app.thread.setProcessState(app.repProcState);
17352                } catch (RemoteException e) {
17353                }
17354            }
17355        }
17356        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17357                app.setProcState)) {
17358            app.lastStateTime = now;
17359            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17360                    isSleeping(), now);
17361            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17362                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17363                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17364                    + (app.nextPssTime-now) + ": " + app);
17365        } else {
17366            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17367                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17368                requestPssLocked(app, app.setProcState);
17369                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17370                        isSleeping(), now);
17371            } else if (false && DEBUG_PSS) {
17372                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17373            }
17374        }
17375        if (app.setProcState != app.curProcState) {
17376            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17377                    "Proc state change of " + app.processName
17378                    + " to " + app.curProcState);
17379            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17380            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17381            if (setImportant && !curImportant) {
17382                // This app is no longer something we consider important enough to allow to
17383                // use arbitrary amounts of battery power.  Note
17384                // its current wake lock time to later know to kill it if
17385                // it is not behaving well.
17386                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17387                synchronized (stats) {
17388                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17389                            app.pid, SystemClock.elapsedRealtime());
17390                }
17391                app.lastCpuTime = app.curCpuTime;
17392
17393            }
17394            app.setProcState = app.curProcState;
17395            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17396                app.notCachedSinceIdle = false;
17397            }
17398            if (!doingAll) {
17399                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17400            } else {
17401                app.procStateChanged = true;
17402            }
17403        }
17404
17405        if (changes != 0) {
17406            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17407            int i = mPendingProcessChanges.size()-1;
17408            ProcessChangeItem item = null;
17409            while (i >= 0) {
17410                item = mPendingProcessChanges.get(i);
17411                if (item.pid == app.pid) {
17412                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17413                    break;
17414                }
17415                i--;
17416            }
17417            if (i < 0) {
17418                // No existing item in pending changes; need a new one.
17419                final int NA = mAvailProcessChanges.size();
17420                if (NA > 0) {
17421                    item = mAvailProcessChanges.remove(NA-1);
17422                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17423                } else {
17424                    item = new ProcessChangeItem();
17425                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17426                }
17427                item.changes = 0;
17428                item.pid = app.pid;
17429                item.uid = app.info.uid;
17430                if (mPendingProcessChanges.size() == 0) {
17431                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17432                            "*** Enqueueing dispatch processes changed!");
17433                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17434                }
17435                mPendingProcessChanges.add(item);
17436            }
17437            item.changes |= changes;
17438            item.processState = app.repProcState;
17439            item.foregroundActivities = app.repForegroundActivities;
17440            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17441                    + Integer.toHexString(System.identityHashCode(item))
17442                    + " " + app.toShortString() + ": changes=" + item.changes
17443                    + " procState=" + item.processState
17444                    + " foreground=" + item.foregroundActivities
17445                    + " type=" + app.adjType + " source=" + app.adjSource
17446                    + " target=" + app.adjTarget);
17447        }
17448
17449        return success;
17450    }
17451
17452    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17453        if (proc.thread != null) {
17454            if (proc.baseProcessTracker != null) {
17455                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17456            }
17457            if (proc.repProcState >= 0) {
17458                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17459                        proc.repProcState);
17460            }
17461        }
17462    }
17463
17464    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17465            ProcessRecord TOP_APP, boolean doingAll, long now) {
17466        if (app.thread == null) {
17467            return false;
17468        }
17469
17470        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17471
17472        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17473    }
17474
17475    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17476            boolean oomAdj) {
17477        if (isForeground != proc.foregroundServices) {
17478            proc.foregroundServices = isForeground;
17479            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17480                    proc.info.uid);
17481            if (isForeground) {
17482                if (curProcs == null) {
17483                    curProcs = new ArrayList<ProcessRecord>();
17484                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17485                }
17486                if (!curProcs.contains(proc)) {
17487                    curProcs.add(proc);
17488                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17489                            proc.info.packageName, proc.info.uid);
17490                }
17491            } else {
17492                if (curProcs != null) {
17493                    if (curProcs.remove(proc)) {
17494                        mBatteryStatsService.noteEvent(
17495                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17496                                proc.info.packageName, proc.info.uid);
17497                        if (curProcs.size() <= 0) {
17498                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17499                        }
17500                    }
17501                }
17502            }
17503            if (oomAdj) {
17504                updateOomAdjLocked();
17505            }
17506        }
17507    }
17508
17509    private final ActivityRecord resumedAppLocked() {
17510        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17511        String pkg;
17512        int uid;
17513        if (act != null) {
17514            pkg = act.packageName;
17515            uid = act.info.applicationInfo.uid;
17516        } else {
17517            pkg = null;
17518            uid = -1;
17519        }
17520        // Has the UID or resumed package name changed?
17521        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17522                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17523            if (mCurResumedPackage != null) {
17524                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17525                        mCurResumedPackage, mCurResumedUid);
17526            }
17527            mCurResumedPackage = pkg;
17528            mCurResumedUid = uid;
17529            if (mCurResumedPackage != null) {
17530                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17531                        mCurResumedPackage, mCurResumedUid);
17532            }
17533        }
17534        return act;
17535    }
17536
17537    final boolean updateOomAdjLocked(ProcessRecord app) {
17538        final ActivityRecord TOP_ACT = resumedAppLocked();
17539        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17540        final boolean wasCached = app.cached;
17541
17542        mAdjSeq++;
17543
17544        // This is the desired cached adjusment we want to tell it to use.
17545        // If our app is currently cached, we know it, and that is it.  Otherwise,
17546        // we don't know it yet, and it needs to now be cached we will then
17547        // need to do a complete oom adj.
17548        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17549                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17550        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17551                SystemClock.uptimeMillis());
17552        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17553            // Changed to/from cached state, so apps after it in the LRU
17554            // list may also be changed.
17555            updateOomAdjLocked();
17556        }
17557        return success;
17558    }
17559
17560    final void updateOomAdjLocked() {
17561        final ActivityRecord TOP_ACT = resumedAppLocked();
17562        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17563        final long now = SystemClock.uptimeMillis();
17564        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17565        final int N = mLruProcesses.size();
17566
17567        if (false) {
17568            RuntimeException e = new RuntimeException();
17569            e.fillInStackTrace();
17570            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17571        }
17572
17573        mAdjSeq++;
17574        mNewNumServiceProcs = 0;
17575        mNewNumAServiceProcs = 0;
17576
17577        final int emptyProcessLimit;
17578        final int cachedProcessLimit;
17579        if (mProcessLimit <= 0) {
17580            emptyProcessLimit = cachedProcessLimit = 0;
17581        } else if (mProcessLimit == 1) {
17582            emptyProcessLimit = 1;
17583            cachedProcessLimit = 0;
17584        } else {
17585            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17586            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17587        }
17588
17589        // Let's determine how many processes we have running vs.
17590        // how many slots we have for background processes; we may want
17591        // to put multiple processes in a slot of there are enough of
17592        // them.
17593        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17594                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17595        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17596        if (numEmptyProcs > cachedProcessLimit) {
17597            // If there are more empty processes than our limit on cached
17598            // processes, then use the cached process limit for the factor.
17599            // This ensures that the really old empty processes get pushed
17600            // down to the bottom, so if we are running low on memory we will
17601            // have a better chance at keeping around more cached processes
17602            // instead of a gazillion empty processes.
17603            numEmptyProcs = cachedProcessLimit;
17604        }
17605        int emptyFactor = numEmptyProcs/numSlots;
17606        if (emptyFactor < 1) emptyFactor = 1;
17607        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17608        if (cachedFactor < 1) cachedFactor = 1;
17609        int stepCached = 0;
17610        int stepEmpty = 0;
17611        int numCached = 0;
17612        int numEmpty = 0;
17613        int numTrimming = 0;
17614
17615        mNumNonCachedProcs = 0;
17616        mNumCachedHiddenProcs = 0;
17617
17618        // First update the OOM adjustment for each of the
17619        // application processes based on their current state.
17620        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17621        int nextCachedAdj = curCachedAdj+1;
17622        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17623        int nextEmptyAdj = curEmptyAdj+2;
17624        for (int i=N-1; i>=0; i--) {
17625            ProcessRecord app = mLruProcesses.get(i);
17626            if (!app.killedByAm && app.thread != null) {
17627                app.procStateChanged = false;
17628                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17629
17630                // If we haven't yet assigned the final cached adj
17631                // to the process, do that now.
17632                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17633                    switch (app.curProcState) {
17634                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17635                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17636                            // This process is a cached process holding activities...
17637                            // assign it the next cached value for that type, and then
17638                            // step that cached level.
17639                            app.curRawAdj = curCachedAdj;
17640                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17641                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17642                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17643                                    + ")");
17644                            if (curCachedAdj != nextCachedAdj) {
17645                                stepCached++;
17646                                if (stepCached >= cachedFactor) {
17647                                    stepCached = 0;
17648                                    curCachedAdj = nextCachedAdj;
17649                                    nextCachedAdj += 2;
17650                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17651                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17652                                    }
17653                                }
17654                            }
17655                            break;
17656                        default:
17657                            // For everything else, assign next empty cached process
17658                            // level and bump that up.  Note that this means that
17659                            // long-running services that have dropped down to the
17660                            // cached level will be treated as empty (since their process
17661                            // state is still as a service), which is what we want.
17662                            app.curRawAdj = curEmptyAdj;
17663                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17664                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17665                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17666                                    + ")");
17667                            if (curEmptyAdj != nextEmptyAdj) {
17668                                stepEmpty++;
17669                                if (stepEmpty >= emptyFactor) {
17670                                    stepEmpty = 0;
17671                                    curEmptyAdj = nextEmptyAdj;
17672                                    nextEmptyAdj += 2;
17673                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17674                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17675                                    }
17676                                }
17677                            }
17678                            break;
17679                    }
17680                }
17681
17682                applyOomAdjLocked(app, TOP_APP, true, now);
17683
17684                // Count the number of process types.
17685                switch (app.curProcState) {
17686                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17687                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17688                        mNumCachedHiddenProcs++;
17689                        numCached++;
17690                        if (numCached > cachedProcessLimit) {
17691                            app.kill("cached #" + numCached, true);
17692                        }
17693                        break;
17694                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17695                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17696                                && app.lastActivityTime < oldTime) {
17697                            app.kill("empty for "
17698                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17699                                    / 1000) + "s", true);
17700                        } else {
17701                            numEmpty++;
17702                            if (numEmpty > emptyProcessLimit) {
17703                                app.kill("empty #" + numEmpty, true);
17704                            }
17705                        }
17706                        break;
17707                    default:
17708                        mNumNonCachedProcs++;
17709                        break;
17710                }
17711
17712                if (app.isolated && app.services.size() <= 0) {
17713                    // If this is an isolated process, and there are no
17714                    // services running in it, then the process is no longer
17715                    // needed.  We agressively kill these because we can by
17716                    // definition not re-use the same process again, and it is
17717                    // good to avoid having whatever code was running in them
17718                    // left sitting around after no longer needed.
17719                    app.kill("isolated not needed", true);
17720                }
17721
17722                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17723                        && !app.killedByAm) {
17724                    numTrimming++;
17725                }
17726            }
17727        }
17728
17729        mNumServiceProcs = mNewNumServiceProcs;
17730
17731        // Now determine the memory trimming level of background processes.
17732        // Unfortunately we need to start at the back of the list to do this
17733        // properly.  We only do this if the number of background apps we
17734        // are managing to keep around is less than half the maximum we desire;
17735        // if we are keeping a good number around, we'll let them use whatever
17736        // memory they want.
17737        final int numCachedAndEmpty = numCached + numEmpty;
17738        int memFactor;
17739        if (numCached <= ProcessList.TRIM_CACHED_APPS
17740                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17741            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17742                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17743            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17744                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17745            } else {
17746                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17747            }
17748        } else {
17749            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17750        }
17751        // We always allow the memory level to go up (better).  We only allow it to go
17752        // down if we are in a state where that is allowed, *and* the total number of processes
17753        // has gone down since last time.
17754        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17755                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17756                + " last=" + mLastNumProcesses);
17757        if (memFactor > mLastMemoryLevel) {
17758            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17759                memFactor = mLastMemoryLevel;
17760                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17761            }
17762        }
17763        mLastMemoryLevel = memFactor;
17764        mLastNumProcesses = mLruProcesses.size();
17765        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17766        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17767        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17768            if (mLowRamStartTime == 0) {
17769                mLowRamStartTime = now;
17770            }
17771            int step = 0;
17772            int fgTrimLevel;
17773            switch (memFactor) {
17774                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17775                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17776                    break;
17777                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17778                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17779                    break;
17780                default:
17781                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17782                    break;
17783            }
17784            int factor = numTrimming/3;
17785            int minFactor = 2;
17786            if (mHomeProcess != null) minFactor++;
17787            if (mPreviousProcess != null) minFactor++;
17788            if (factor < minFactor) factor = minFactor;
17789            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17790            for (int i=N-1; i>=0; i--) {
17791                ProcessRecord app = mLruProcesses.get(i);
17792                if (allChanged || app.procStateChanged) {
17793                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17794                    app.procStateChanged = false;
17795                }
17796                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17797                        && !app.killedByAm) {
17798                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17799                        try {
17800                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17801                                    "Trimming memory of " + app.processName
17802                                    + " to " + curLevel);
17803                            app.thread.scheduleTrimMemory(curLevel);
17804                        } catch (RemoteException e) {
17805                        }
17806                        if (false) {
17807                            // For now we won't do this; our memory trimming seems
17808                            // to be good enough at this point that destroying
17809                            // activities causes more harm than good.
17810                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17811                                    && app != mHomeProcess && app != mPreviousProcess) {
17812                                // Need to do this on its own message because the stack may not
17813                                // be in a consistent state at this point.
17814                                // For these apps we will also finish their activities
17815                                // to help them free memory.
17816                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17817                            }
17818                        }
17819                    }
17820                    app.trimMemoryLevel = curLevel;
17821                    step++;
17822                    if (step >= factor) {
17823                        step = 0;
17824                        switch (curLevel) {
17825                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17826                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17827                                break;
17828                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17829                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17830                                break;
17831                        }
17832                    }
17833                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17834                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17835                            && app.thread != null) {
17836                        try {
17837                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17838                                    "Trimming memory of heavy-weight " + app.processName
17839                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17840                            app.thread.scheduleTrimMemory(
17841                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17842                        } catch (RemoteException e) {
17843                        }
17844                    }
17845                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17846                } else {
17847                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17848                            || app.systemNoUi) && app.pendingUiClean) {
17849                        // If this application is now in the background and it
17850                        // had done UI, then give it the special trim level to
17851                        // have it free UI resources.
17852                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17853                        if (app.trimMemoryLevel < level && app.thread != null) {
17854                            try {
17855                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17856                                        "Trimming memory of bg-ui " + app.processName
17857                                        + " to " + level);
17858                                app.thread.scheduleTrimMemory(level);
17859                            } catch (RemoteException e) {
17860                            }
17861                        }
17862                        app.pendingUiClean = false;
17863                    }
17864                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17865                        try {
17866                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17867                                    "Trimming memory of fg " + app.processName
17868                                    + " to " + fgTrimLevel);
17869                            app.thread.scheduleTrimMemory(fgTrimLevel);
17870                        } catch (RemoteException e) {
17871                        }
17872                    }
17873                    app.trimMemoryLevel = fgTrimLevel;
17874                }
17875            }
17876        } else {
17877            if (mLowRamStartTime != 0) {
17878                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17879                mLowRamStartTime = 0;
17880            }
17881            for (int i=N-1; i>=0; i--) {
17882                ProcessRecord app = mLruProcesses.get(i);
17883                if (allChanged || app.procStateChanged) {
17884                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17885                    app.procStateChanged = false;
17886                }
17887                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17888                        || app.systemNoUi) && app.pendingUiClean) {
17889                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17890                            && app.thread != null) {
17891                        try {
17892                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17893                                    "Trimming memory of ui hidden " + app.processName
17894                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17895                            app.thread.scheduleTrimMemory(
17896                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17897                        } catch (RemoteException e) {
17898                        }
17899                    }
17900                    app.pendingUiClean = false;
17901                }
17902                app.trimMemoryLevel = 0;
17903            }
17904        }
17905
17906        if (mAlwaysFinishActivities) {
17907            // Need to do this on its own message because the stack may not
17908            // be in a consistent state at this point.
17909            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17910        }
17911
17912        if (allChanged) {
17913            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17914        }
17915
17916        if (mProcessStats.shouldWriteNowLocked(now)) {
17917            mHandler.post(new Runnable() {
17918                @Override public void run() {
17919                    synchronized (ActivityManagerService.this) {
17920                        mProcessStats.writeStateAsyncLocked();
17921                    }
17922                }
17923            });
17924        }
17925
17926        if (DEBUG_OOM_ADJ) {
17927            if (false) {
17928                RuntimeException here = new RuntimeException("here");
17929                here.fillInStackTrace();
17930                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
17931            } else {
17932                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17933            }
17934        }
17935    }
17936
17937    final void trimApplications() {
17938        synchronized (this) {
17939            int i;
17940
17941            // First remove any unused application processes whose package
17942            // has been removed.
17943            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17944                final ProcessRecord app = mRemovedProcesses.get(i);
17945                if (app.activities.size() == 0
17946                        && app.curReceiver == null && app.services.size() == 0) {
17947                    Slog.i(
17948                        TAG, "Exiting empty application process "
17949                        + app.processName + " ("
17950                        + (app.thread != null ? app.thread.asBinder() : null)
17951                        + ")\n");
17952                    if (app.pid > 0 && app.pid != MY_PID) {
17953                        app.kill("empty", false);
17954                    } else {
17955                        try {
17956                            app.thread.scheduleExit();
17957                        } catch (Exception e) {
17958                            // Ignore exceptions.
17959                        }
17960                    }
17961                    cleanUpApplicationRecordLocked(app, false, true, -1);
17962                    mRemovedProcesses.remove(i);
17963
17964                    if (app.persistent) {
17965                        addAppLocked(app.info, false, null /* ABI override */);
17966                    }
17967                }
17968            }
17969
17970            // Now update the oom adj for all processes.
17971            updateOomAdjLocked();
17972        }
17973    }
17974
17975    /** This method sends the specified signal to each of the persistent apps */
17976    public void signalPersistentProcesses(int sig) throws RemoteException {
17977        if (sig != Process.SIGNAL_USR1) {
17978            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17979        }
17980
17981        synchronized (this) {
17982            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17983                    != PackageManager.PERMISSION_GRANTED) {
17984                throw new SecurityException("Requires permission "
17985                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17986            }
17987
17988            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17989                ProcessRecord r = mLruProcesses.get(i);
17990                if (r.thread != null && r.persistent) {
17991                    Process.sendSignal(r.pid, sig);
17992                }
17993            }
17994        }
17995    }
17996
17997    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
17998        if (proc == null || proc == mProfileProc) {
17999            proc = mProfileProc;
18000            profileType = mProfileType;
18001            clearProfilerLocked();
18002        }
18003        if (proc == null) {
18004            return;
18005        }
18006        try {
18007            proc.thread.profilerControl(false, null, profileType);
18008        } catch (RemoteException e) {
18009            throw new IllegalStateException("Process disappeared");
18010        }
18011    }
18012
18013    private void clearProfilerLocked() {
18014        if (mProfileFd != null) {
18015            try {
18016                mProfileFd.close();
18017            } catch (IOException e) {
18018            }
18019        }
18020        mProfileApp = null;
18021        mProfileProc = null;
18022        mProfileFile = null;
18023        mProfileType = 0;
18024        mAutoStopProfiler = false;
18025        mSamplingInterval = 0;
18026    }
18027
18028    public boolean profileControl(String process, int userId, boolean start,
18029            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18030
18031        try {
18032            synchronized (this) {
18033                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18034                // its own permission.
18035                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18036                        != PackageManager.PERMISSION_GRANTED) {
18037                    throw new SecurityException("Requires permission "
18038                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18039                }
18040
18041                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18042                    throw new IllegalArgumentException("null profile info or fd");
18043                }
18044
18045                ProcessRecord proc = null;
18046                if (process != null) {
18047                    proc = findProcessLocked(process, userId, "profileControl");
18048                }
18049
18050                if (start && (proc == null || proc.thread == null)) {
18051                    throw new IllegalArgumentException("Unknown process: " + process);
18052                }
18053
18054                if (start) {
18055                    stopProfilerLocked(null, 0);
18056                    setProfileApp(proc.info, proc.processName, profilerInfo);
18057                    mProfileProc = proc;
18058                    mProfileType = profileType;
18059                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18060                    try {
18061                        fd = fd.dup();
18062                    } catch (IOException e) {
18063                        fd = null;
18064                    }
18065                    profilerInfo.profileFd = fd;
18066                    proc.thread.profilerControl(start, profilerInfo, profileType);
18067                    fd = null;
18068                    mProfileFd = null;
18069                } else {
18070                    stopProfilerLocked(proc, profileType);
18071                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18072                        try {
18073                            profilerInfo.profileFd.close();
18074                        } catch (IOException e) {
18075                        }
18076                    }
18077                }
18078
18079                return true;
18080            }
18081        } catch (RemoteException e) {
18082            throw new IllegalStateException("Process disappeared");
18083        } finally {
18084            if (profilerInfo != null && profilerInfo.profileFd != null) {
18085                try {
18086                    profilerInfo.profileFd.close();
18087                } catch (IOException e) {
18088                }
18089            }
18090        }
18091    }
18092
18093    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18094        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18095                userId, true, ALLOW_FULL_ONLY, callName, null);
18096        ProcessRecord proc = null;
18097        try {
18098            int pid = Integer.parseInt(process);
18099            synchronized (mPidsSelfLocked) {
18100                proc = mPidsSelfLocked.get(pid);
18101            }
18102        } catch (NumberFormatException e) {
18103        }
18104
18105        if (proc == null) {
18106            ArrayMap<String, SparseArray<ProcessRecord>> all
18107                    = mProcessNames.getMap();
18108            SparseArray<ProcessRecord> procs = all.get(process);
18109            if (procs != null && procs.size() > 0) {
18110                proc = procs.valueAt(0);
18111                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18112                    for (int i=1; i<procs.size(); i++) {
18113                        ProcessRecord thisProc = procs.valueAt(i);
18114                        if (thisProc.userId == userId) {
18115                            proc = thisProc;
18116                            break;
18117                        }
18118                    }
18119                }
18120            }
18121        }
18122
18123        return proc;
18124    }
18125
18126    public boolean dumpHeap(String process, int userId, boolean managed,
18127            String path, ParcelFileDescriptor fd) throws RemoteException {
18128
18129        try {
18130            synchronized (this) {
18131                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18132                // its own permission (same as profileControl).
18133                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18134                        != PackageManager.PERMISSION_GRANTED) {
18135                    throw new SecurityException("Requires permission "
18136                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18137                }
18138
18139                if (fd == null) {
18140                    throw new IllegalArgumentException("null fd");
18141                }
18142
18143                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18144                if (proc == null || proc.thread == null) {
18145                    throw new IllegalArgumentException("Unknown process: " + process);
18146                }
18147
18148                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18149                if (!isDebuggable) {
18150                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18151                        throw new SecurityException("Process not debuggable: " + proc);
18152                    }
18153                }
18154
18155                proc.thread.dumpHeap(managed, path, fd);
18156                fd = null;
18157                return true;
18158            }
18159        } catch (RemoteException e) {
18160            throw new IllegalStateException("Process disappeared");
18161        } finally {
18162            if (fd != null) {
18163                try {
18164                    fd.close();
18165                } catch (IOException e) {
18166                }
18167            }
18168        }
18169    }
18170
18171    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18172    public void monitor() {
18173        synchronized (this) { }
18174    }
18175
18176    void onCoreSettingsChange(Bundle settings) {
18177        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18178            ProcessRecord processRecord = mLruProcesses.get(i);
18179            try {
18180                if (processRecord.thread != null) {
18181                    processRecord.thread.setCoreSettings(settings);
18182                }
18183            } catch (RemoteException re) {
18184                /* ignore */
18185            }
18186        }
18187    }
18188
18189    // Multi-user methods
18190
18191    /**
18192     * Start user, if its not already running, but don't bring it to foreground.
18193     */
18194    @Override
18195    public boolean startUserInBackground(final int userId) {
18196        return startUser(userId, /* foreground */ false);
18197    }
18198
18199    /**
18200     * Start user, if its not already running, and bring it to foreground.
18201     */
18202    boolean startUserInForeground(final int userId, Dialog dlg) {
18203        boolean result = startUser(userId, /* foreground */ true);
18204        dlg.dismiss();
18205        return result;
18206    }
18207
18208    /**
18209     * Refreshes the list of users related to the current user when either a
18210     * user switch happens or when a new related user is started in the
18211     * background.
18212     */
18213    private void updateCurrentProfileIdsLocked() {
18214        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18215                mCurrentUserId, false /* enabledOnly */);
18216        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18217        for (int i = 0; i < currentProfileIds.length; i++) {
18218            currentProfileIds[i] = profiles.get(i).id;
18219        }
18220        mCurrentProfileIds = currentProfileIds;
18221
18222        synchronized (mUserProfileGroupIdsSelfLocked) {
18223            mUserProfileGroupIdsSelfLocked.clear();
18224            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18225            for (int i = 0; i < users.size(); i++) {
18226                UserInfo user = users.get(i);
18227                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18228                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18229                }
18230            }
18231        }
18232    }
18233
18234    private Set getProfileIdsLocked(int userId) {
18235        Set userIds = new HashSet<Integer>();
18236        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18237                userId, false /* enabledOnly */);
18238        for (UserInfo user : profiles) {
18239            userIds.add(Integer.valueOf(user.id));
18240        }
18241        return userIds;
18242    }
18243
18244    @Override
18245    public boolean switchUser(final int userId) {
18246        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18247        String userName;
18248        synchronized (this) {
18249            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18250            if (userInfo == null) {
18251                Slog.w(TAG, "No user info for user #" + userId);
18252                return false;
18253            }
18254            if (userInfo.isManagedProfile()) {
18255                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18256                return false;
18257            }
18258            userName = userInfo.name;
18259            mTargetUserId = userId;
18260        }
18261        mHandler.removeMessages(START_USER_SWITCH_MSG);
18262        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18263        return true;
18264    }
18265
18266    private void showUserSwitchDialog(int userId, String userName) {
18267        // The dialog will show and then initiate the user switch by calling startUserInForeground
18268        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18269                true /* above system */);
18270        d.show();
18271    }
18272
18273    private boolean startUser(final int userId, final boolean foreground) {
18274        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18275                != PackageManager.PERMISSION_GRANTED) {
18276            String msg = "Permission Denial: switchUser() from pid="
18277                    + Binder.getCallingPid()
18278                    + ", uid=" + Binder.getCallingUid()
18279                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18280            Slog.w(TAG, msg);
18281            throw new SecurityException(msg);
18282        }
18283
18284        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18285
18286        final long ident = Binder.clearCallingIdentity();
18287        try {
18288            synchronized (this) {
18289                final int oldUserId = mCurrentUserId;
18290                if (oldUserId == userId) {
18291                    return true;
18292                }
18293
18294                mStackSupervisor.setLockTaskModeLocked(null, false);
18295
18296                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18297                if (userInfo == null) {
18298                    Slog.w(TAG, "No user info for user #" + userId);
18299                    return false;
18300                }
18301                if (foreground && userInfo.isManagedProfile()) {
18302                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18303                    return false;
18304                }
18305
18306                if (foreground) {
18307                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18308                            R.anim.screen_user_enter);
18309                }
18310
18311                boolean needStart = false;
18312
18313                // If the user we are switching to is not currently started, then
18314                // we need to start it now.
18315                if (mStartedUsers.get(userId) == null) {
18316                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18317                    updateStartedUserArrayLocked();
18318                    needStart = true;
18319                }
18320
18321                final Integer userIdInt = Integer.valueOf(userId);
18322                mUserLru.remove(userIdInt);
18323                mUserLru.add(userIdInt);
18324
18325                if (foreground) {
18326                    mCurrentUserId = userId;
18327                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18328                    updateCurrentProfileIdsLocked();
18329                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18330                    // Once the internal notion of the active user has switched, we lock the device
18331                    // with the option to show the user switcher on the keyguard.
18332                    mWindowManager.lockNow(null);
18333                } else {
18334                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18335                    updateCurrentProfileIdsLocked();
18336                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18337                    mUserLru.remove(currentUserIdInt);
18338                    mUserLru.add(currentUserIdInt);
18339                }
18340
18341                final UserStartedState uss = mStartedUsers.get(userId);
18342
18343                // Make sure user is in the started state.  If it is currently
18344                // stopping, we need to knock that off.
18345                if (uss.mState == UserStartedState.STATE_STOPPING) {
18346                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18347                    // so we can just fairly silently bring the user back from
18348                    // the almost-dead.
18349                    uss.mState = UserStartedState.STATE_RUNNING;
18350                    updateStartedUserArrayLocked();
18351                    needStart = true;
18352                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18353                    // This means ACTION_SHUTDOWN has been sent, so we will
18354                    // need to treat this as a new boot of the user.
18355                    uss.mState = UserStartedState.STATE_BOOTING;
18356                    updateStartedUserArrayLocked();
18357                    needStart = true;
18358                }
18359
18360                if (uss.mState == UserStartedState.STATE_BOOTING) {
18361                    // Booting up a new user, need to tell system services about it.
18362                    // Note that this is on the same handler as scheduling of broadcasts,
18363                    // which is important because it needs to go first.
18364                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18365                }
18366
18367                if (foreground) {
18368                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18369                            oldUserId));
18370                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18371                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18372                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18373                            oldUserId, userId, uss));
18374                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18375                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18376                }
18377
18378                if (needStart) {
18379                    // Send USER_STARTED broadcast
18380                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18381                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18382                            | Intent.FLAG_RECEIVER_FOREGROUND);
18383                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18384                    broadcastIntentLocked(null, null, intent,
18385                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18386                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18387                }
18388
18389                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18390                    if (userId != UserHandle.USER_OWNER) {
18391                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18392                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18393                        broadcastIntentLocked(null, null, intent, null,
18394                                new IIntentReceiver.Stub() {
18395                                    public void performReceive(Intent intent, int resultCode,
18396                                            String data, Bundle extras, boolean ordered,
18397                                            boolean sticky, int sendingUser) {
18398                                        onUserInitialized(uss, foreground, oldUserId, userId);
18399                                    }
18400                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18401                                true, false, MY_PID, Process.SYSTEM_UID,
18402                                userId);
18403                        uss.initializing = true;
18404                    } else {
18405                        getUserManagerLocked().makeInitialized(userInfo.id);
18406                    }
18407                }
18408
18409                if (foreground) {
18410                    if (!uss.initializing) {
18411                        moveUserToForeground(uss, oldUserId, userId);
18412                    }
18413                } else {
18414                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18415                }
18416
18417                if (needStart) {
18418                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18419                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18420                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18421                    broadcastIntentLocked(null, null, intent,
18422                            null, new IIntentReceiver.Stub() {
18423                                @Override
18424                                public void performReceive(Intent intent, int resultCode, String data,
18425                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18426                                        throws RemoteException {
18427                                }
18428                            }, 0, null, null,
18429                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18430                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18431                }
18432            }
18433        } finally {
18434            Binder.restoreCallingIdentity(ident);
18435        }
18436
18437        return true;
18438    }
18439
18440    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18441        long ident = Binder.clearCallingIdentity();
18442        try {
18443            Intent intent;
18444            if (oldUserId >= 0) {
18445                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18446                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18447                int count = profiles.size();
18448                for (int i = 0; i < count; i++) {
18449                    int profileUserId = profiles.get(i).id;
18450                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18451                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18452                            | Intent.FLAG_RECEIVER_FOREGROUND);
18453                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18454                    broadcastIntentLocked(null, null, intent,
18455                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18456                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18457                }
18458            }
18459            if (newUserId >= 0) {
18460                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18461                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18462                int count = profiles.size();
18463                for (int i = 0; i < count; i++) {
18464                    int profileUserId = profiles.get(i).id;
18465                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18466                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18467                            | Intent.FLAG_RECEIVER_FOREGROUND);
18468                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18469                    broadcastIntentLocked(null, null, intent,
18470                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18471                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18472                }
18473                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18474                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18475                        | Intent.FLAG_RECEIVER_FOREGROUND);
18476                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18477                broadcastIntentLocked(null, null, intent,
18478                        null, null, 0, null, null,
18479                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18480                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18481            }
18482        } finally {
18483            Binder.restoreCallingIdentity(ident);
18484        }
18485    }
18486
18487    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18488            final int newUserId) {
18489        final int N = mUserSwitchObservers.beginBroadcast();
18490        if (N > 0) {
18491            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18492                int mCount = 0;
18493                @Override
18494                public void sendResult(Bundle data) throws RemoteException {
18495                    synchronized (ActivityManagerService.this) {
18496                        if (mCurUserSwitchCallback == this) {
18497                            mCount++;
18498                            if (mCount == N) {
18499                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18500                            }
18501                        }
18502                    }
18503                }
18504            };
18505            synchronized (this) {
18506                uss.switching = true;
18507                mCurUserSwitchCallback = callback;
18508            }
18509            for (int i=0; i<N; i++) {
18510                try {
18511                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18512                            newUserId, callback);
18513                } catch (RemoteException e) {
18514                }
18515            }
18516        } else {
18517            synchronized (this) {
18518                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18519            }
18520        }
18521        mUserSwitchObservers.finishBroadcast();
18522    }
18523
18524    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18525        synchronized (this) {
18526            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18527            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18528        }
18529    }
18530
18531    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18532        mCurUserSwitchCallback = null;
18533        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18534        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18535                oldUserId, newUserId, uss));
18536    }
18537
18538    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18539        synchronized (this) {
18540            if (foreground) {
18541                moveUserToForeground(uss, oldUserId, newUserId);
18542            }
18543        }
18544
18545        completeSwitchAndInitalize(uss, newUserId, true, false);
18546    }
18547
18548    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18549        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18550        if (homeInFront) {
18551            startHomeActivityLocked(newUserId);
18552        } else {
18553            mStackSupervisor.resumeTopActivitiesLocked();
18554        }
18555        EventLogTags.writeAmSwitchUser(newUserId);
18556        getUserManagerLocked().userForeground(newUserId);
18557        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18558    }
18559
18560    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18561        completeSwitchAndInitalize(uss, newUserId, false, true);
18562    }
18563
18564    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18565            boolean clearInitializing, boolean clearSwitching) {
18566        boolean unfrozen = false;
18567        synchronized (this) {
18568            if (clearInitializing) {
18569                uss.initializing = false;
18570                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18571            }
18572            if (clearSwitching) {
18573                uss.switching = false;
18574            }
18575            if (!uss.switching && !uss.initializing) {
18576                mWindowManager.stopFreezingScreen();
18577                unfrozen = true;
18578            }
18579        }
18580        if (unfrozen) {
18581            final int N = mUserSwitchObservers.beginBroadcast();
18582            for (int i=0; i<N; i++) {
18583                try {
18584                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18585                } catch (RemoteException e) {
18586                }
18587            }
18588            mUserSwitchObservers.finishBroadcast();
18589        }
18590    }
18591
18592    void scheduleStartProfilesLocked() {
18593        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18594            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18595                    DateUtils.SECOND_IN_MILLIS);
18596        }
18597    }
18598
18599    void startProfilesLocked() {
18600        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18601        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18602                mCurrentUserId, false /* enabledOnly */);
18603        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18604        for (UserInfo user : profiles) {
18605            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18606                    && user.id != mCurrentUserId) {
18607                toStart.add(user);
18608            }
18609        }
18610        final int n = toStart.size();
18611        int i = 0;
18612        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18613            startUserInBackground(toStart.get(i).id);
18614        }
18615        if (i < n) {
18616            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18617        }
18618    }
18619
18620    void finishUserBoot(UserStartedState uss) {
18621        synchronized (this) {
18622            if (uss.mState == UserStartedState.STATE_BOOTING
18623                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18624                uss.mState = UserStartedState.STATE_RUNNING;
18625                final int userId = uss.mHandle.getIdentifier();
18626                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18627                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18628                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18629                broadcastIntentLocked(null, null, intent,
18630                        null, null, 0, null, null,
18631                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18632                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18633            }
18634        }
18635    }
18636
18637    void finishUserSwitch(UserStartedState uss) {
18638        synchronized (this) {
18639            finishUserBoot(uss);
18640
18641            startProfilesLocked();
18642
18643            int num = mUserLru.size();
18644            int i = 0;
18645            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18646                Integer oldUserId = mUserLru.get(i);
18647                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18648                if (oldUss == null) {
18649                    // Shouldn't happen, but be sane if it does.
18650                    mUserLru.remove(i);
18651                    num--;
18652                    continue;
18653                }
18654                if (oldUss.mState == UserStartedState.STATE_STOPPING
18655                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18656                    // This user is already stopping, doesn't count.
18657                    num--;
18658                    i++;
18659                    continue;
18660                }
18661                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18662                    // Owner and current can't be stopped, but count as running.
18663                    i++;
18664                    continue;
18665                }
18666                // This is a user to be stopped.
18667                stopUserLocked(oldUserId, null);
18668                num--;
18669                i++;
18670            }
18671        }
18672    }
18673
18674    @Override
18675    public int stopUser(final int userId, final IStopUserCallback callback) {
18676        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18677                != PackageManager.PERMISSION_GRANTED) {
18678            String msg = "Permission Denial: switchUser() from pid="
18679                    + Binder.getCallingPid()
18680                    + ", uid=" + Binder.getCallingUid()
18681                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18682            Slog.w(TAG, msg);
18683            throw new SecurityException(msg);
18684        }
18685        if (userId <= 0) {
18686            throw new IllegalArgumentException("Can't stop primary user " + userId);
18687        }
18688        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18689        synchronized (this) {
18690            return stopUserLocked(userId, callback);
18691        }
18692    }
18693
18694    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18695        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18696        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18697            return ActivityManager.USER_OP_IS_CURRENT;
18698        }
18699
18700        final UserStartedState uss = mStartedUsers.get(userId);
18701        if (uss == null) {
18702            // User is not started, nothing to do...  but we do need to
18703            // callback if requested.
18704            if (callback != null) {
18705                mHandler.post(new Runnable() {
18706                    @Override
18707                    public void run() {
18708                        try {
18709                            callback.userStopped(userId);
18710                        } catch (RemoteException e) {
18711                        }
18712                    }
18713                });
18714            }
18715            return ActivityManager.USER_OP_SUCCESS;
18716        }
18717
18718        if (callback != null) {
18719            uss.mStopCallbacks.add(callback);
18720        }
18721
18722        if (uss.mState != UserStartedState.STATE_STOPPING
18723                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18724            uss.mState = UserStartedState.STATE_STOPPING;
18725            updateStartedUserArrayLocked();
18726
18727            long ident = Binder.clearCallingIdentity();
18728            try {
18729                // We are going to broadcast ACTION_USER_STOPPING and then
18730                // once that is done send a final ACTION_SHUTDOWN and then
18731                // stop the user.
18732                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18733                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18734                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18735                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18736                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18737                // This is the result receiver for the final shutdown broadcast.
18738                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18739                    @Override
18740                    public void performReceive(Intent intent, int resultCode, String data,
18741                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18742                        finishUserStop(uss);
18743                    }
18744                };
18745                // This is the result receiver for the initial stopping broadcast.
18746                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18747                    @Override
18748                    public void performReceive(Intent intent, int resultCode, String data,
18749                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18750                        // On to the next.
18751                        synchronized (ActivityManagerService.this) {
18752                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18753                                // Whoops, we are being started back up.  Abort, abort!
18754                                return;
18755                            }
18756                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18757                        }
18758                        mBatteryStatsService.noteEvent(
18759                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18760                                Integer.toString(userId), userId);
18761                        mSystemServiceManager.stopUser(userId);
18762                        broadcastIntentLocked(null, null, shutdownIntent,
18763                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18764                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18765                    }
18766                };
18767                // Kick things off.
18768                broadcastIntentLocked(null, null, stoppingIntent,
18769                        null, stoppingReceiver, 0, null, null,
18770                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18771                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18772            } finally {
18773                Binder.restoreCallingIdentity(ident);
18774            }
18775        }
18776
18777        return ActivityManager.USER_OP_SUCCESS;
18778    }
18779
18780    void finishUserStop(UserStartedState uss) {
18781        final int userId = uss.mHandle.getIdentifier();
18782        boolean stopped;
18783        ArrayList<IStopUserCallback> callbacks;
18784        synchronized (this) {
18785            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18786            if (mStartedUsers.get(userId) != uss) {
18787                stopped = false;
18788            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18789                stopped = false;
18790            } else {
18791                stopped = true;
18792                // User can no longer run.
18793                mStartedUsers.remove(userId);
18794                mUserLru.remove(Integer.valueOf(userId));
18795                updateStartedUserArrayLocked();
18796
18797                // Clean up all state and processes associated with the user.
18798                // Kill all the processes for the user.
18799                forceStopUserLocked(userId, "finish user");
18800            }
18801
18802            // Explicitly remove the old information in mRecentTasks.
18803            removeRecentTasksForUserLocked(userId);
18804        }
18805
18806        for (int i=0; i<callbacks.size(); i++) {
18807            try {
18808                if (stopped) callbacks.get(i).userStopped(userId);
18809                else callbacks.get(i).userStopAborted(userId);
18810            } catch (RemoteException e) {
18811            }
18812        }
18813
18814        if (stopped) {
18815            mSystemServiceManager.cleanupUser(userId);
18816            synchronized (this) {
18817                mStackSupervisor.removeUserLocked(userId);
18818            }
18819        }
18820    }
18821
18822    @Override
18823    public UserInfo getCurrentUser() {
18824        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18825                != PackageManager.PERMISSION_GRANTED) && (
18826                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18827                != PackageManager.PERMISSION_GRANTED)) {
18828            String msg = "Permission Denial: getCurrentUser() from pid="
18829                    + Binder.getCallingPid()
18830                    + ", uid=" + Binder.getCallingUid()
18831                    + " requires " + INTERACT_ACROSS_USERS;
18832            Slog.w(TAG, msg);
18833            throw new SecurityException(msg);
18834        }
18835        synchronized (this) {
18836            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18837            return getUserManagerLocked().getUserInfo(userId);
18838        }
18839    }
18840
18841    int getCurrentUserIdLocked() {
18842        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18843    }
18844
18845    @Override
18846    public boolean isUserRunning(int userId, boolean orStopped) {
18847        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18848                != PackageManager.PERMISSION_GRANTED) {
18849            String msg = "Permission Denial: isUserRunning() from pid="
18850                    + Binder.getCallingPid()
18851                    + ", uid=" + Binder.getCallingUid()
18852                    + " requires " + INTERACT_ACROSS_USERS;
18853            Slog.w(TAG, msg);
18854            throw new SecurityException(msg);
18855        }
18856        synchronized (this) {
18857            return isUserRunningLocked(userId, orStopped);
18858        }
18859    }
18860
18861    boolean isUserRunningLocked(int userId, boolean orStopped) {
18862        UserStartedState state = mStartedUsers.get(userId);
18863        if (state == null) {
18864            return false;
18865        }
18866        if (orStopped) {
18867            return true;
18868        }
18869        return state.mState != UserStartedState.STATE_STOPPING
18870                && state.mState != UserStartedState.STATE_SHUTDOWN;
18871    }
18872
18873    @Override
18874    public int[] getRunningUserIds() {
18875        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18876                != PackageManager.PERMISSION_GRANTED) {
18877            String msg = "Permission Denial: isUserRunning() from pid="
18878                    + Binder.getCallingPid()
18879                    + ", uid=" + Binder.getCallingUid()
18880                    + " requires " + INTERACT_ACROSS_USERS;
18881            Slog.w(TAG, msg);
18882            throw new SecurityException(msg);
18883        }
18884        synchronized (this) {
18885            return mStartedUserArray;
18886        }
18887    }
18888
18889    private void updateStartedUserArrayLocked() {
18890        int num = 0;
18891        for (int i=0; i<mStartedUsers.size();  i++) {
18892            UserStartedState uss = mStartedUsers.valueAt(i);
18893            // This list does not include stopping users.
18894            if (uss.mState != UserStartedState.STATE_STOPPING
18895                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18896                num++;
18897            }
18898        }
18899        mStartedUserArray = new int[num];
18900        num = 0;
18901        for (int i=0; i<mStartedUsers.size();  i++) {
18902            UserStartedState uss = mStartedUsers.valueAt(i);
18903            if (uss.mState != UserStartedState.STATE_STOPPING
18904                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18905                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18906                num++;
18907            }
18908        }
18909    }
18910
18911    @Override
18912    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18913        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18914                != PackageManager.PERMISSION_GRANTED) {
18915            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18916                    + Binder.getCallingPid()
18917                    + ", uid=" + Binder.getCallingUid()
18918                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18919            Slog.w(TAG, msg);
18920            throw new SecurityException(msg);
18921        }
18922
18923        mUserSwitchObservers.register(observer);
18924    }
18925
18926    @Override
18927    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18928        mUserSwitchObservers.unregister(observer);
18929    }
18930
18931    private boolean userExists(int userId) {
18932        if (userId == 0) {
18933            return true;
18934        }
18935        UserManagerService ums = getUserManagerLocked();
18936        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18937    }
18938
18939    int[] getUsersLocked() {
18940        UserManagerService ums = getUserManagerLocked();
18941        return ums != null ? ums.getUserIds() : new int[] { 0 };
18942    }
18943
18944    UserManagerService getUserManagerLocked() {
18945        if (mUserManager == null) {
18946            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
18947            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
18948        }
18949        return mUserManager;
18950    }
18951
18952    private int applyUserId(int uid, int userId) {
18953        return UserHandle.getUid(userId, uid);
18954    }
18955
18956    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18957        if (info == null) return null;
18958        ApplicationInfo newInfo = new ApplicationInfo(info);
18959        newInfo.uid = applyUserId(info.uid, userId);
18960        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18961                + info.packageName;
18962        return newInfo;
18963    }
18964
18965    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18966        if (aInfo == null
18967                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18968            return aInfo;
18969        }
18970
18971        ActivityInfo info = new ActivityInfo(aInfo);
18972        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18973        return info;
18974    }
18975
18976    private final class LocalService extends ActivityManagerInternal {
18977        @Override
18978        public void goingToSleep() {
18979            ActivityManagerService.this.goingToSleep();
18980        }
18981
18982        @Override
18983        public void wakingUp() {
18984            ActivityManagerService.this.wakingUp();
18985        }
18986
18987        @Override
18988        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18989                String processName, String abiOverride, int uid, Runnable crashHandler) {
18990            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18991                    processName, abiOverride, uid, crashHandler);
18992        }
18993    }
18994
18995    /**
18996     * An implementation of IAppTask, that allows an app to manage its own tasks via
18997     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18998     * only the process that calls getAppTasks() can call the AppTask methods.
18999     */
19000    class AppTaskImpl extends IAppTask.Stub {
19001        private int mTaskId;
19002        private int mCallingUid;
19003
19004        public AppTaskImpl(int taskId, int callingUid) {
19005            mTaskId = taskId;
19006            mCallingUid = callingUid;
19007        }
19008
19009        private void checkCaller() {
19010            if (mCallingUid != Binder.getCallingUid()) {
19011                throw new SecurityException("Caller " + mCallingUid
19012                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19013            }
19014        }
19015
19016        @Override
19017        public void finishAndRemoveTask() {
19018            checkCaller();
19019
19020            synchronized (ActivityManagerService.this) {
19021                long origId = Binder.clearCallingIdentity();
19022                try {
19023                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19024                    if (tr == null) {
19025                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19026                    }
19027                    // Only kill the process if we are not a new document
19028                    int flags = tr.getBaseIntent().getFlags();
19029                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
19030                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
19031                    removeTaskByIdLocked(mTaskId,
19032                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
19033                } finally {
19034                    Binder.restoreCallingIdentity(origId);
19035                }
19036            }
19037        }
19038
19039        @Override
19040        public ActivityManager.RecentTaskInfo getTaskInfo() {
19041            checkCaller();
19042
19043            synchronized (ActivityManagerService.this) {
19044                long origId = Binder.clearCallingIdentity();
19045                try {
19046                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19047                    if (tr == null) {
19048                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19049                    }
19050                    return createRecentTaskInfoFromTaskRecord(tr);
19051                } finally {
19052                    Binder.restoreCallingIdentity(origId);
19053                }
19054            }
19055        }
19056
19057        @Override
19058        public void moveToFront() {
19059            checkCaller();
19060
19061            final TaskRecord tr;
19062            synchronized (ActivityManagerService.this) {
19063                tr = recentTaskForIdLocked(mTaskId);
19064                if (tr == null) {
19065                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19066                }
19067                if (tr.getRootActivity() != null) {
19068                    moveTaskToFrontLocked(tr.taskId, 0, null);
19069                    return;
19070                }
19071            }
19072
19073            startActivityFromRecentsInner(tr.taskId, null);
19074        }
19075
19076        @Override
19077        public int startActivity(IBinder whoThread, String callingPackage,
19078                Intent intent, String resolvedType, Bundle options) {
19079            checkCaller();
19080
19081            int callingUser = UserHandle.getCallingUserId();
19082            TaskRecord tr;
19083            IApplicationThread appThread;
19084            synchronized (ActivityManagerService.this) {
19085                tr = recentTaskForIdLocked(mTaskId);
19086                if (tr == null) {
19087                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19088                }
19089                appThread = ApplicationThreadNative.asInterface(whoThread);
19090                if (appThread == null) {
19091                    throw new IllegalArgumentException("Bad app thread " + appThread);
19092                }
19093            }
19094            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19095                    resolvedType, null, null, null, null, 0, 0, null, null,
19096                    null, options, callingUser, null, tr);
19097        }
19098
19099        @Override
19100        public void setExcludeFromRecents(boolean exclude) {
19101            checkCaller();
19102
19103            synchronized (ActivityManagerService.this) {
19104                long origId = Binder.clearCallingIdentity();
19105                try {
19106                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19107                    if (tr == null) {
19108                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19109                    }
19110                    Intent intent = tr.getBaseIntent();
19111                    if (exclude) {
19112                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19113                    } else {
19114                        intent.setFlags(intent.getFlags()
19115                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19116                    }
19117                } finally {
19118                    Binder.restoreCallingIdentity(origId);
19119                }
19120            }
19121        }
19122    }
19123}
19124