ActivityManagerService.java revision a11bb7427171418681428754051d5ee4dce851ee
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 final Bundle extras;
438        public final Intent intent;
439        public final String hint;
440        public final int userHandle;
441        public boolean haveResult = false;
442        public Bundle result = null;
443        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
444                String _hint, int _userHandle) {
445            activity = _activity;
446            extras = _extras;
447            intent = _intent;
448            hint = _hint;
449            userHandle = _userHandle;
450        }
451        @Override
452        public void run() {
453            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
454            synchronized (this) {
455                haveResult = true;
456                notifyAll();
457            }
458        }
459    }
460
461    final ArrayList<PendingAssistExtras> mPendingAssistExtras
462            = new ArrayList<PendingAssistExtras>();
463
464    /**
465     * Process management.
466     */
467    final ProcessList mProcessList = new ProcessList();
468
469    /**
470     * All of the applications we currently have running organized by name.
471     * The keys are strings of the application package name (as
472     * returned by the package manager), and the keys are ApplicationRecord
473     * objects.
474     */
475    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
476
477    /**
478     * Tracking long-term execution of processes to look for abuse and other
479     * bad app behavior.
480     */
481    final ProcessStatsService mProcessStats;
482
483    /**
484     * The currently running isolated processes.
485     */
486    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
487
488    /**
489     * Counter for assigning isolated process uids, to avoid frequently reusing the
490     * same ones.
491     */
492    int mNextIsolatedProcessUid = 0;
493
494    /**
495     * The currently running heavy-weight process, if any.
496     */
497    ProcessRecord mHeavyWeightProcess = null;
498
499    /**
500     * The last time that various processes have crashed.
501     */
502    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
503
504    /**
505     * Information about a process that is currently marked as bad.
506     */
507    static final class BadProcessInfo {
508        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
509            this.time = time;
510            this.shortMsg = shortMsg;
511            this.longMsg = longMsg;
512            this.stack = stack;
513        }
514
515        final long time;
516        final String shortMsg;
517        final String longMsg;
518        final String stack;
519    }
520
521    /**
522     * Set of applications that we consider to be bad, and will reject
523     * incoming broadcasts from (which the user has no control over).
524     * Processes are added to this set when they have crashed twice within
525     * a minimum amount of time; they are removed from it when they are
526     * later restarted (hopefully due to some user action).  The value is the
527     * time it was added to the list.
528     */
529    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
530
531    /**
532     * All of the processes we currently have running organized by pid.
533     * The keys are the pid running the application.
534     *
535     * <p>NOTE: This object is protected by its own lock, NOT the global
536     * activity manager lock!
537     */
538    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
539
540    /**
541     * All of the processes that have been forced to be foreground.  The key
542     * is the pid of the caller who requested it (we hold a death
543     * link on it).
544     */
545    abstract class ForegroundToken implements IBinder.DeathRecipient {
546        int pid;
547        IBinder token;
548    }
549    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
550
551    /**
552     * List of records for processes that someone had tried to start before the
553     * system was ready.  We don't start them at that point, but ensure they
554     * are started by the time booting is complete.
555     */
556    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
557
558    /**
559     * List of persistent applications that are in the process
560     * of being started.
561     */
562    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
563
564    /**
565     * Processes that are being forcibly torn down.
566     */
567    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
568
569    /**
570     * List of running applications, sorted by recent usage.
571     * The first entry in the list is the least recently used.
572     */
573    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
574
575    /**
576     * Where in mLruProcesses that the processes hosting activities start.
577     */
578    int mLruProcessActivityStart = 0;
579
580    /**
581     * Where in mLruProcesses that the processes hosting services start.
582     * This is after (lower index) than mLruProcessesActivityStart.
583     */
584    int mLruProcessServiceStart = 0;
585
586    /**
587     * List of processes that should gc as soon as things are idle.
588     */
589    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
590
591    /**
592     * Processes we want to collect PSS data from.
593     */
594    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
595
596    /**
597     * Last time we requested PSS data of all processes.
598     */
599    long mLastFullPssTime = SystemClock.uptimeMillis();
600
601    /**
602     * If set, the next time we collect PSS data we should do a full collection
603     * with data from native processes and the kernel.
604     */
605    boolean mFullPssPending = false;
606
607    /**
608     * This is the process holding what we currently consider to be
609     * the "home" activity.
610     */
611    ProcessRecord mHomeProcess;
612
613    /**
614     * This is the process holding the activity the user last visited that
615     * is in a different process from the one they are currently in.
616     */
617    ProcessRecord mPreviousProcess;
618
619    /**
620     * The time at which the previous process was last visible.
621     */
622    long mPreviousProcessVisibleTime;
623
624    /**
625     * Which uses have been started, so are allowed to run code.
626     */
627    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
628
629    /**
630     * LRU list of history of current users.  Most recently current is at the end.
631     */
632    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
633
634    /**
635     * Constant array of the users that are currently started.
636     */
637    int[] mStartedUserArray = new int[] { 0 };
638
639    /**
640     * Registered observers of the user switching mechanics.
641     */
642    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
643            = new RemoteCallbackList<IUserSwitchObserver>();
644
645    /**
646     * Currently active user switch.
647     */
648    Object mCurUserSwitchCallback;
649
650    /**
651     * Packages that the user has asked to have run in screen size
652     * compatibility mode instead of filling the screen.
653     */
654    final CompatModePackages mCompatModePackages;
655
656    /**
657     * Set of IntentSenderRecord objects that are currently active.
658     */
659    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
660            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
661
662    /**
663     * Fingerprints (hashCode()) of stack traces that we've
664     * already logged DropBox entries for.  Guarded by itself.  If
665     * something (rogue user app) forces this over
666     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
667     */
668    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
669    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
670
671    /**
672     * Strict Mode background batched logging state.
673     *
674     * The string buffer is guarded by itself, and its lock is also
675     * used to determine if another batched write is already
676     * in-flight.
677     */
678    private final StringBuilder mStrictModeBuffer = new StringBuilder();
679
680    /**
681     * Keeps track of all IIntentReceivers that have been registered for
682     * broadcasts.  Hash keys are the receiver IBinder, hash value is
683     * a ReceiverList.
684     */
685    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
686            new HashMap<IBinder, ReceiverList>();
687
688    /**
689     * Resolver for broadcast intents to registered receivers.
690     * Holds BroadcastFilter (subclass of IntentFilter).
691     */
692    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
693            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
694        @Override
695        protected boolean allowFilterResult(
696                BroadcastFilter filter, List<BroadcastFilter> dest) {
697            IBinder target = filter.receiverList.receiver.asBinder();
698            for (int i=dest.size()-1; i>=0; i--) {
699                if (dest.get(i).receiverList.receiver.asBinder() == target) {
700                    return false;
701                }
702            }
703            return true;
704        }
705
706        @Override
707        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
708            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
709                    || userId == filter.owningUserId) {
710                return super.newResult(filter, match, userId);
711            }
712            return null;
713        }
714
715        @Override
716        protected BroadcastFilter[] newArray(int size) {
717            return new BroadcastFilter[size];
718        }
719
720        @Override
721        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
722            return packageName.equals(filter.packageName);
723        }
724    };
725
726    /**
727     * State of all active sticky broadcasts per user.  Keys are the action of the
728     * sticky Intent, values are an ArrayList of all broadcasted intents with
729     * that action (which should usually be one).  The SparseArray is keyed
730     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
731     * for stickies that are sent to all users.
732     */
733    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
734            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
735
736    final ActiveServices mServices;
737
738    /**
739     * Backup/restore process management
740     */
741    String mBackupAppName = null;
742    BackupRecord mBackupTarget = null;
743
744    final ProviderMap mProviderMap;
745
746    /**
747     * List of content providers who have clients waiting for them.  The
748     * application is currently being launched and the provider will be
749     * removed from this list once it is published.
750     */
751    final ArrayList<ContentProviderRecord> mLaunchingProviders
752            = new ArrayList<ContentProviderRecord>();
753
754    /**
755     * File storing persisted {@link #mGrantedUriPermissions}.
756     */
757    private final AtomicFile mGrantFile;
758
759    /** XML constants used in {@link #mGrantFile} */
760    private static final String TAG_URI_GRANTS = "uri-grants";
761    private static final String TAG_URI_GRANT = "uri-grant";
762    private static final String ATTR_USER_HANDLE = "userHandle";
763    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
764    private static final String ATTR_TARGET_USER_ID = "targetUserId";
765    private static final String ATTR_SOURCE_PKG = "sourcePkg";
766    private static final String ATTR_TARGET_PKG = "targetPkg";
767    private static final String ATTR_URI = "uri";
768    private static final String ATTR_MODE_FLAGS = "modeFlags";
769    private static final String ATTR_CREATED_TIME = "createdTime";
770    private static final String ATTR_PREFIX = "prefix";
771
772    /**
773     * Global set of specific {@link Uri} permissions that have been granted.
774     * This optimized lookup structure maps from {@link UriPermission#targetUid}
775     * to {@link UriPermission#uri} to {@link UriPermission}.
776     */
777    @GuardedBy("this")
778    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
779            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
780
781    public static class GrantUri {
782        public final int sourceUserId;
783        public final Uri uri;
784        public boolean prefix;
785
786        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
787            this.sourceUserId = sourceUserId;
788            this.uri = uri;
789            this.prefix = prefix;
790        }
791
792        @Override
793        public int hashCode() {
794            return toString().hashCode();
795        }
796
797        @Override
798        public boolean equals(Object o) {
799            if (o instanceof GrantUri) {
800                GrantUri other = (GrantUri) o;
801                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
802                        && prefix == other.prefix;
803            }
804            return false;
805        }
806
807        @Override
808        public String toString() {
809            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
810            if (prefix) result += " [prefix]";
811            return result;
812        }
813
814        public String toSafeString() {
815            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
816            if (prefix) result += " [prefix]";
817            return result;
818        }
819
820        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
821            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
822                    ContentProvider.getUriWithoutUserId(uri), false);
823        }
824    }
825
826    CoreSettingsObserver mCoreSettingsObserver;
827
828    /**
829     * Thread-local storage used to carry caller permissions over through
830     * indirect content-provider access.
831     */
832    private class Identity {
833        public int pid;
834        public int uid;
835
836        Identity(int _pid, int _uid) {
837            pid = _pid;
838            uid = _uid;
839        }
840    }
841
842    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
843
844    /**
845     * All information we have collected about the runtime performance of
846     * any user id that can impact battery performance.
847     */
848    final BatteryStatsService mBatteryStatsService;
849
850    /**
851     * Information about component usage
852     */
853    UsageStatsManagerInternal mUsageStatsService;
854
855    /**
856     * Information about and control over application operations
857     */
858    final AppOpsService mAppOpsService;
859
860    /**
861     * Save recent tasks information across reboots.
862     */
863    final TaskPersister mTaskPersister;
864
865    /**
866     * Current configuration information.  HistoryRecord objects are given
867     * a reference to this object to indicate which configuration they are
868     * currently running in, so this object must be kept immutable.
869     */
870    Configuration mConfiguration = new Configuration();
871
872    /**
873     * Current sequencing integer of the configuration, for skipping old
874     * configurations.
875     */
876    int mConfigurationSeq = 0;
877
878    /**
879     * Hardware-reported OpenGLES version.
880     */
881    final int GL_ES_VERSION;
882
883    /**
884     * List of initialization arguments to pass to all processes when binding applications to them.
885     * For example, references to the commonly used services.
886     */
887    HashMap<String, IBinder> mAppBindArgs;
888
889    /**
890     * Temporary to avoid allocations.  Protected by main lock.
891     */
892    final StringBuilder mStringBuilder = new StringBuilder(256);
893
894    /**
895     * Used to control how we initialize the service.
896     */
897    ComponentName mTopComponent;
898    String mTopAction = Intent.ACTION_MAIN;
899    String mTopData;
900    boolean mProcessesReady = false;
901    boolean mSystemReady = false;
902    boolean mBooting = false;
903    boolean mCallFinishBooting = false;
904    boolean mBootAnimationComplete = false;
905    boolean mWaitingUpdate = false;
906    boolean mDidUpdate = false;
907    boolean mOnBattery = false;
908    boolean mLaunchWarningShown = false;
909
910    Context mContext;
911
912    int mFactoryTest;
913
914    boolean mCheckedForSetup;
915
916    /**
917     * The time at which we will allow normal application switches again,
918     * after a call to {@link #stopAppSwitches()}.
919     */
920    long mAppSwitchesAllowedTime;
921
922    /**
923     * This is set to true after the first switch after mAppSwitchesAllowedTime
924     * is set; any switches after that will clear the time.
925     */
926    boolean mDidAppSwitch;
927
928    /**
929     * Last time (in realtime) at which we checked for power usage.
930     */
931    long mLastPowerCheckRealtime;
932
933    /**
934     * Last time (in uptime) at which we checked for power usage.
935     */
936    long mLastPowerCheckUptime;
937
938    /**
939     * Set while we are wanting to sleep, to prevent any
940     * activities from being started/resumed.
941     */
942    private boolean mSleeping = false;
943
944    /**
945     * Set while we are running a voice interaction.  This overrides
946     * sleeping while it is active.
947     */
948    private boolean mRunningVoice = false;
949
950    /**
951     * State of external calls telling us if the device is asleep.
952     */
953    private boolean mWentToSleep = false;
954
955    static final int LOCK_SCREEN_HIDDEN = 0;
956    static final int LOCK_SCREEN_LEAVING = 1;
957    static final int LOCK_SCREEN_SHOWN = 2;
958    /**
959     * State of external call telling us if the lock screen is shown.
960     */
961    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
962
963    /**
964     * Set if we are shutting down the system, similar to sleeping.
965     */
966    boolean mShuttingDown = false;
967
968    /**
969     * Current sequence id for oom_adj computation traversal.
970     */
971    int mAdjSeq = 0;
972
973    /**
974     * Current sequence id for process LRU updating.
975     */
976    int mLruSeq = 0;
977
978    /**
979     * Keep track of the non-cached/empty process we last found, to help
980     * determine how to distribute cached/empty processes next time.
981     */
982    int mNumNonCachedProcs = 0;
983
984    /**
985     * Keep track of the number of cached hidden procs, to balance oom adj
986     * distribution between those and empty procs.
987     */
988    int mNumCachedHiddenProcs = 0;
989
990    /**
991     * Keep track of the number of service processes we last found, to
992     * determine on the next iteration which should be B services.
993     */
994    int mNumServiceProcs = 0;
995    int mNewNumAServiceProcs = 0;
996    int mNewNumServiceProcs = 0;
997
998    /**
999     * Allow the current computed overall memory level of the system to go down?
1000     * This is set to false when we are killing processes for reasons other than
1001     * memory management, so that the now smaller process list will not be taken as
1002     * an indication that memory is tighter.
1003     */
1004    boolean mAllowLowerMemLevel = false;
1005
1006    /**
1007     * The last computed memory level, for holding when we are in a state that
1008     * processes are going away for other reasons.
1009     */
1010    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1011
1012    /**
1013     * The last total number of process we have, to determine if changes actually look
1014     * like a shrinking number of process due to lower RAM.
1015     */
1016    int mLastNumProcesses;
1017
1018    /**
1019     * The uptime of the last time we performed idle maintenance.
1020     */
1021    long mLastIdleTime = SystemClock.uptimeMillis();
1022
1023    /**
1024     * Total time spent with RAM that has been added in the past since the last idle time.
1025     */
1026    long mLowRamTimeSinceLastIdle = 0;
1027
1028    /**
1029     * If RAM is currently low, when that horrible situation started.
1030     */
1031    long mLowRamStartTime = 0;
1032
1033    /**
1034     * For reporting to battery stats the current top application.
1035     */
1036    private String mCurResumedPackage = null;
1037    private int mCurResumedUid = -1;
1038
1039    /**
1040     * For reporting to battery stats the apps currently running foreground
1041     * service.  The ProcessMap is package/uid tuples; each of these contain
1042     * an array of the currently foreground processes.
1043     */
1044    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1045            = new ProcessMap<ArrayList<ProcessRecord>>();
1046
1047    /**
1048     * This is set if we had to do a delayed dexopt of an app before launching
1049     * it, to increase the ANR timeouts in that case.
1050     */
1051    boolean mDidDexOpt;
1052
1053    /**
1054     * Set if the systemServer made a call to enterSafeMode.
1055     */
1056    boolean mSafeMode;
1057
1058    String mDebugApp = null;
1059    boolean mWaitForDebugger = false;
1060    boolean mDebugTransient = false;
1061    String mOrigDebugApp = null;
1062    boolean mOrigWaitForDebugger = false;
1063    boolean mAlwaysFinishActivities = false;
1064    IActivityController mController = null;
1065    String mProfileApp = null;
1066    ProcessRecord mProfileProc = null;
1067    String mProfileFile;
1068    ParcelFileDescriptor mProfileFd;
1069    int mSamplingInterval = 0;
1070    boolean mAutoStopProfiler = false;
1071    int mProfileType = 0;
1072    String mOpenGlTraceApp = null;
1073
1074    static class ProcessChangeItem {
1075        static final int CHANGE_ACTIVITIES = 1<<0;
1076        static final int CHANGE_PROCESS_STATE = 1<<1;
1077        int changes;
1078        int uid;
1079        int pid;
1080        int processState;
1081        boolean foregroundActivities;
1082    }
1083
1084    final RemoteCallbackList<IProcessObserver> mProcessObservers
1085            = new RemoteCallbackList<IProcessObserver>();
1086    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1087
1088    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1089            = new ArrayList<ProcessChangeItem>();
1090    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1091            = new ArrayList<ProcessChangeItem>();
1092
1093    /**
1094     * Runtime CPU use collection thread.  This object's lock is used to
1095     * perform synchronization with the thread (notifying it to run).
1096     */
1097    final Thread mProcessCpuThread;
1098
1099    /**
1100     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1101     * Must acquire this object's lock when accessing it.
1102     * NOTE: this lock will be held while doing long operations (trawling
1103     * through all processes in /proc), so it should never be acquired by
1104     * any critical paths such as when holding the main activity manager lock.
1105     */
1106    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1107            MONITOR_THREAD_CPU_USAGE);
1108    final AtomicLong mLastCpuTime = new AtomicLong(0);
1109    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1110
1111    long mLastWriteTime = 0;
1112
1113    /**
1114     * Used to retain an update lock when the foreground activity is in
1115     * immersive mode.
1116     */
1117    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1118
1119    /**
1120     * Set to true after the system has finished booting.
1121     */
1122    boolean mBooted = false;
1123
1124    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1125    int mProcessLimitOverride = -1;
1126
1127    WindowManagerService mWindowManager;
1128
1129    final ActivityThread mSystemThread;
1130
1131    // Holds the current foreground user's id
1132    int mCurrentUserId = 0;
1133    // Holds the target user's id during a user switch
1134    int mTargetUserId = UserHandle.USER_NULL;
1135    // If there are multiple profiles for the current user, their ids are here
1136    // Currently only the primary user can have managed profiles
1137    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1138
1139    /**
1140     * Mapping from each known user ID to the profile group ID it is associated with.
1141     */
1142    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1143
1144    private UserManagerService mUserManager;
1145
1146    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1147        final ProcessRecord mApp;
1148        final int mPid;
1149        final IApplicationThread mAppThread;
1150
1151        AppDeathRecipient(ProcessRecord app, int pid,
1152                IApplicationThread thread) {
1153            if (localLOGV) Slog.v(
1154                TAG, "New death recipient " + this
1155                + " for thread " + thread.asBinder());
1156            mApp = app;
1157            mPid = pid;
1158            mAppThread = thread;
1159        }
1160
1161        @Override
1162        public void binderDied() {
1163            if (localLOGV) Slog.v(
1164                TAG, "Death received in " + this
1165                + " for thread " + mAppThread.asBinder());
1166            synchronized(ActivityManagerService.this) {
1167                appDiedLocked(mApp, mPid, mAppThread);
1168            }
1169        }
1170    }
1171
1172    static final int SHOW_ERROR_MSG = 1;
1173    static final int SHOW_NOT_RESPONDING_MSG = 2;
1174    static final int SHOW_FACTORY_ERROR_MSG = 3;
1175    static final int UPDATE_CONFIGURATION_MSG = 4;
1176    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1177    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1178    static final int SERVICE_TIMEOUT_MSG = 12;
1179    static final int UPDATE_TIME_ZONE = 13;
1180    static final int SHOW_UID_ERROR_MSG = 14;
1181    static final int IM_FEELING_LUCKY_MSG = 15;
1182    static final int PROC_START_TIMEOUT_MSG = 20;
1183    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1184    static final int KILL_APPLICATION_MSG = 22;
1185    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1186    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1187    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1188    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1189    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1190    static final int CLEAR_DNS_CACHE_MSG = 28;
1191    static final int UPDATE_HTTP_PROXY_MSG = 29;
1192    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1193    static final int DISPATCH_PROCESSES_CHANGED = 31;
1194    static final int DISPATCH_PROCESS_DIED = 32;
1195    static final int REPORT_MEM_USAGE_MSG = 33;
1196    static final int REPORT_USER_SWITCH_MSG = 34;
1197    static final int CONTINUE_USER_SWITCH_MSG = 35;
1198    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1199    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1200    static final int PERSIST_URI_GRANTS_MSG = 38;
1201    static final int REQUEST_ALL_PSS_MSG = 39;
1202    static final int START_PROFILES_MSG = 40;
1203    static final int UPDATE_TIME = 41;
1204    static final int SYSTEM_USER_START_MSG = 42;
1205    static final int SYSTEM_USER_CURRENT_MSG = 43;
1206    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1207    static final int FINISH_BOOTING_MSG = 45;
1208    static final int START_USER_SWITCH_MSG = 46;
1209    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1210
1211    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1212    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1213    static final int FIRST_COMPAT_MODE_MSG = 300;
1214    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1215
1216    AlertDialog mUidAlert;
1217    CompatModeDialog mCompatModeDialog;
1218    long mLastMemUsageReportTime = 0;
1219
1220    private LockToAppRequestDialog mLockToAppRequest;
1221
1222    /**
1223     * Flag whether the current user is a "monkey", i.e. whether
1224     * the UI is driven by a UI automation tool.
1225     */
1226    private boolean mUserIsMonkey;
1227
1228    /** Flag whether the device has a Recents UI */
1229    boolean mHasRecents;
1230
1231    /** The dimensions of the thumbnails in the Recents UI. */
1232    int mThumbnailWidth;
1233    int mThumbnailHeight;
1234
1235    final ServiceThread mHandlerThread;
1236    final MainHandler mHandler;
1237
1238    final class MainHandler extends Handler {
1239        public MainHandler(Looper looper) {
1240            super(looper, null, true);
1241        }
1242
1243        @Override
1244        public void handleMessage(Message msg) {
1245            switch (msg.what) {
1246            case SHOW_ERROR_MSG: {
1247                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1248                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1249                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1250                synchronized (ActivityManagerService.this) {
1251                    ProcessRecord proc = (ProcessRecord)data.get("app");
1252                    AppErrorResult res = (AppErrorResult) data.get("result");
1253                    if (proc != null && proc.crashDialog != null) {
1254                        Slog.e(TAG, "App already has crash dialog: " + proc);
1255                        if (res != null) {
1256                            res.set(0);
1257                        }
1258                        return;
1259                    }
1260                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1261                            >= Process.FIRST_APPLICATION_UID
1262                            && proc.pid != MY_PID);
1263                    for (int userId : mCurrentProfileIds) {
1264                        isBackground &= (proc.userId != userId);
1265                    }
1266                    if (isBackground && !showBackground) {
1267                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1268                        if (res != null) {
1269                            res.set(0);
1270                        }
1271                        return;
1272                    }
1273                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1274                        Dialog d = new AppErrorDialog(mContext,
1275                                ActivityManagerService.this, res, proc);
1276                        d.show();
1277                        proc.crashDialog = d;
1278                    } else {
1279                        // The device is asleep, so just pretend that the user
1280                        // saw a crash dialog and hit "force quit".
1281                        if (res != null) {
1282                            res.set(0);
1283                        }
1284                    }
1285                }
1286
1287                ensureBootCompleted();
1288            } break;
1289            case SHOW_NOT_RESPONDING_MSG: {
1290                synchronized (ActivityManagerService.this) {
1291                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1292                    ProcessRecord proc = (ProcessRecord)data.get("app");
1293                    if (proc != null && proc.anrDialog != null) {
1294                        Slog.e(TAG, "App already has anr dialog: " + proc);
1295                        return;
1296                    }
1297
1298                    Intent intent = new Intent("android.intent.action.ANR");
1299                    if (!mProcessesReady) {
1300                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1301                                | Intent.FLAG_RECEIVER_FOREGROUND);
1302                    }
1303                    broadcastIntentLocked(null, null, intent,
1304                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1305                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1306
1307                    if (mShowDialogs) {
1308                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1309                                mContext, proc, (ActivityRecord)data.get("activity"),
1310                                msg.arg1 != 0);
1311                        d.show();
1312                        proc.anrDialog = d;
1313                    } else {
1314                        // Just kill the app if there is no dialog to be shown.
1315                        killAppAtUsersRequest(proc, null);
1316                    }
1317                }
1318
1319                ensureBootCompleted();
1320            } break;
1321            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1322                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1323                synchronized (ActivityManagerService.this) {
1324                    ProcessRecord proc = (ProcessRecord) data.get("app");
1325                    if (proc == null) {
1326                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1327                        break;
1328                    }
1329                    if (proc.crashDialog != null) {
1330                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1331                        return;
1332                    }
1333                    AppErrorResult res = (AppErrorResult) data.get("result");
1334                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1335                        Dialog d = new StrictModeViolationDialog(mContext,
1336                                ActivityManagerService.this, res, proc);
1337                        d.show();
1338                        proc.crashDialog = d;
1339                    } else {
1340                        // The device is asleep, so just pretend that the user
1341                        // saw a crash dialog and hit "force quit".
1342                        res.set(0);
1343                    }
1344                }
1345                ensureBootCompleted();
1346            } break;
1347            case SHOW_FACTORY_ERROR_MSG: {
1348                Dialog d = new FactoryErrorDialog(
1349                    mContext, msg.getData().getCharSequence("msg"));
1350                d.show();
1351                ensureBootCompleted();
1352            } break;
1353            case UPDATE_CONFIGURATION_MSG: {
1354                final ContentResolver resolver = mContext.getContentResolver();
1355                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1356            } break;
1357            case GC_BACKGROUND_PROCESSES_MSG: {
1358                synchronized (ActivityManagerService.this) {
1359                    performAppGcsIfAppropriateLocked();
1360                }
1361            } break;
1362            case WAIT_FOR_DEBUGGER_MSG: {
1363                synchronized (ActivityManagerService.this) {
1364                    ProcessRecord app = (ProcessRecord)msg.obj;
1365                    if (msg.arg1 != 0) {
1366                        if (!app.waitedForDebugger) {
1367                            Dialog d = new AppWaitingForDebuggerDialog(
1368                                    ActivityManagerService.this,
1369                                    mContext, app);
1370                            app.waitDialog = d;
1371                            app.waitedForDebugger = true;
1372                            d.show();
1373                        }
1374                    } else {
1375                        if (app.waitDialog != null) {
1376                            app.waitDialog.dismiss();
1377                            app.waitDialog = null;
1378                        }
1379                    }
1380                }
1381            } break;
1382            case SERVICE_TIMEOUT_MSG: {
1383                if (mDidDexOpt) {
1384                    mDidDexOpt = false;
1385                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1386                    nmsg.obj = msg.obj;
1387                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1388                    return;
1389                }
1390                mServices.serviceTimeout((ProcessRecord)msg.obj);
1391            } break;
1392            case UPDATE_TIME_ZONE: {
1393                synchronized (ActivityManagerService.this) {
1394                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1395                        ProcessRecord r = mLruProcesses.get(i);
1396                        if (r.thread != null) {
1397                            try {
1398                                r.thread.updateTimeZone();
1399                            } catch (RemoteException ex) {
1400                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1401                            }
1402                        }
1403                    }
1404                }
1405            } break;
1406            case CLEAR_DNS_CACHE_MSG: {
1407                synchronized (ActivityManagerService.this) {
1408                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1409                        ProcessRecord r = mLruProcesses.get(i);
1410                        if (r.thread != null) {
1411                            try {
1412                                r.thread.clearDnsCache();
1413                            } catch (RemoteException ex) {
1414                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1415                            }
1416                        }
1417                    }
1418                }
1419            } break;
1420            case UPDATE_HTTP_PROXY_MSG: {
1421                ProxyInfo proxy = (ProxyInfo)msg.obj;
1422                String host = "";
1423                String port = "";
1424                String exclList = "";
1425                Uri pacFileUrl = Uri.EMPTY;
1426                if (proxy != null) {
1427                    host = proxy.getHost();
1428                    port = Integer.toString(proxy.getPort());
1429                    exclList = proxy.getExclusionListAsString();
1430                    pacFileUrl = proxy.getPacFileUrl();
1431                }
1432                synchronized (ActivityManagerService.this) {
1433                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1434                        ProcessRecord r = mLruProcesses.get(i);
1435                        if (r.thread != null) {
1436                            try {
1437                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1438                            } catch (RemoteException ex) {
1439                                Slog.w(TAG, "Failed to update http proxy for: " +
1440                                        r.info.processName);
1441                            }
1442                        }
1443                    }
1444                }
1445            } break;
1446            case SHOW_UID_ERROR_MSG: {
1447                String title = "System UIDs Inconsistent";
1448                String text = "UIDs on the system are inconsistent, you need to wipe your"
1449                        + " data partition or your device will be unstable.";
1450                Log.e(TAG, title + ": " + text);
1451                if (mShowDialogs) {
1452                    // XXX This is a temporary dialog, no need to localize.
1453                    AlertDialog d = new BaseErrorDialog(mContext);
1454                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1455                    d.setCancelable(false);
1456                    d.setTitle(title);
1457                    d.setMessage(text);
1458                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1459                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1460                    mUidAlert = d;
1461                    d.show();
1462                }
1463            } break;
1464            case IM_FEELING_LUCKY_MSG: {
1465                if (mUidAlert != null) {
1466                    mUidAlert.dismiss();
1467                    mUidAlert = null;
1468                }
1469            } break;
1470            case PROC_START_TIMEOUT_MSG: {
1471                if (mDidDexOpt) {
1472                    mDidDexOpt = false;
1473                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1474                    nmsg.obj = msg.obj;
1475                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1476                    return;
1477                }
1478                ProcessRecord app = (ProcessRecord)msg.obj;
1479                synchronized (ActivityManagerService.this) {
1480                    processStartTimedOutLocked(app);
1481                }
1482            } break;
1483            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1484                synchronized (ActivityManagerService.this) {
1485                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1486                }
1487            } break;
1488            case KILL_APPLICATION_MSG: {
1489                synchronized (ActivityManagerService.this) {
1490                    int appid = msg.arg1;
1491                    boolean restart = (msg.arg2 == 1);
1492                    Bundle bundle = (Bundle)msg.obj;
1493                    String pkg = bundle.getString("pkg");
1494                    String reason = bundle.getString("reason");
1495                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1496                            false, UserHandle.USER_ALL, reason);
1497                }
1498            } break;
1499            case FINALIZE_PENDING_INTENT_MSG: {
1500                ((PendingIntentRecord)msg.obj).completeFinalize();
1501            } break;
1502            case POST_HEAVY_NOTIFICATION_MSG: {
1503                INotificationManager inm = NotificationManager.getService();
1504                if (inm == null) {
1505                    return;
1506                }
1507
1508                ActivityRecord root = (ActivityRecord)msg.obj;
1509                ProcessRecord process = root.app;
1510                if (process == null) {
1511                    return;
1512                }
1513
1514                try {
1515                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1516                    String text = mContext.getString(R.string.heavy_weight_notification,
1517                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1518                    Notification notification = new Notification();
1519                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1520                    notification.when = 0;
1521                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1522                    notification.tickerText = text;
1523                    notification.defaults = 0; // please be quiet
1524                    notification.sound = null;
1525                    notification.vibrate = null;
1526                    notification.color = mContext.getResources().getColor(
1527                            com.android.internal.R.color.system_notification_accent_color);
1528                    notification.setLatestEventInfo(context, text,
1529                            mContext.getText(R.string.heavy_weight_notification_detail),
1530                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1531                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1532                                    new UserHandle(root.userId)));
1533
1534                    try {
1535                        int[] outId = new int[1];
1536                        inm.enqueueNotificationWithTag("android", "android", null,
1537                                R.string.heavy_weight_notification,
1538                                notification, outId, root.userId);
1539                    } catch (RuntimeException e) {
1540                        Slog.w(ActivityManagerService.TAG,
1541                                "Error showing notification for heavy-weight app", e);
1542                    } catch (RemoteException e) {
1543                    }
1544                } catch (NameNotFoundException e) {
1545                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1546                }
1547            } break;
1548            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1549                INotificationManager inm = NotificationManager.getService();
1550                if (inm == null) {
1551                    return;
1552                }
1553                try {
1554                    inm.cancelNotificationWithTag("android", null,
1555                            R.string.heavy_weight_notification,  msg.arg1);
1556                } catch (RuntimeException e) {
1557                    Slog.w(ActivityManagerService.TAG,
1558                            "Error canceling notification for service", e);
1559                } catch (RemoteException e) {
1560                }
1561            } break;
1562            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1563                synchronized (ActivityManagerService.this) {
1564                    checkExcessivePowerUsageLocked(true);
1565                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1566                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1567                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1568                }
1569            } break;
1570            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1571                synchronized (ActivityManagerService.this) {
1572                    ActivityRecord ar = (ActivityRecord)msg.obj;
1573                    if (mCompatModeDialog != null) {
1574                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1575                                ar.info.applicationInfo.packageName)) {
1576                            return;
1577                        }
1578                        mCompatModeDialog.dismiss();
1579                        mCompatModeDialog = null;
1580                    }
1581                    if (ar != null && false) {
1582                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1583                                ar.packageName)) {
1584                            int mode = mCompatModePackages.computeCompatModeLocked(
1585                                    ar.info.applicationInfo);
1586                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1587                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1588                                mCompatModeDialog = new CompatModeDialog(
1589                                        ActivityManagerService.this, mContext,
1590                                        ar.info.applicationInfo);
1591                                mCompatModeDialog.show();
1592                            }
1593                        }
1594                    }
1595                }
1596                break;
1597            }
1598            case DISPATCH_PROCESSES_CHANGED: {
1599                dispatchProcessesChanged();
1600                break;
1601            }
1602            case DISPATCH_PROCESS_DIED: {
1603                final int pid = msg.arg1;
1604                final int uid = msg.arg2;
1605                dispatchProcessDied(pid, uid);
1606                break;
1607            }
1608            case REPORT_MEM_USAGE_MSG: {
1609                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1610                Thread thread = new Thread() {
1611                    @Override public void run() {
1612                        reportMemUsage(memInfos);
1613                    }
1614                };
1615                thread.start();
1616                break;
1617            }
1618            case START_USER_SWITCH_MSG: {
1619                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1620                break;
1621            }
1622            case REPORT_USER_SWITCH_MSG: {
1623                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1624                break;
1625            }
1626            case CONTINUE_USER_SWITCH_MSG: {
1627                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1628                break;
1629            }
1630            case USER_SWITCH_TIMEOUT_MSG: {
1631                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1632                break;
1633            }
1634            case IMMERSIVE_MODE_LOCK_MSG: {
1635                final boolean nextState = (msg.arg1 != 0);
1636                if (mUpdateLock.isHeld() != nextState) {
1637                    if (DEBUG_IMMERSIVE) {
1638                        final ActivityRecord r = (ActivityRecord) msg.obj;
1639                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1640                    }
1641                    if (nextState) {
1642                        mUpdateLock.acquire();
1643                    } else {
1644                        mUpdateLock.release();
1645                    }
1646                }
1647                break;
1648            }
1649            case PERSIST_URI_GRANTS_MSG: {
1650                writeGrantedUriPermissions();
1651                break;
1652            }
1653            case REQUEST_ALL_PSS_MSG: {
1654                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1655                break;
1656            }
1657            case START_PROFILES_MSG: {
1658                synchronized (ActivityManagerService.this) {
1659                    startProfilesLocked();
1660                }
1661                break;
1662            }
1663            case UPDATE_TIME: {
1664                synchronized (ActivityManagerService.this) {
1665                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1666                        ProcessRecord r = mLruProcesses.get(i);
1667                        if (r.thread != null) {
1668                            try {
1669                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1670                            } catch (RemoteException ex) {
1671                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1672                            }
1673                        }
1674                    }
1675                }
1676                break;
1677            }
1678            case SYSTEM_USER_START_MSG: {
1679                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1680                        Integer.toString(msg.arg1), msg.arg1);
1681                mSystemServiceManager.startUser(msg.arg1);
1682                break;
1683            }
1684            case SYSTEM_USER_CURRENT_MSG: {
1685                mBatteryStatsService.noteEvent(
1686                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1687                        Integer.toString(msg.arg2), msg.arg2);
1688                mBatteryStatsService.noteEvent(
1689                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1690                        Integer.toString(msg.arg1), msg.arg1);
1691                mSystemServiceManager.switchUser(msg.arg1);
1692                mLockToAppRequest.clearPrompt();
1693                break;
1694            }
1695            case ENTER_ANIMATION_COMPLETE_MSG: {
1696                synchronized (ActivityManagerService.this) {
1697                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1698                    if (r != null && r.app != null && r.app.thread != null) {
1699                        try {
1700                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1701                        } catch (RemoteException e) {
1702                        }
1703                    }
1704                }
1705                break;
1706            }
1707            case FINISH_BOOTING_MSG: {
1708                if (msg.arg1 != 0) {
1709                    finishBooting();
1710                }
1711                if (msg.arg2 != 0) {
1712                    enableScreenAfterBoot();
1713                }
1714                break;
1715            }
1716            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1717                try {
1718                    Locale l = (Locale) msg.obj;
1719                    IBinder service = ServiceManager.getService("mount");
1720                    IMountService mountService = IMountService.Stub.asInterface(service);
1721                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1722                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1723                } catch (RemoteException e) {
1724                    Log.e(TAG, "Error storing locale for decryption UI", e);
1725                }
1726                break;
1727            }
1728            }
1729        }
1730    };
1731
1732    static final int COLLECT_PSS_BG_MSG = 1;
1733
1734    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1735        @Override
1736        public void handleMessage(Message msg) {
1737            switch (msg.what) {
1738            case COLLECT_PSS_BG_MSG: {
1739                long start = SystemClock.uptimeMillis();
1740                MemInfoReader memInfo = null;
1741                synchronized (ActivityManagerService.this) {
1742                    if (mFullPssPending) {
1743                        mFullPssPending = false;
1744                        memInfo = new MemInfoReader();
1745                    }
1746                }
1747                if (memInfo != null) {
1748                    updateCpuStatsNow();
1749                    long nativeTotalPss = 0;
1750                    synchronized (mProcessCpuTracker) {
1751                        final int N = mProcessCpuTracker.countStats();
1752                        for (int j=0; j<N; j++) {
1753                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1754                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1755                                // This is definitely an application process; skip it.
1756                                continue;
1757                            }
1758                            synchronized (mPidsSelfLocked) {
1759                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1760                                    // This is one of our own processes; skip it.
1761                                    continue;
1762                                }
1763                            }
1764                            nativeTotalPss += Debug.getPss(st.pid, null);
1765                        }
1766                    }
1767                    memInfo.readMemInfo();
1768                    synchronized (ActivityManagerService.this) {
1769                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1770                                + (SystemClock.uptimeMillis()-start) + "ms");
1771                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1772                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1773                                memInfo.getKernelUsedSizeKb(), nativeTotalPss);
1774                    }
1775                }
1776
1777                int i=0, num=0;
1778                long[] tmp = new long[1];
1779                do {
1780                    ProcessRecord proc;
1781                    int procState;
1782                    int pid;
1783                    synchronized (ActivityManagerService.this) {
1784                        if (i >= mPendingPssProcesses.size()) {
1785                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1786                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1787                            mPendingPssProcesses.clear();
1788                            return;
1789                        }
1790                        proc = mPendingPssProcesses.get(i);
1791                        procState = proc.pssProcState;
1792                        if (proc.thread != null && procState == proc.setProcState) {
1793                            pid = proc.pid;
1794                        } else {
1795                            proc = null;
1796                            pid = 0;
1797                        }
1798                        i++;
1799                    }
1800                    if (proc != null) {
1801                        long pss = Debug.getPss(pid, tmp);
1802                        synchronized (ActivityManagerService.this) {
1803                            if (proc.thread != null && proc.setProcState == procState
1804                                    && proc.pid == pid) {
1805                                num++;
1806                                proc.lastPssTime = SystemClock.uptimeMillis();
1807                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1808                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1809                                        + ": " + pss + " lastPss=" + proc.lastPss
1810                                        + " state=" + ProcessList.makeProcStateString(procState));
1811                                if (proc.initialIdlePss == 0) {
1812                                    proc.initialIdlePss = pss;
1813                                }
1814                                proc.lastPss = pss;
1815                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1816                                    proc.lastCachedPss = pss;
1817                                }
1818                            }
1819                        }
1820                    }
1821                } while (true);
1822            }
1823            }
1824        }
1825    };
1826
1827    /**
1828     * Monitor for package changes and update our internal state.
1829     */
1830    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1831        @Override
1832        public void onPackageRemoved(String packageName, int uid) {
1833            // Remove all tasks with activities in the specified package from the list of recent tasks
1834            final int eventUserId = getChangingUserId();
1835            synchronized (ActivityManagerService.this) {
1836                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1837                    TaskRecord tr = mRecentTasks.get(i);
1838                    if (tr.userId != eventUserId) continue;
1839
1840                    ComponentName cn = tr.intent.getComponent();
1841                    if (cn != null && cn.getPackageName().equals(packageName)) {
1842                        // If the package name matches, remove the task
1843                        removeTaskByIdLocked(tr.taskId, true);
1844                    }
1845                }
1846            }
1847        }
1848
1849        @Override
1850        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1851            onPackageModified(packageName);
1852            return true;
1853        }
1854
1855        @Override
1856        public void onPackageModified(String packageName) {
1857            final int eventUserId = getChangingUserId();
1858            final IPackageManager pm = AppGlobals.getPackageManager();
1859            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1860                    new ArrayList<Pair<Intent, Integer>>();
1861            final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
1862            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1863            // Copy the list of recent tasks so that we don't hold onto the lock on
1864            // ActivityManagerService for long periods while checking if components exist.
1865            synchronized (ActivityManagerService.this) {
1866                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1867                    TaskRecord tr = mRecentTasks.get(i);
1868                    if (tr.userId != eventUserId) continue;
1869
1870                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1871                }
1872            }
1873            // Check the recent tasks and filter out all tasks with components that no longer exist.
1874            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1875                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1876                ComponentName cn = p.first.getComponent();
1877                if (cn != null && cn.getPackageName().equals(packageName)) {
1878                    if (componentsKnownToExist.contains(cn)) {
1879                        // If we know that the component still exists in the package, then skip
1880                        continue;
1881                    }
1882                    try {
1883                        ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId);
1884                        if (info != null) {
1885                            componentsKnownToExist.add(cn);
1886                        } else {
1887                            tasksToRemove.add(p.second);
1888                        }
1889                    } catch (RemoteException e) {
1890                        Log.e(TAG, "Failed to query activity info for component: " + cn, e);
1891                    }
1892                }
1893            }
1894            // Prune all the tasks with removed components from the list of recent tasks
1895            synchronized (ActivityManagerService.this) {
1896                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1897                    removeTaskByIdLocked(tasksToRemove.get(i), false);
1898                }
1899            }
1900        }
1901
1902        @Override
1903        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1904            // Force stop the specified packages
1905            int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
1906            if (packages != null) {
1907                for (String pkg : packages) {
1908                    synchronized (ActivityManagerService.this) {
1909                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
1910                                userId, "finished booting")) {
1911                            return true;
1912                        }
1913                    }
1914                }
1915            }
1916            return false;
1917        }
1918    };
1919
1920    public void setSystemProcess() {
1921        try {
1922            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1923            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1924            ServiceManager.addService("meminfo", new MemBinder(this));
1925            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1926            ServiceManager.addService("dbinfo", new DbBinder(this));
1927            if (MONITOR_CPU_USAGE) {
1928                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1929            }
1930            ServiceManager.addService("permission", new PermissionController(this));
1931
1932            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1933                    "android", STOCK_PM_FLAGS);
1934            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1935
1936            synchronized (this) {
1937                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1938                app.persistent = true;
1939                app.pid = MY_PID;
1940                app.maxAdj = ProcessList.SYSTEM_ADJ;
1941                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1942                mProcessNames.put(app.processName, app.uid, app);
1943                synchronized (mPidsSelfLocked) {
1944                    mPidsSelfLocked.put(app.pid, app);
1945                }
1946                updateLruProcessLocked(app, false, null);
1947                updateOomAdjLocked();
1948            }
1949        } catch (PackageManager.NameNotFoundException e) {
1950            throw new RuntimeException(
1951                    "Unable to find android system package", e);
1952        }
1953    }
1954
1955    public void setWindowManager(WindowManagerService wm) {
1956        mWindowManager = wm;
1957        mStackSupervisor.setWindowManager(wm);
1958    }
1959
1960    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1961        mUsageStatsService = usageStatsManager;
1962    }
1963
1964    public void startObservingNativeCrashes() {
1965        final NativeCrashListener ncl = new NativeCrashListener(this);
1966        ncl.start();
1967    }
1968
1969    public IAppOpsService getAppOpsService() {
1970        return mAppOpsService;
1971    }
1972
1973    static class MemBinder extends Binder {
1974        ActivityManagerService mActivityManagerService;
1975        MemBinder(ActivityManagerService activityManagerService) {
1976            mActivityManagerService = activityManagerService;
1977        }
1978
1979        @Override
1980        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1981            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1982                    != PackageManager.PERMISSION_GRANTED) {
1983                pw.println("Permission Denial: can't dump meminfo from from pid="
1984                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1985                        + " without permission " + android.Manifest.permission.DUMP);
1986                return;
1987            }
1988
1989            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1990        }
1991    }
1992
1993    static class GraphicsBinder extends Binder {
1994        ActivityManagerService mActivityManagerService;
1995        GraphicsBinder(ActivityManagerService activityManagerService) {
1996            mActivityManagerService = activityManagerService;
1997        }
1998
1999        @Override
2000        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2001            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2002                    != PackageManager.PERMISSION_GRANTED) {
2003                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2004                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2005                        + " without permission " + android.Manifest.permission.DUMP);
2006                return;
2007            }
2008
2009            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2010        }
2011    }
2012
2013    static class DbBinder extends Binder {
2014        ActivityManagerService mActivityManagerService;
2015        DbBinder(ActivityManagerService activityManagerService) {
2016            mActivityManagerService = activityManagerService;
2017        }
2018
2019        @Override
2020        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2021            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2022                    != PackageManager.PERMISSION_GRANTED) {
2023                pw.println("Permission Denial: can't dump dbinfo from from pid="
2024                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2025                        + " without permission " + android.Manifest.permission.DUMP);
2026                return;
2027            }
2028
2029            mActivityManagerService.dumpDbInfo(fd, pw, args);
2030        }
2031    }
2032
2033    static class CpuBinder extends Binder {
2034        ActivityManagerService mActivityManagerService;
2035        CpuBinder(ActivityManagerService activityManagerService) {
2036            mActivityManagerService = activityManagerService;
2037        }
2038
2039        @Override
2040        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2041            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2042                    != PackageManager.PERMISSION_GRANTED) {
2043                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2044                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2045                        + " without permission " + android.Manifest.permission.DUMP);
2046                return;
2047            }
2048
2049            synchronized (mActivityManagerService.mProcessCpuTracker) {
2050                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2051                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2052                        SystemClock.uptimeMillis()));
2053            }
2054        }
2055    }
2056
2057    public static final class Lifecycle extends SystemService {
2058        private final ActivityManagerService mService;
2059
2060        public Lifecycle(Context context) {
2061            super(context);
2062            mService = new ActivityManagerService(context);
2063        }
2064
2065        @Override
2066        public void onStart() {
2067            mService.start();
2068        }
2069
2070        public ActivityManagerService getService() {
2071            return mService;
2072        }
2073    }
2074
2075    // Note: This method is invoked on the main thread but may need to attach various
2076    // handlers to other threads.  So take care to be explicit about the looper.
2077    public ActivityManagerService(Context systemContext) {
2078        mContext = systemContext;
2079        mFactoryTest = FactoryTest.getMode();
2080        mSystemThread = ActivityThread.currentActivityThread();
2081
2082        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2083
2084        mHandlerThread = new ServiceThread(TAG,
2085                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2086        mHandlerThread.start();
2087        mHandler = new MainHandler(mHandlerThread.getLooper());
2088
2089        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2090                "foreground", BROADCAST_FG_TIMEOUT, false);
2091        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2092                "background", BROADCAST_BG_TIMEOUT, true);
2093        mBroadcastQueues[0] = mFgBroadcastQueue;
2094        mBroadcastQueues[1] = mBgBroadcastQueue;
2095
2096        mServices = new ActiveServices(this);
2097        mProviderMap = new ProviderMap(this);
2098
2099        // TODO: Move creation of battery stats service outside of activity manager service.
2100        File dataDir = Environment.getDataDirectory();
2101        File systemDir = new File(dataDir, "system");
2102        systemDir.mkdirs();
2103        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2104        mBatteryStatsService.getActiveStatistics().readLocked();
2105        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2106        mOnBattery = DEBUG_POWER ? true
2107                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2108        mBatteryStatsService.getActiveStatistics().setCallback(this);
2109
2110        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2111
2112        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2113
2114        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2115
2116        // User 0 is the first and only user that runs at boot.
2117        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2118        mUserLru.add(Integer.valueOf(0));
2119        updateStartedUserArrayLocked();
2120
2121        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2122            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2123
2124        mConfiguration.setToDefaults();
2125        mConfiguration.setLocale(Locale.getDefault());
2126
2127        mConfigurationSeq = mConfiguration.seq = 1;
2128        mProcessCpuTracker.init();
2129
2130        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2131        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2132        mStackSupervisor = new ActivityStackSupervisor(this);
2133        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2134
2135        mProcessCpuThread = new Thread("CpuTracker") {
2136            @Override
2137            public void run() {
2138                while (true) {
2139                    try {
2140                        try {
2141                            synchronized(this) {
2142                                final long now = SystemClock.uptimeMillis();
2143                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2144                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2145                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2146                                //        + ", write delay=" + nextWriteDelay);
2147                                if (nextWriteDelay < nextCpuDelay) {
2148                                    nextCpuDelay = nextWriteDelay;
2149                                }
2150                                if (nextCpuDelay > 0) {
2151                                    mProcessCpuMutexFree.set(true);
2152                                    this.wait(nextCpuDelay);
2153                                }
2154                            }
2155                        } catch (InterruptedException e) {
2156                        }
2157                        updateCpuStatsNow();
2158                    } catch (Exception e) {
2159                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2160                    }
2161                }
2162            }
2163        };
2164
2165        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2166
2167        Watchdog.getInstance().addMonitor(this);
2168        Watchdog.getInstance().addThread(mHandler);
2169    }
2170
2171    public void setSystemServiceManager(SystemServiceManager mgr) {
2172        mSystemServiceManager = mgr;
2173    }
2174
2175    private void start() {
2176        Process.removeAllProcessGroups();
2177        mProcessCpuThread.start();
2178
2179        mBatteryStatsService.publish(mContext);
2180        mAppOpsService.publish(mContext);
2181        Slog.d("AppOps", "AppOpsService published");
2182        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2183    }
2184
2185    public void initPowerManagement() {
2186        mStackSupervisor.initPowerManagement();
2187        mBatteryStatsService.initPowerManagement();
2188    }
2189
2190    @Override
2191    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2192            throws RemoteException {
2193        if (code == SYSPROPS_TRANSACTION) {
2194            // We need to tell all apps about the system property change.
2195            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2196            synchronized(this) {
2197                final int NP = mProcessNames.getMap().size();
2198                for (int ip=0; ip<NP; ip++) {
2199                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2200                    final int NA = apps.size();
2201                    for (int ia=0; ia<NA; ia++) {
2202                        ProcessRecord app = apps.valueAt(ia);
2203                        if (app.thread != null) {
2204                            procs.add(app.thread.asBinder());
2205                        }
2206                    }
2207                }
2208            }
2209
2210            int N = procs.size();
2211            for (int i=0; i<N; i++) {
2212                Parcel data2 = Parcel.obtain();
2213                try {
2214                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2215                } catch (RemoteException e) {
2216                }
2217                data2.recycle();
2218            }
2219        }
2220        try {
2221            return super.onTransact(code, data, reply, flags);
2222        } catch (RuntimeException e) {
2223            // The activity manager only throws security exceptions, so let's
2224            // log all others.
2225            if (!(e instanceof SecurityException)) {
2226                Slog.wtf(TAG, "Activity Manager Crash", e);
2227            }
2228            throw e;
2229        }
2230    }
2231
2232    void updateCpuStats() {
2233        final long now = SystemClock.uptimeMillis();
2234        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2235            return;
2236        }
2237        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2238            synchronized (mProcessCpuThread) {
2239                mProcessCpuThread.notify();
2240            }
2241        }
2242    }
2243
2244    void updateCpuStatsNow() {
2245        synchronized (mProcessCpuTracker) {
2246            mProcessCpuMutexFree.set(false);
2247            final long now = SystemClock.uptimeMillis();
2248            boolean haveNewCpuStats = false;
2249
2250            if (MONITOR_CPU_USAGE &&
2251                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2252                mLastCpuTime.set(now);
2253                haveNewCpuStats = true;
2254                mProcessCpuTracker.update();
2255                //Slog.i(TAG, mProcessCpu.printCurrentState());
2256                //Slog.i(TAG, "Total CPU usage: "
2257                //        + mProcessCpu.getTotalCpuPercent() + "%");
2258
2259                // Slog the cpu usage if the property is set.
2260                if ("true".equals(SystemProperties.get("events.cpu"))) {
2261                    int user = mProcessCpuTracker.getLastUserTime();
2262                    int system = mProcessCpuTracker.getLastSystemTime();
2263                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2264                    int irq = mProcessCpuTracker.getLastIrqTime();
2265                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2266                    int idle = mProcessCpuTracker.getLastIdleTime();
2267
2268                    int total = user + system + iowait + irq + softIrq + idle;
2269                    if (total == 0) total = 1;
2270
2271                    EventLog.writeEvent(EventLogTags.CPU,
2272                            ((user+system+iowait+irq+softIrq) * 100) / total,
2273                            (user * 100) / total,
2274                            (system * 100) / total,
2275                            (iowait * 100) / total,
2276                            (irq * 100) / total,
2277                            (softIrq * 100) / total);
2278                }
2279            }
2280
2281            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2282            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2283            synchronized(bstats) {
2284                synchronized(mPidsSelfLocked) {
2285                    if (haveNewCpuStats) {
2286                        if (mOnBattery) {
2287                            int perc = bstats.startAddingCpuLocked();
2288                            int totalUTime = 0;
2289                            int totalSTime = 0;
2290                            final int N = mProcessCpuTracker.countStats();
2291                            for (int i=0; i<N; i++) {
2292                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2293                                if (!st.working) {
2294                                    continue;
2295                                }
2296                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2297                                int otherUTime = (st.rel_utime*perc)/100;
2298                                int otherSTime = (st.rel_stime*perc)/100;
2299                                totalUTime += otherUTime;
2300                                totalSTime += otherSTime;
2301                                if (pr != null) {
2302                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2303                                    if (ps == null || !ps.isActive()) {
2304                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2305                                                pr.info.uid, pr.processName);
2306                                    }
2307                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2308                                            st.rel_stime-otherSTime);
2309                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2310                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2311                                } else {
2312                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2313                                    if (ps == null || !ps.isActive()) {
2314                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2315                                                bstats.mapUid(st.uid), st.name);
2316                                    }
2317                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2318                                            st.rel_stime-otherSTime);
2319                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2320                                }
2321                            }
2322                            bstats.finishAddingCpuLocked(perc, totalUTime,
2323                                    totalSTime, cpuSpeedTimes);
2324                        }
2325                    }
2326                }
2327
2328                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2329                    mLastWriteTime = now;
2330                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2331                }
2332            }
2333        }
2334    }
2335
2336    @Override
2337    public void batteryNeedsCpuUpdate() {
2338        updateCpuStatsNow();
2339    }
2340
2341    @Override
2342    public void batteryPowerChanged(boolean onBattery) {
2343        // When plugging in, update the CPU stats first before changing
2344        // the plug state.
2345        updateCpuStatsNow();
2346        synchronized (this) {
2347            synchronized(mPidsSelfLocked) {
2348                mOnBattery = DEBUG_POWER ? true : onBattery;
2349            }
2350        }
2351    }
2352
2353    /**
2354     * Initialize the application bind args. These are passed to each
2355     * process when the bindApplication() IPC is sent to the process. They're
2356     * lazily setup to make sure the services are running when they're asked for.
2357     */
2358    private HashMap<String, IBinder> getCommonServicesLocked() {
2359        if (mAppBindArgs == null) {
2360            mAppBindArgs = new HashMap<String, IBinder>();
2361
2362            // Setup the application init args
2363            mAppBindArgs.put("package", ServiceManager.getService("package"));
2364            mAppBindArgs.put("window", ServiceManager.getService("window"));
2365            mAppBindArgs.put(Context.ALARM_SERVICE,
2366                    ServiceManager.getService(Context.ALARM_SERVICE));
2367        }
2368        return mAppBindArgs;
2369    }
2370
2371    final void setFocusedActivityLocked(ActivityRecord r) {
2372        if (mFocusedActivity != r) {
2373            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2374            mFocusedActivity = r;
2375            if (r.task != null && r.task.voiceInteractor != null) {
2376                startRunningVoiceLocked();
2377            } else {
2378                finishRunningVoiceLocked();
2379            }
2380            mStackSupervisor.setFocusedStack(r);
2381            if (r != null) {
2382                mWindowManager.setFocusedApp(r.appToken, true);
2383            }
2384            applyUpdateLockStateLocked(r);
2385        }
2386    }
2387
2388    final void clearFocusedActivity(ActivityRecord r) {
2389        if (mFocusedActivity == r) {
2390            mFocusedActivity = null;
2391        }
2392    }
2393
2394    @Override
2395    public void setFocusedStack(int stackId) {
2396        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2397        synchronized (ActivityManagerService.this) {
2398            ActivityStack stack = mStackSupervisor.getStack(stackId);
2399            if (stack != null) {
2400                ActivityRecord r = stack.topRunningActivityLocked(null);
2401                if (r != null) {
2402                    setFocusedActivityLocked(r);
2403                }
2404            }
2405        }
2406    }
2407
2408    @Override
2409    public void notifyActivityDrawn(IBinder token) {
2410        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2411        synchronized (this) {
2412            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2413            if (r != null) {
2414                r.task.stack.notifyActivityDrawnLocked(r);
2415            }
2416        }
2417    }
2418
2419    final void applyUpdateLockStateLocked(ActivityRecord r) {
2420        // Modifications to the UpdateLock state are done on our handler, outside
2421        // the activity manager's locks.  The new state is determined based on the
2422        // state *now* of the relevant activity record.  The object is passed to
2423        // the handler solely for logging detail, not to be consulted/modified.
2424        final boolean nextState = r != null && r.immersive;
2425        mHandler.sendMessage(
2426                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2427    }
2428
2429    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2430        Message msg = Message.obtain();
2431        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2432        msg.obj = r.task.askedCompatMode ? null : r;
2433        mHandler.sendMessage(msg);
2434    }
2435
2436    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2437            String what, Object obj, ProcessRecord srcApp) {
2438        app.lastActivityTime = now;
2439
2440        if (app.activities.size() > 0) {
2441            // Don't want to touch dependent processes that are hosting activities.
2442            return index;
2443        }
2444
2445        int lrui = mLruProcesses.lastIndexOf(app);
2446        if (lrui < 0) {
2447            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2448                    + what + " " + obj + " from " + srcApp);
2449            return index;
2450        }
2451
2452        if (lrui >= index) {
2453            // Don't want to cause this to move dependent processes *back* in the
2454            // list as if they were less frequently used.
2455            return index;
2456        }
2457
2458        if (lrui >= mLruProcessActivityStart) {
2459            // Don't want to touch dependent processes that are hosting activities.
2460            return index;
2461        }
2462
2463        mLruProcesses.remove(lrui);
2464        if (index > 0) {
2465            index--;
2466        }
2467        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2468                + " in LRU list: " + app);
2469        mLruProcesses.add(index, app);
2470        return index;
2471    }
2472
2473    final void removeLruProcessLocked(ProcessRecord app) {
2474        int lrui = mLruProcesses.lastIndexOf(app);
2475        if (lrui >= 0) {
2476            if (!app.killed) {
2477                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2478                Process.killProcessQuiet(app.pid);
2479                Process.killProcessGroup(app.info.uid, app.pid);
2480            }
2481            if (lrui <= mLruProcessActivityStart) {
2482                mLruProcessActivityStart--;
2483            }
2484            if (lrui <= mLruProcessServiceStart) {
2485                mLruProcessServiceStart--;
2486            }
2487            mLruProcesses.remove(lrui);
2488        }
2489    }
2490
2491    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2492            ProcessRecord client) {
2493        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2494                || app.treatLikeActivity;
2495        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2496        if (!activityChange && hasActivity) {
2497            // The process has activities, so we are only allowing activity-based adjustments
2498            // to move it.  It should be kept in the front of the list with other
2499            // processes that have activities, and we don't want those to change their
2500            // order except due to activity operations.
2501            return;
2502        }
2503
2504        mLruSeq++;
2505        final long now = SystemClock.uptimeMillis();
2506        app.lastActivityTime = now;
2507
2508        // First a quick reject: if the app is already at the position we will
2509        // put it, then there is nothing to do.
2510        if (hasActivity) {
2511            final int N = mLruProcesses.size();
2512            if (N > 0 && mLruProcesses.get(N-1) == app) {
2513                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2514                return;
2515            }
2516        } else {
2517            if (mLruProcessServiceStart > 0
2518                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2519                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2520                return;
2521            }
2522        }
2523
2524        int lrui = mLruProcesses.lastIndexOf(app);
2525
2526        if (app.persistent && lrui >= 0) {
2527            // We don't care about the position of persistent processes, as long as
2528            // they are in the list.
2529            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2530            return;
2531        }
2532
2533        /* In progress: compute new position first, so we can avoid doing work
2534           if the process is not actually going to move.  Not yet working.
2535        int addIndex;
2536        int nextIndex;
2537        boolean inActivity = false, inService = false;
2538        if (hasActivity) {
2539            // Process has activities, put it at the very tipsy-top.
2540            addIndex = mLruProcesses.size();
2541            nextIndex = mLruProcessServiceStart;
2542            inActivity = true;
2543        } else if (hasService) {
2544            // Process has services, put it at the top of the service list.
2545            addIndex = mLruProcessActivityStart;
2546            nextIndex = mLruProcessServiceStart;
2547            inActivity = true;
2548            inService = true;
2549        } else  {
2550            // Process not otherwise of interest, it goes to the top of the non-service area.
2551            addIndex = mLruProcessServiceStart;
2552            if (client != null) {
2553                int clientIndex = mLruProcesses.lastIndexOf(client);
2554                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2555                        + app);
2556                if (clientIndex >= 0 && addIndex > clientIndex) {
2557                    addIndex = clientIndex;
2558                }
2559            }
2560            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2561        }
2562
2563        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2564                + mLruProcessActivityStart + "): " + app);
2565        */
2566
2567        if (lrui >= 0) {
2568            if (lrui < mLruProcessActivityStart) {
2569                mLruProcessActivityStart--;
2570            }
2571            if (lrui < mLruProcessServiceStart) {
2572                mLruProcessServiceStart--;
2573            }
2574            /*
2575            if (addIndex > lrui) {
2576                addIndex--;
2577            }
2578            if (nextIndex > lrui) {
2579                nextIndex--;
2580            }
2581            */
2582            mLruProcesses.remove(lrui);
2583        }
2584
2585        /*
2586        mLruProcesses.add(addIndex, app);
2587        if (inActivity) {
2588            mLruProcessActivityStart++;
2589        }
2590        if (inService) {
2591            mLruProcessActivityStart++;
2592        }
2593        */
2594
2595        int nextIndex;
2596        if (hasActivity) {
2597            final int N = mLruProcesses.size();
2598            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2599                // Process doesn't have activities, but has clients with
2600                // activities...  move it up, but one below the top (the top
2601                // should always have a real activity).
2602                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2603                mLruProcesses.add(N-1, app);
2604                // To keep it from spamming the LRU list (by making a bunch of clients),
2605                // we will push down any other entries owned by the app.
2606                final int uid = app.info.uid;
2607                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2608                    ProcessRecord subProc = mLruProcesses.get(i);
2609                    if (subProc.info.uid == uid) {
2610                        // We want to push this one down the list.  If the process after
2611                        // it is for the same uid, however, don't do so, because we don't
2612                        // want them internally to be re-ordered.
2613                        if (mLruProcesses.get(i-1).info.uid != uid) {
2614                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2615                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2616                            ProcessRecord tmp = mLruProcesses.get(i);
2617                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2618                            mLruProcesses.set(i-1, tmp);
2619                            i--;
2620                        }
2621                    } else {
2622                        // A gap, we can stop here.
2623                        break;
2624                    }
2625                }
2626            } else {
2627                // Process has activities, put it at the very tipsy-top.
2628                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2629                mLruProcesses.add(app);
2630            }
2631            nextIndex = mLruProcessServiceStart;
2632        } else if (hasService) {
2633            // Process has services, put it at the top of the service list.
2634            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2635            mLruProcesses.add(mLruProcessActivityStart, app);
2636            nextIndex = mLruProcessServiceStart;
2637            mLruProcessActivityStart++;
2638        } else  {
2639            // Process not otherwise of interest, it goes to the top of the non-service area.
2640            int index = mLruProcessServiceStart;
2641            if (client != null) {
2642                // If there is a client, don't allow the process to be moved up higher
2643                // in the list than that client.
2644                int clientIndex = mLruProcesses.lastIndexOf(client);
2645                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2646                        + " when updating " + app);
2647                if (clientIndex <= lrui) {
2648                    // Don't allow the client index restriction to push it down farther in the
2649                    // list than it already is.
2650                    clientIndex = lrui;
2651                }
2652                if (clientIndex >= 0 && index > clientIndex) {
2653                    index = clientIndex;
2654                }
2655            }
2656            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2657            mLruProcesses.add(index, app);
2658            nextIndex = index-1;
2659            mLruProcessActivityStart++;
2660            mLruProcessServiceStart++;
2661        }
2662
2663        // If the app is currently using a content provider or service,
2664        // bump those processes as well.
2665        for (int j=app.connections.size()-1; j>=0; j--) {
2666            ConnectionRecord cr = app.connections.valueAt(j);
2667            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2668                    && cr.binding.service.app != null
2669                    && cr.binding.service.app.lruSeq != mLruSeq
2670                    && !cr.binding.service.app.persistent) {
2671                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2672                        "service connection", cr, app);
2673            }
2674        }
2675        for (int j=app.conProviders.size()-1; j>=0; j--) {
2676            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2677            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2678                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2679                        "provider reference", cpr, app);
2680            }
2681        }
2682    }
2683
2684    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2685        if (uid == Process.SYSTEM_UID) {
2686            // The system gets to run in any process.  If there are multiple
2687            // processes with the same uid, just pick the first (this
2688            // should never happen).
2689            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2690            if (procs == null) return null;
2691            final int N = procs.size();
2692            for (int i = 0; i < N; i++) {
2693                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2694            }
2695        }
2696        ProcessRecord proc = mProcessNames.get(processName, uid);
2697        if (false && proc != null && !keepIfLarge
2698                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2699                && proc.lastCachedPss >= 4000) {
2700            // Turn this condition on to cause killing to happen regularly, for testing.
2701            if (proc.baseProcessTracker != null) {
2702                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2703            }
2704            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2705        } else if (proc != null && !keepIfLarge
2706                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2707                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2708            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2709            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2710                if (proc.baseProcessTracker != null) {
2711                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2712                }
2713                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2714            }
2715        }
2716        return proc;
2717    }
2718
2719    void ensurePackageDexOpt(String packageName) {
2720        IPackageManager pm = AppGlobals.getPackageManager();
2721        try {
2722            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2723                mDidDexOpt = true;
2724            }
2725        } catch (RemoteException e) {
2726        }
2727    }
2728
2729    boolean isNextTransitionForward() {
2730        int transit = mWindowManager.getPendingAppTransition();
2731        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2732                || transit == AppTransition.TRANSIT_TASK_OPEN
2733                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2734    }
2735
2736    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2737            String processName, String abiOverride, int uid, Runnable crashHandler) {
2738        synchronized(this) {
2739            ApplicationInfo info = new ApplicationInfo();
2740            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2741            // For isolated processes, the former contains the parent's uid and the latter the
2742            // actual uid of the isolated process.
2743            // In the special case introduced by this method (which is, starting an isolated
2744            // process directly from the SystemServer without an actual parent app process) the
2745            // closest thing to a parent's uid is SYSTEM_UID.
2746            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2747            // the |isolated| logic in the ProcessRecord constructor.
2748            info.uid = Process.SYSTEM_UID;
2749            info.processName = processName;
2750            info.className = entryPoint;
2751            info.packageName = "android";
2752            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2753                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2754                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2755                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2756                    crashHandler);
2757            return proc != null ? proc.pid : 0;
2758        }
2759    }
2760
2761    final ProcessRecord startProcessLocked(String processName,
2762            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2763            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2764            boolean isolated, boolean keepIfLarge) {
2765        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2766                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2767                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2768                null /* crashHandler */);
2769    }
2770
2771    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2772            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2773            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2774            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2775        long startTime = SystemClock.elapsedRealtime();
2776        ProcessRecord app;
2777        if (!isolated) {
2778            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2779            checkTime(startTime, "startProcess: after getProcessRecord");
2780        } else {
2781            // If this is an isolated process, it can't re-use an existing process.
2782            app = null;
2783        }
2784        // We don't have to do anything more if:
2785        // (1) There is an existing application record; and
2786        // (2) The caller doesn't think it is dead, OR there is no thread
2787        //     object attached to it so we know it couldn't have crashed; and
2788        // (3) There is a pid assigned to it, so it is either starting or
2789        //     already running.
2790        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2791                + " app=" + app + " knownToBeDead=" + knownToBeDead
2792                + " thread=" + (app != null ? app.thread : null)
2793                + " pid=" + (app != null ? app.pid : -1));
2794        if (app != null && app.pid > 0) {
2795            if (!knownToBeDead || app.thread == null) {
2796                // We already have the app running, or are waiting for it to
2797                // come up (we have a pid but not yet its thread), so keep it.
2798                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2799                // If this is a new package in the process, add the package to the list
2800                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2801                checkTime(startTime, "startProcess: done, added package to proc");
2802                return app;
2803            }
2804
2805            // An application record is attached to a previous process,
2806            // clean it up now.
2807            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2808            checkTime(startTime, "startProcess: bad proc running, killing");
2809            Process.killProcessGroup(app.info.uid, app.pid);
2810            handleAppDiedLocked(app, true, true);
2811            checkTime(startTime, "startProcess: done killing old proc");
2812        }
2813
2814        String hostingNameStr = hostingName != null
2815                ? hostingName.flattenToShortString() : null;
2816
2817        if (!isolated) {
2818            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2819                // If we are in the background, then check to see if this process
2820                // is bad.  If so, we will just silently fail.
2821                if (mBadProcesses.get(info.processName, info.uid) != null) {
2822                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2823                            + "/" + info.processName);
2824                    return null;
2825                }
2826            } else {
2827                // When the user is explicitly starting a process, then clear its
2828                // crash count so that we won't make it bad until they see at
2829                // least one crash dialog again, and make the process good again
2830                // if it had been bad.
2831                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2832                        + "/" + info.processName);
2833                mProcessCrashTimes.remove(info.processName, info.uid);
2834                if (mBadProcesses.get(info.processName, info.uid) != null) {
2835                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2836                            UserHandle.getUserId(info.uid), info.uid,
2837                            info.processName);
2838                    mBadProcesses.remove(info.processName, info.uid);
2839                    if (app != null) {
2840                        app.bad = false;
2841                    }
2842                }
2843            }
2844        }
2845
2846        if (app == null) {
2847            checkTime(startTime, "startProcess: creating new process record");
2848            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2849            app.crashHandler = crashHandler;
2850            if (app == null) {
2851                Slog.w(TAG, "Failed making new process record for "
2852                        + processName + "/" + info.uid + " isolated=" + isolated);
2853                return null;
2854            }
2855            mProcessNames.put(processName, app.uid, app);
2856            if (isolated) {
2857                mIsolatedProcesses.put(app.uid, app);
2858            }
2859            checkTime(startTime, "startProcess: done creating new process record");
2860        } else {
2861            // If this is a new package in the process, add the package to the list
2862            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2863            checkTime(startTime, "startProcess: added package to existing proc");
2864        }
2865
2866        // If the system is not ready yet, then hold off on starting this
2867        // process until it is.
2868        if (!mProcessesReady
2869                && !isAllowedWhileBooting(info)
2870                && !allowWhileBooting) {
2871            if (!mProcessesOnHold.contains(app)) {
2872                mProcessesOnHold.add(app);
2873            }
2874            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2875            checkTime(startTime, "startProcess: returning with proc on hold");
2876            return app;
2877        }
2878
2879        checkTime(startTime, "startProcess: stepping in to startProcess");
2880        startProcessLocked(
2881                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2882        checkTime(startTime, "startProcess: done starting proc!");
2883        return (app.pid != 0) ? app : null;
2884    }
2885
2886    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2887        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2888    }
2889
2890    private final void startProcessLocked(ProcessRecord app,
2891            String hostingType, String hostingNameStr) {
2892        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2893                null /* entryPoint */, null /* entryPointArgs */);
2894    }
2895
2896    private final void startProcessLocked(ProcessRecord app, String hostingType,
2897            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2898        long startTime = SystemClock.elapsedRealtime();
2899        if (app.pid > 0 && app.pid != MY_PID) {
2900            checkTime(startTime, "startProcess: removing from pids map");
2901            synchronized (mPidsSelfLocked) {
2902                mPidsSelfLocked.remove(app.pid);
2903                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2904            }
2905            checkTime(startTime, "startProcess: done removing from pids map");
2906            app.setPid(0);
2907        }
2908
2909        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2910                "startProcessLocked removing on hold: " + app);
2911        mProcessesOnHold.remove(app);
2912
2913        checkTime(startTime, "startProcess: starting to update cpu stats");
2914        updateCpuStats();
2915        checkTime(startTime, "startProcess: done updating cpu stats");
2916
2917        try {
2918            int uid = app.uid;
2919
2920            int[] gids = null;
2921            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2922            if (!app.isolated) {
2923                int[] permGids = null;
2924                try {
2925                    checkTime(startTime, "startProcess: getting gids from package manager");
2926                    final PackageManager pm = mContext.getPackageManager();
2927                    permGids = pm.getPackageGids(app.info.packageName);
2928
2929                    if (Environment.isExternalStorageEmulated()) {
2930                        checkTime(startTime, "startProcess: checking external storage perm");
2931                        if (pm.checkPermission(
2932                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2933                                app.info.packageName) == PERMISSION_GRANTED) {
2934                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2935                        } else {
2936                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2937                        }
2938                    }
2939                } catch (PackageManager.NameNotFoundException e) {
2940                    Slog.w(TAG, "Unable to retrieve gids", e);
2941                }
2942
2943                /*
2944                 * Add shared application and profile GIDs so applications can share some
2945                 * resources like shared libraries and access user-wide resources
2946                 */
2947                if (permGids == null) {
2948                    gids = new int[2];
2949                } else {
2950                    gids = new int[permGids.length + 2];
2951                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2952                }
2953                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2954                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2955            }
2956            checkTime(startTime, "startProcess: building args");
2957            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2958                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2959                        && mTopComponent != null
2960                        && app.processName.equals(mTopComponent.getPackageName())) {
2961                    uid = 0;
2962                }
2963                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2964                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2965                    uid = 0;
2966                }
2967            }
2968            int debugFlags = 0;
2969            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2970                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2971                // Also turn on CheckJNI for debuggable apps. It's quite
2972                // awkward to turn on otherwise.
2973                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2974            }
2975            // Run the app in safe mode if its manifest requests so or the
2976            // system is booted in safe mode.
2977            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2978                mSafeMode == true) {
2979                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2980            }
2981            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2982                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2983            }
2984            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2985                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2986            }
2987            if ("1".equals(SystemProperties.get("debug.assert"))) {
2988                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2989            }
2990
2991            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
2992            if (requiredAbi == null) {
2993                requiredAbi = Build.SUPPORTED_ABIS[0];
2994            }
2995
2996            String instructionSet = null;
2997            if (app.info.primaryCpuAbi != null) {
2998                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
2999            }
3000
3001            // Start the process.  It will either succeed and return a result containing
3002            // the PID of the new process, or else throw a RuntimeException.
3003            boolean isActivityProcess = (entryPoint == null);
3004            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3005            checkTime(startTime, "startProcess: asking zygote to start proc");
3006            Process.ProcessStartResult startResult = Process.start(entryPoint,
3007                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3008                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3009                    app.info.dataDir, entryPointArgs);
3010            checkTime(startTime, "startProcess: returned from zygote!");
3011
3012            if (app.isolated) {
3013                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3014            }
3015            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3016            checkTime(startTime, "startProcess: done updating battery stats");
3017
3018            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3019                    UserHandle.getUserId(uid), startResult.pid, uid,
3020                    app.processName, hostingType,
3021                    hostingNameStr != null ? hostingNameStr : "");
3022
3023            if (app.persistent) {
3024                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3025            }
3026
3027            checkTime(startTime, "startProcess: building log message");
3028            StringBuilder buf = mStringBuilder;
3029            buf.setLength(0);
3030            buf.append("Start proc ");
3031            buf.append(app.processName);
3032            if (!isActivityProcess) {
3033                buf.append(" [");
3034                buf.append(entryPoint);
3035                buf.append("]");
3036            }
3037            buf.append(" for ");
3038            buf.append(hostingType);
3039            if (hostingNameStr != null) {
3040                buf.append(" ");
3041                buf.append(hostingNameStr);
3042            }
3043            buf.append(": pid=");
3044            buf.append(startResult.pid);
3045            buf.append(" uid=");
3046            buf.append(uid);
3047            buf.append(" gids={");
3048            if (gids != null) {
3049                for (int gi=0; gi<gids.length; gi++) {
3050                    if (gi != 0) buf.append(", ");
3051                    buf.append(gids[gi]);
3052
3053                }
3054            }
3055            buf.append("}");
3056            if (requiredAbi != null) {
3057                buf.append(" abi=");
3058                buf.append(requiredAbi);
3059            }
3060            Slog.i(TAG, buf.toString());
3061            app.setPid(startResult.pid);
3062            app.usingWrapper = startResult.usingWrapper;
3063            app.removed = false;
3064            app.killed = false;
3065            app.killedByAm = false;
3066            checkTime(startTime, "startProcess: starting to update pids map");
3067            synchronized (mPidsSelfLocked) {
3068                this.mPidsSelfLocked.put(startResult.pid, app);
3069                if (isActivityProcess) {
3070                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3071                    msg.obj = app;
3072                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3073                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3074                }
3075            }
3076            checkTime(startTime, "startProcess: done updating pids map");
3077        } catch (RuntimeException e) {
3078            // XXX do better error recovery.
3079            app.setPid(0);
3080            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3081            if (app.isolated) {
3082                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3083            }
3084            Slog.e(TAG, "Failure starting process " + app.processName, e);
3085        }
3086    }
3087
3088    void updateUsageStats(ActivityRecord component, boolean resumed) {
3089        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3090        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3091        if (resumed) {
3092            if (mUsageStatsService != null) {
3093                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3094                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3095            }
3096            synchronized (stats) {
3097                stats.noteActivityResumedLocked(component.app.uid);
3098            }
3099        } else {
3100            if (mUsageStatsService != null) {
3101                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3102                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3103            }
3104            synchronized (stats) {
3105                stats.noteActivityPausedLocked(component.app.uid);
3106            }
3107        }
3108    }
3109
3110    Intent getHomeIntent() {
3111        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3112        intent.setComponent(mTopComponent);
3113        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3114            intent.addCategory(Intent.CATEGORY_HOME);
3115        }
3116        return intent;
3117    }
3118
3119    boolean startHomeActivityLocked(int userId) {
3120        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3121                && mTopAction == null) {
3122            // We are running in factory test mode, but unable to find
3123            // the factory test app, so just sit around displaying the
3124            // error message and don't try to start anything.
3125            return false;
3126        }
3127        Intent intent = getHomeIntent();
3128        ActivityInfo aInfo =
3129            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3130        if (aInfo != null) {
3131            intent.setComponent(new ComponentName(
3132                    aInfo.applicationInfo.packageName, aInfo.name));
3133            // Don't do this if the home app is currently being
3134            // instrumented.
3135            aInfo = new ActivityInfo(aInfo);
3136            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3137            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3138                    aInfo.applicationInfo.uid, true);
3139            if (app == null || app.instrumentationClass == null) {
3140                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3141                mStackSupervisor.startHomeActivity(intent, aInfo);
3142            }
3143        }
3144
3145        return true;
3146    }
3147
3148    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3149        ActivityInfo ai = null;
3150        ComponentName comp = intent.getComponent();
3151        try {
3152            if (comp != null) {
3153                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3154            } else {
3155                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3156                        intent,
3157                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3158                            flags, userId);
3159
3160                if (info != null) {
3161                    ai = info.activityInfo;
3162                }
3163            }
3164        } catch (RemoteException e) {
3165            // ignore
3166        }
3167
3168        return ai;
3169    }
3170
3171    /**
3172     * Starts the "new version setup screen" if appropriate.
3173     */
3174    void startSetupActivityLocked() {
3175        // Only do this once per boot.
3176        if (mCheckedForSetup) {
3177            return;
3178        }
3179
3180        // We will show this screen if the current one is a different
3181        // version than the last one shown, and we are not running in
3182        // low-level factory test mode.
3183        final ContentResolver resolver = mContext.getContentResolver();
3184        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3185                Settings.Global.getInt(resolver,
3186                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3187            mCheckedForSetup = true;
3188
3189            // See if we should be showing the platform update setup UI.
3190            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3191            List<ResolveInfo> ris = mContext.getPackageManager()
3192                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3193
3194            // We don't allow third party apps to replace this.
3195            ResolveInfo ri = null;
3196            for (int i=0; ris != null && i<ris.size(); i++) {
3197                if ((ris.get(i).activityInfo.applicationInfo.flags
3198                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3199                    ri = ris.get(i);
3200                    break;
3201                }
3202            }
3203
3204            if (ri != null) {
3205                String vers = ri.activityInfo.metaData != null
3206                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3207                        : null;
3208                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3209                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3210                            Intent.METADATA_SETUP_VERSION);
3211                }
3212                String lastVers = Settings.Secure.getString(
3213                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3214                if (vers != null && !vers.equals(lastVers)) {
3215                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3216                    intent.setComponent(new ComponentName(
3217                            ri.activityInfo.packageName, ri.activityInfo.name));
3218                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3219                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3220                            null);
3221                }
3222            }
3223        }
3224    }
3225
3226    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3227        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3228    }
3229
3230    void enforceNotIsolatedCaller(String caller) {
3231        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3232            throw new SecurityException("Isolated process not allowed to call " + caller);
3233        }
3234    }
3235
3236    void enforceShellRestriction(String restriction, int userHandle) {
3237        if (Binder.getCallingUid() == Process.SHELL_UID) {
3238            if (userHandle < 0
3239                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3240                throw new SecurityException("Shell does not have permission to access user "
3241                        + userHandle);
3242            }
3243        }
3244    }
3245
3246    @Override
3247    public int getFrontActivityScreenCompatMode() {
3248        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3249        synchronized (this) {
3250            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3251        }
3252    }
3253
3254    @Override
3255    public void setFrontActivityScreenCompatMode(int mode) {
3256        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3257                "setFrontActivityScreenCompatMode");
3258        synchronized (this) {
3259            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3260        }
3261    }
3262
3263    @Override
3264    public int getPackageScreenCompatMode(String packageName) {
3265        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3266        synchronized (this) {
3267            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3268        }
3269    }
3270
3271    @Override
3272    public void setPackageScreenCompatMode(String packageName, int mode) {
3273        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3274                "setPackageScreenCompatMode");
3275        synchronized (this) {
3276            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3277        }
3278    }
3279
3280    @Override
3281    public boolean getPackageAskScreenCompat(String packageName) {
3282        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3283        synchronized (this) {
3284            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3285        }
3286    }
3287
3288    @Override
3289    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3290        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3291                "setPackageAskScreenCompat");
3292        synchronized (this) {
3293            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3294        }
3295    }
3296
3297    private void dispatchProcessesChanged() {
3298        int N;
3299        synchronized (this) {
3300            N = mPendingProcessChanges.size();
3301            if (mActiveProcessChanges.length < N) {
3302                mActiveProcessChanges = new ProcessChangeItem[N];
3303            }
3304            mPendingProcessChanges.toArray(mActiveProcessChanges);
3305            mAvailProcessChanges.addAll(mPendingProcessChanges);
3306            mPendingProcessChanges.clear();
3307            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3308        }
3309
3310        int i = mProcessObservers.beginBroadcast();
3311        while (i > 0) {
3312            i--;
3313            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3314            if (observer != null) {
3315                try {
3316                    for (int j=0; j<N; j++) {
3317                        ProcessChangeItem item = mActiveProcessChanges[j];
3318                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3319                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3320                                    + item.pid + " uid=" + item.uid + ": "
3321                                    + item.foregroundActivities);
3322                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3323                                    item.foregroundActivities);
3324                        }
3325                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3326                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3327                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3328                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3329                        }
3330                    }
3331                } catch (RemoteException e) {
3332                }
3333            }
3334        }
3335        mProcessObservers.finishBroadcast();
3336    }
3337
3338    private void dispatchProcessDied(int pid, int uid) {
3339        int i = mProcessObservers.beginBroadcast();
3340        while (i > 0) {
3341            i--;
3342            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3343            if (observer != null) {
3344                try {
3345                    observer.onProcessDied(pid, uid);
3346                } catch (RemoteException e) {
3347                }
3348            }
3349        }
3350        mProcessObservers.finishBroadcast();
3351    }
3352
3353    @Override
3354    public final int startActivity(IApplicationThread caller, String callingPackage,
3355            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3356            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3357        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3358            resultWho, requestCode, startFlags, profilerInfo, options,
3359            UserHandle.getCallingUserId());
3360    }
3361
3362    @Override
3363    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3364            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3365            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3366        enforceNotIsolatedCaller("startActivity");
3367        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3368                false, ALLOW_FULL_ONLY, "startActivity", null);
3369        // TODO: Switch to user app stacks here.
3370        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3371                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3372                profilerInfo, null, null, options, userId, null, null);
3373    }
3374
3375    @Override
3376    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3377            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3378            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3379
3380        // This is very dangerous -- it allows you to perform a start activity (including
3381        // permission grants) as any app that may launch one of your own activities.  So
3382        // we will only allow this to be done from activities that are part of the core framework,
3383        // and then only when they are running as the system.
3384        final ActivityRecord sourceRecord;
3385        final int targetUid;
3386        final String targetPackage;
3387        synchronized (this) {
3388            if (resultTo == null) {
3389                throw new SecurityException("Must be called from an activity");
3390            }
3391            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3392            if (sourceRecord == null) {
3393                throw new SecurityException("Called with bad activity token: " + resultTo);
3394            }
3395            if (!sourceRecord.info.packageName.equals("android")) {
3396                throw new SecurityException(
3397                        "Must be called from an activity that is declared in the android package");
3398            }
3399            if (sourceRecord.app == null) {
3400                throw new SecurityException("Called without a process attached to activity");
3401            }
3402            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3403                // This is still okay, as long as this activity is running under the
3404                // uid of the original calling activity.
3405                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3406                    throw new SecurityException(
3407                            "Calling activity in uid " + sourceRecord.app.uid
3408                                    + " must be system uid or original calling uid "
3409                                    + sourceRecord.launchedFromUid);
3410                }
3411            }
3412            targetUid = sourceRecord.launchedFromUid;
3413            targetPackage = sourceRecord.launchedFromPackage;
3414        }
3415
3416        if (userId == UserHandle.USER_NULL) {
3417            userId = UserHandle.getUserId(sourceRecord.app.uid);
3418        }
3419
3420        // TODO: Switch to user app stacks here.
3421        try {
3422            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3423                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3424                    null, null, options, userId, null, null);
3425            return ret;
3426        } catch (SecurityException e) {
3427            // XXX need to figure out how to propagate to original app.
3428            // A SecurityException here is generally actually a fault of the original
3429            // calling activity (such as a fairly granting permissions), so propagate it
3430            // back to them.
3431            /*
3432            StringBuilder msg = new StringBuilder();
3433            msg.append("While launching");
3434            msg.append(intent.toString());
3435            msg.append(": ");
3436            msg.append(e.getMessage());
3437            */
3438            throw e;
3439        }
3440    }
3441
3442    @Override
3443    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3444            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3445            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3446        enforceNotIsolatedCaller("startActivityAndWait");
3447        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3448                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3449        WaitResult res = new WaitResult();
3450        // TODO: Switch to user app stacks here.
3451        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3452                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3453                options, userId, null, null);
3454        return res;
3455    }
3456
3457    @Override
3458    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3459            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3460            int startFlags, Configuration config, Bundle options, int userId) {
3461        enforceNotIsolatedCaller("startActivityWithConfig");
3462        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3463                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3464        // TODO: Switch to user app stacks here.
3465        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3466                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3467                null, null, config, options, userId, null, null);
3468        return ret;
3469    }
3470
3471    @Override
3472    public int startActivityIntentSender(IApplicationThread caller,
3473            IntentSender intent, Intent fillInIntent, String resolvedType,
3474            IBinder resultTo, String resultWho, int requestCode,
3475            int flagsMask, int flagsValues, Bundle options) {
3476        enforceNotIsolatedCaller("startActivityIntentSender");
3477        // Refuse possible leaked file descriptors
3478        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3479            throw new IllegalArgumentException("File descriptors passed in Intent");
3480        }
3481
3482        IIntentSender sender = intent.getTarget();
3483        if (!(sender instanceof PendingIntentRecord)) {
3484            throw new IllegalArgumentException("Bad PendingIntent object");
3485        }
3486
3487        PendingIntentRecord pir = (PendingIntentRecord)sender;
3488
3489        synchronized (this) {
3490            // If this is coming from the currently resumed activity, it is
3491            // effectively saying that app switches are allowed at this point.
3492            final ActivityStack stack = getFocusedStack();
3493            if (stack.mResumedActivity != null &&
3494                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3495                mAppSwitchesAllowedTime = 0;
3496            }
3497        }
3498        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3499                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3500        return ret;
3501    }
3502
3503    @Override
3504    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3505            Intent intent, String resolvedType, IVoiceInteractionSession session,
3506            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3507            Bundle options, int userId) {
3508        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3509                != PackageManager.PERMISSION_GRANTED) {
3510            String msg = "Permission Denial: startVoiceActivity() from pid="
3511                    + Binder.getCallingPid()
3512                    + ", uid=" + Binder.getCallingUid()
3513                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3514            Slog.w(TAG, msg);
3515            throw new SecurityException(msg);
3516        }
3517        if (session == null || interactor == null) {
3518            throw new NullPointerException("null session or interactor");
3519        }
3520        userId = handleIncomingUser(callingPid, callingUid, userId,
3521                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3522        // TODO: Switch to user app stacks here.
3523        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3524                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3525                null, options, userId, null, null);
3526    }
3527
3528    @Override
3529    public boolean startNextMatchingActivity(IBinder callingActivity,
3530            Intent intent, Bundle options) {
3531        // Refuse possible leaked file descriptors
3532        if (intent != null && intent.hasFileDescriptors() == true) {
3533            throw new IllegalArgumentException("File descriptors passed in Intent");
3534        }
3535
3536        synchronized (this) {
3537            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3538            if (r == null) {
3539                ActivityOptions.abort(options);
3540                return false;
3541            }
3542            if (r.app == null || r.app.thread == null) {
3543                // The caller is not running...  d'oh!
3544                ActivityOptions.abort(options);
3545                return false;
3546            }
3547            intent = new Intent(intent);
3548            // The caller is not allowed to change the data.
3549            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3550            // And we are resetting to find the next component...
3551            intent.setComponent(null);
3552
3553            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3554
3555            ActivityInfo aInfo = null;
3556            try {
3557                List<ResolveInfo> resolves =
3558                    AppGlobals.getPackageManager().queryIntentActivities(
3559                            intent, r.resolvedType,
3560                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3561                            UserHandle.getCallingUserId());
3562
3563                // Look for the original activity in the list...
3564                final int N = resolves != null ? resolves.size() : 0;
3565                for (int i=0; i<N; i++) {
3566                    ResolveInfo rInfo = resolves.get(i);
3567                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3568                            && rInfo.activityInfo.name.equals(r.info.name)) {
3569                        // We found the current one...  the next matching is
3570                        // after it.
3571                        i++;
3572                        if (i<N) {
3573                            aInfo = resolves.get(i).activityInfo;
3574                        }
3575                        if (debug) {
3576                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3577                                    + "/" + r.info.name);
3578                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3579                                    + "/" + aInfo.name);
3580                        }
3581                        break;
3582                    }
3583                }
3584            } catch (RemoteException e) {
3585            }
3586
3587            if (aInfo == null) {
3588                // Nobody who is next!
3589                ActivityOptions.abort(options);
3590                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3591                return false;
3592            }
3593
3594            intent.setComponent(new ComponentName(
3595                    aInfo.applicationInfo.packageName, aInfo.name));
3596            intent.setFlags(intent.getFlags()&~(
3597                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3598                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3599                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3600                    Intent.FLAG_ACTIVITY_NEW_TASK));
3601
3602            // Okay now we need to start the new activity, replacing the
3603            // currently running activity.  This is a little tricky because
3604            // we want to start the new one as if the current one is finished,
3605            // but not finish the current one first so that there is no flicker.
3606            // And thus...
3607            final boolean wasFinishing = r.finishing;
3608            r.finishing = true;
3609
3610            // Propagate reply information over to the new activity.
3611            final ActivityRecord resultTo = r.resultTo;
3612            final String resultWho = r.resultWho;
3613            final int requestCode = r.requestCode;
3614            r.resultTo = null;
3615            if (resultTo != null) {
3616                resultTo.removeResultsLocked(r, resultWho, requestCode);
3617            }
3618
3619            final long origId = Binder.clearCallingIdentity();
3620            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3621                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3622                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3623                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3624            Binder.restoreCallingIdentity(origId);
3625
3626            r.finishing = wasFinishing;
3627            if (res != ActivityManager.START_SUCCESS) {
3628                return false;
3629            }
3630            return true;
3631        }
3632    }
3633
3634    @Override
3635    public final int startActivityFromRecents(int taskId, Bundle options) {
3636        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3637            String msg = "Permission Denial: startActivityFromRecents called without " +
3638                    START_TASKS_FROM_RECENTS;
3639            Slog.w(TAG, msg);
3640            throw new SecurityException(msg);
3641        }
3642        return startActivityFromRecentsInner(taskId, options);
3643    }
3644
3645    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3646        final TaskRecord task;
3647        final int callingUid;
3648        final String callingPackage;
3649        final Intent intent;
3650        final int userId;
3651        synchronized (this) {
3652            task = recentTaskForIdLocked(taskId);
3653            if (task == null) {
3654                throw new IllegalArgumentException("Task " + taskId + " not found.");
3655            }
3656            callingUid = task.mCallingUid;
3657            callingPackage = task.mCallingPackage;
3658            intent = task.intent;
3659            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3660            userId = task.userId;
3661        }
3662        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3663                options, userId, null, task);
3664    }
3665
3666    final int startActivityInPackage(int uid, String callingPackage,
3667            Intent intent, String resolvedType, IBinder resultTo,
3668            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3669            IActivityContainer container, TaskRecord inTask) {
3670
3671        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3672                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3673
3674        // TODO: Switch to user app stacks here.
3675        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3676                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3677                null, null, null, options, userId, container, inTask);
3678        return ret;
3679    }
3680
3681    @Override
3682    public final int startActivities(IApplicationThread caller, String callingPackage,
3683            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3684            int userId) {
3685        enforceNotIsolatedCaller("startActivities");
3686        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3687                false, ALLOW_FULL_ONLY, "startActivity", null);
3688        // TODO: Switch to user app stacks here.
3689        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3690                resolvedTypes, resultTo, options, userId);
3691        return ret;
3692    }
3693
3694    final int startActivitiesInPackage(int uid, String callingPackage,
3695            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3696            Bundle options, int userId) {
3697
3698        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3699                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3700        // TODO: Switch to user app stacks here.
3701        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3702                resultTo, options, userId);
3703        return ret;
3704    }
3705
3706    //explicitly remove thd old information in mRecentTasks when removing existing user.
3707    private void removeRecentTasksForUserLocked(int userId) {
3708        if(userId <= 0) {
3709            Slog.i(TAG, "Can't remove recent task on user " + userId);
3710            return;
3711        }
3712
3713        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3714            TaskRecord tr = mRecentTasks.get(i);
3715            if (tr.userId == userId) {
3716                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3717                        + " when finishing user" + userId);
3718                mRecentTasks.remove(i);
3719                tr.removedFromRecents(mTaskPersister);
3720            }
3721        }
3722
3723        // Remove tasks from persistent storage.
3724        mTaskPersister.wakeup(null, true);
3725    }
3726
3727    // Sort by taskId
3728    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3729        @Override
3730        public int compare(TaskRecord lhs, TaskRecord rhs) {
3731            return rhs.taskId - lhs.taskId;
3732        }
3733    };
3734
3735    // Extract the affiliates of the chain containing mRecentTasks[start].
3736    private int processNextAffiliateChain(int start) {
3737        final TaskRecord startTask = mRecentTasks.get(start);
3738        final int affiliateId = startTask.mAffiliatedTaskId;
3739
3740        // Quick identification of isolated tasks. I.e. those not launched behind.
3741        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3742                startTask.mNextAffiliate == null) {
3743            // There is still a slim chance that there are other tasks that point to this task
3744            // and that the chain is so messed up that this task no longer points to them but
3745            // the gain of this optimization outweighs the risk.
3746            startTask.inRecents = true;
3747            return start + 1;
3748        }
3749
3750        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3751        mTmpRecents.clear();
3752        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3753            final TaskRecord task = mRecentTasks.get(i);
3754            if (task.mAffiliatedTaskId == affiliateId) {
3755                mRecentTasks.remove(i);
3756                mTmpRecents.add(task);
3757            }
3758        }
3759
3760        // Sort them all by taskId. That is the order they were create in and that order will
3761        // always be correct.
3762        Collections.sort(mTmpRecents, mTaskRecordComparator);
3763
3764        // Go through and fix up the linked list.
3765        // The first one is the end of the chain and has no next.
3766        final TaskRecord first = mTmpRecents.get(0);
3767        first.inRecents = true;
3768        if (first.mNextAffiliate != null) {
3769            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3770            first.setNextAffiliate(null);
3771            mTaskPersister.wakeup(first, false);
3772        }
3773        // Everything in the middle is doubly linked from next to prev.
3774        final int tmpSize = mTmpRecents.size();
3775        for (int i = 0; i < tmpSize - 1; ++i) {
3776            final TaskRecord next = mTmpRecents.get(i);
3777            final TaskRecord prev = mTmpRecents.get(i + 1);
3778            if (next.mPrevAffiliate != prev) {
3779                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3780                        " setting prev=" + prev);
3781                next.setPrevAffiliate(prev);
3782                mTaskPersister.wakeup(next, false);
3783            }
3784            if (prev.mNextAffiliate != next) {
3785                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3786                        " setting next=" + next);
3787                prev.setNextAffiliate(next);
3788                mTaskPersister.wakeup(prev, false);
3789            }
3790            prev.inRecents = true;
3791        }
3792        // The last one is the beginning of the list and has no prev.
3793        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3794        if (last.mPrevAffiliate != null) {
3795            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3796            last.setPrevAffiliate(null);
3797            mTaskPersister.wakeup(last, false);
3798        }
3799
3800        // Insert the group back into mRecentTasks at start.
3801        mRecentTasks.addAll(start, mTmpRecents);
3802
3803        // Let the caller know where we left off.
3804        return start + tmpSize;
3805    }
3806
3807    /**
3808     * Update the recent tasks lists: make sure tasks should still be here (their
3809     * applications / activities still exist), update their availability, fixup ordering
3810     * of affiliations.
3811     */
3812    void cleanupRecentTasksLocked(int userId) {
3813        if (mRecentTasks == null) {
3814            // Happens when called from the packagemanager broadcast before boot.
3815            return;
3816        }
3817
3818        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3819        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3820        final IPackageManager pm = AppGlobals.getPackageManager();
3821        final ActivityInfo dummyAct = new ActivityInfo();
3822        final ApplicationInfo dummyApp = new ApplicationInfo();
3823
3824        int N = mRecentTasks.size();
3825
3826        int[] users = userId == UserHandle.USER_ALL
3827                ? getUsersLocked() : new int[] { userId };
3828        for (int user : users) {
3829            for (int i = 0; i < N; i++) {
3830                TaskRecord task = mRecentTasks.get(i);
3831                if (task.userId != user) {
3832                    // Only look at tasks for the user ID of interest.
3833                    continue;
3834                }
3835                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3836                    // This situation is broken, and we should just get rid of it now.
3837                    mRecentTasks.remove(i);
3838                    task.removedFromRecents(mTaskPersister);
3839                    i--;
3840                    N--;
3841                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3842                    continue;
3843                }
3844                // Check whether this activity is currently available.
3845                if (task.realActivity != null) {
3846                    ActivityInfo ai = availActCache.get(task.realActivity);
3847                    if (ai == null) {
3848                        try {
3849                            ai = pm.getActivityInfo(task.realActivity,
3850                                    PackageManager.GET_UNINSTALLED_PACKAGES
3851                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3852                        } catch (RemoteException e) {
3853                            // Will never happen.
3854                            continue;
3855                        }
3856                        if (ai == null) {
3857                            ai = dummyAct;
3858                        }
3859                        availActCache.put(task.realActivity, ai);
3860                    }
3861                    if (ai == dummyAct) {
3862                        // This could be either because the activity no longer exists, or the
3863                        // app is temporarily gone.  For the former we want to remove the recents
3864                        // entry; for the latter we want to mark it as unavailable.
3865                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3866                        if (app == null) {
3867                            try {
3868                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3869                                        PackageManager.GET_UNINSTALLED_PACKAGES
3870                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3871                            } catch (RemoteException e) {
3872                                // Will never happen.
3873                                continue;
3874                            }
3875                            if (app == null) {
3876                                app = dummyApp;
3877                            }
3878                            availAppCache.put(task.realActivity.getPackageName(), app);
3879                        }
3880                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3881                            // Doesn't exist any more!  Good-bye.
3882                            mRecentTasks.remove(i);
3883                            task.removedFromRecents(mTaskPersister);
3884                            i--;
3885                            N--;
3886                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3887                            continue;
3888                        } else {
3889                            // Otherwise just not available for now.
3890                            if (task.isAvailable) {
3891                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3892                                        + task);
3893                            }
3894                            task.isAvailable = false;
3895                        }
3896                    } else {
3897                        if (!ai.enabled || !ai.applicationInfo.enabled
3898                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3899                            if (task.isAvailable) {
3900                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3901                                        + task + " (enabled=" + ai.enabled + "/"
3902                                        + ai.applicationInfo.enabled +  " flags="
3903                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3904                            }
3905                            task.isAvailable = false;
3906                        } else {
3907                            if (!task.isAvailable) {
3908                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3909                                        + task);
3910                            }
3911                            task.isAvailable = true;
3912                        }
3913                    }
3914                }
3915            }
3916        }
3917
3918        // Verify the affiliate chain for each task.
3919        for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
3920        }
3921
3922        mTmpRecents.clear();
3923        // mRecentTasks is now in sorted, affiliated order.
3924    }
3925
3926    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3927        int N = mRecentTasks.size();
3928        TaskRecord top = task;
3929        int topIndex = taskIndex;
3930        while (top.mNextAffiliate != null && topIndex > 0) {
3931            top = top.mNextAffiliate;
3932            topIndex--;
3933        }
3934        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3935                + topIndex + " from intial " + taskIndex);
3936        // Find the end of the chain, doing a sanity check along the way.
3937        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3938        int endIndex = topIndex;
3939        TaskRecord prev = top;
3940        while (endIndex < N) {
3941            TaskRecord cur = mRecentTasks.get(endIndex);
3942            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3943                    + endIndex + " " + cur);
3944            if (cur == top) {
3945                // Verify start of the chain.
3946                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
3947                    Slog.wtf(TAG, "Bad chain @" + endIndex
3948                            + ": first task has next affiliate: " + prev);
3949                    sane = false;
3950                    break;
3951                }
3952            } else {
3953                // Verify middle of the chain's next points back to the one before.
3954                if (cur.mNextAffiliate != prev
3955                        || cur.mNextAffiliateTaskId != prev.taskId) {
3956                    Slog.wtf(TAG, "Bad chain @" + endIndex
3957                            + ": middle task " + cur + " @" + endIndex
3958                            + " has bad next affiliate "
3959                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
3960                            + ", expected " + prev);
3961                    sane = false;
3962                    break;
3963                }
3964            }
3965            if (cur.mPrevAffiliateTaskId == -1) {
3966                // Chain ends here.
3967                if (cur.mPrevAffiliate != null) {
3968                    Slog.wtf(TAG, "Bad chain @" + endIndex
3969                            + ": last task " + cur + " has previous affiliate "
3970                            + cur.mPrevAffiliate);
3971                    sane = false;
3972                }
3973                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
3974                break;
3975            } else {
3976                // Verify middle of the chain's prev points to a valid item.
3977                if (cur.mPrevAffiliate == null) {
3978                    Slog.wtf(TAG, "Bad chain @" + endIndex
3979                            + ": task " + cur + " has previous affiliate "
3980                            + cur.mPrevAffiliate + " but should be id "
3981                            + cur.mPrevAffiliate);
3982                    sane = false;
3983                    break;
3984                }
3985            }
3986            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
3987                Slog.wtf(TAG, "Bad chain @" + endIndex
3988                        + ": task " + cur + " has affiliated id "
3989                        + cur.mAffiliatedTaskId + " but should be "
3990                        + task.mAffiliatedTaskId);
3991                sane = false;
3992                break;
3993            }
3994            prev = cur;
3995            endIndex++;
3996            if (endIndex >= N) {
3997                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
3998                        + ": last task " + prev);
3999                sane = false;
4000                break;
4001            }
4002        }
4003        if (sane) {
4004            if (endIndex < taskIndex) {
4005                Slog.wtf(TAG, "Bad chain @" + endIndex
4006                        + ": did not extend to task " + task + " @" + taskIndex);
4007                sane = false;
4008            }
4009        }
4010        if (sane) {
4011            // All looks good, we can just move all of the affiliated tasks
4012            // to the top.
4013            for (int i=topIndex; i<=endIndex; i++) {
4014                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4015                        + " from " + i + " to " + (i-topIndex));
4016                TaskRecord cur = mRecentTasks.remove(i);
4017                mRecentTasks.add(i-topIndex, cur);
4018            }
4019            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4020                    + " to " + endIndex);
4021            return true;
4022        }
4023
4024        // Whoops, couldn't do it.
4025        return false;
4026    }
4027
4028    final void addRecentTaskLocked(TaskRecord task) {
4029        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4030                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4031
4032        int N = mRecentTasks.size();
4033        // Quick case: check if the top-most recent task is the same.
4034        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4035            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4036            return;
4037        }
4038        // Another quick case: check if this is part of a set of affiliated
4039        // tasks that are at the top.
4040        if (isAffiliated && N > 0 && task.inRecents
4041                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4042            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4043                    + " at top when adding " + task);
4044            return;
4045        }
4046        // Another quick case: never add voice sessions.
4047        if (task.voiceSession != null) {
4048            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4049            return;
4050        }
4051
4052        boolean needAffiliationFix = false;
4053
4054        // Slightly less quick case: the task is already in recents, so all we need
4055        // to do is move it.
4056        if (task.inRecents) {
4057            int taskIndex = mRecentTasks.indexOf(task);
4058            if (taskIndex >= 0) {
4059                if (!isAffiliated) {
4060                    // Simple case: this is not an affiliated task, so we just move it to the front.
4061                    mRecentTasks.remove(taskIndex);
4062                    mRecentTasks.add(0, task);
4063                    notifyTaskPersisterLocked(task, false);
4064                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4065                            + " from " + taskIndex);
4066                    return;
4067                } else {
4068                    // More complicated: need to keep all affiliated tasks together.
4069                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4070                        // All went well.
4071                        return;
4072                    }
4073
4074                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4075                    // everything and then go through our general path of adding a new task.
4076                    needAffiliationFix = true;
4077                }
4078            } else {
4079                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4080                needAffiliationFix = true;
4081            }
4082        }
4083
4084        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4085        trimRecentsForTask(task, true);
4086
4087        N = mRecentTasks.size();
4088        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4089            final TaskRecord tr = mRecentTasks.remove(N - 1);
4090            tr.removedFromRecents(mTaskPersister);
4091            N--;
4092        }
4093        task.inRecents = true;
4094        if (!isAffiliated || needAffiliationFix) {
4095            // If this is a simple non-affiliated task, or we had some failure trying to
4096            // handle it as part of an affilated task, then just place it at the top.
4097            mRecentTasks.add(0, task);
4098        } else if (isAffiliated) {
4099            // If this is a new affiliated task, then move all of the affiliated tasks
4100            // to the front and insert this new one.
4101            TaskRecord other = task.mNextAffiliate;
4102            if (other == null) {
4103                other = task.mPrevAffiliate;
4104            }
4105            if (other != null) {
4106                int otherIndex = mRecentTasks.indexOf(other);
4107                if (otherIndex >= 0) {
4108                    // Insert new task at appropriate location.
4109                    int taskIndex;
4110                    if (other == task.mNextAffiliate) {
4111                        // We found the index of our next affiliation, which is who is
4112                        // before us in the list, so add after that point.
4113                        taskIndex = otherIndex+1;
4114                    } else {
4115                        // We found the index of our previous affiliation, which is who is
4116                        // after us in the list, so add at their position.
4117                        taskIndex = otherIndex;
4118                    }
4119                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4120                            + taskIndex + ": " + task);
4121                    mRecentTasks.add(taskIndex, task);
4122
4123                    // Now move everything to the front.
4124                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4125                        // All went well.
4126                        return;
4127                    }
4128
4129                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4130                    // everything and then go through our general path of adding a new task.
4131                    needAffiliationFix = true;
4132                } else {
4133                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4134                            + other);
4135                    needAffiliationFix = true;
4136                }
4137            } else {
4138                if (DEBUG_RECENTS) Slog.d(TAG,
4139                        "addRecent: adding affiliated task without next/prev:" + task);
4140                needAffiliationFix = true;
4141            }
4142        }
4143        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4144
4145        if (needAffiliationFix) {
4146            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4147            cleanupRecentTasksLocked(task.userId);
4148        }
4149    }
4150
4151    /**
4152     * If needed, remove oldest existing entries in recents that are for the same kind
4153     * of task as the given one.
4154     */
4155    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4156        int N = mRecentTasks.size();
4157        final Intent intent = task.intent;
4158        final boolean document = intent != null && intent.isDocument();
4159
4160        int maxRecents = task.maxRecents - 1;
4161        for (int i=0; i<N; i++) {
4162            final TaskRecord tr = mRecentTasks.get(i);
4163            if (task != tr) {
4164                if (task.userId != tr.userId) {
4165                    continue;
4166                }
4167                if (i > MAX_RECENT_BITMAPS) {
4168                    tr.freeLastThumbnail();
4169                }
4170                final Intent trIntent = tr.intent;
4171                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4172                    (intent == null || !intent.filterEquals(trIntent))) {
4173                    continue;
4174                }
4175                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4176                if (document && trIsDocument) {
4177                    // These are the same document activity (not necessarily the same doc).
4178                    if (maxRecents > 0) {
4179                        --maxRecents;
4180                        continue;
4181                    }
4182                    // Hit the maximum number of documents for this task. Fall through
4183                    // and remove this document from recents.
4184                } else if (document || trIsDocument) {
4185                    // Only one of these is a document. Not the droid we're looking for.
4186                    continue;
4187                }
4188            }
4189
4190            if (!doTrim) {
4191                // If the caller is not actually asking for a trim, just tell them we reached
4192                // a point where the trim would happen.
4193                return i;
4194            }
4195
4196            // Either task and tr are the same or, their affinities match or their intents match
4197            // and neither of them is a document, or they are documents using the same activity
4198            // and their maxRecents has been reached.
4199            tr.disposeThumbnail();
4200            mRecentTasks.remove(i);
4201            if (task != tr) {
4202                tr.removedFromRecents(mTaskPersister);
4203            }
4204            i--;
4205            N--;
4206            if (task.intent == null) {
4207                // If the new recent task we are adding is not fully
4208                // specified, then replace it with the existing recent task.
4209                task = tr;
4210            }
4211            notifyTaskPersisterLocked(tr, false);
4212        }
4213
4214        return -1;
4215    }
4216
4217    @Override
4218    public void reportActivityFullyDrawn(IBinder token) {
4219        synchronized (this) {
4220            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4221            if (r == null) {
4222                return;
4223            }
4224            r.reportFullyDrawnLocked();
4225        }
4226    }
4227
4228    @Override
4229    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4230        synchronized (this) {
4231            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4232            if (r == null) {
4233                return;
4234            }
4235            final long origId = Binder.clearCallingIdentity();
4236            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4237            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4238                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4239            if (config != null) {
4240                r.frozenBeforeDestroy = true;
4241                if (!updateConfigurationLocked(config, r, false, false)) {
4242                    mStackSupervisor.resumeTopActivitiesLocked();
4243                }
4244            }
4245            Binder.restoreCallingIdentity(origId);
4246        }
4247    }
4248
4249    @Override
4250    public int getRequestedOrientation(IBinder token) {
4251        synchronized (this) {
4252            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4253            if (r == null) {
4254                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4255            }
4256            return mWindowManager.getAppOrientation(r.appToken);
4257        }
4258    }
4259
4260    /**
4261     * This is the internal entry point for handling Activity.finish().
4262     *
4263     * @param token The Binder token referencing the Activity we want to finish.
4264     * @param resultCode Result code, if any, from this Activity.
4265     * @param resultData Result data (Intent), if any, from this Activity.
4266     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4267     *            the root Activity in the task.
4268     *
4269     * @return Returns true if the activity successfully finished, or false if it is still running.
4270     */
4271    @Override
4272    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4273            boolean finishTask) {
4274        // Refuse possible leaked file descriptors
4275        if (resultData != null && resultData.hasFileDescriptors() == true) {
4276            throw new IllegalArgumentException("File descriptors passed in Intent");
4277        }
4278
4279        synchronized(this) {
4280            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4281            if (r == null) {
4282                return true;
4283            }
4284            // Keep track of the root activity of the task before we finish it
4285            TaskRecord tr = r.task;
4286            ActivityRecord rootR = tr.getRootActivity();
4287            if (rootR == null) {
4288                Slog.w(TAG, "Finishing task with all activities already finished");
4289            }
4290            // Do not allow task to finish in Lock Task mode.
4291            if (tr == mStackSupervisor.mLockTaskModeTask) {
4292                if (rootR == r) {
4293                    Slog.i(TAG, "Not finishing task in lock task mode");
4294                    mStackSupervisor.showLockTaskToast();
4295                    return false;
4296                }
4297            }
4298            if (mController != null) {
4299                // Find the first activity that is not finishing.
4300                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4301                if (next != null) {
4302                    // ask watcher if this is allowed
4303                    boolean resumeOK = true;
4304                    try {
4305                        resumeOK = mController.activityResuming(next.packageName);
4306                    } catch (RemoteException e) {
4307                        mController = null;
4308                        Watchdog.getInstance().setActivityController(null);
4309                    }
4310
4311                    if (!resumeOK) {
4312                        Slog.i(TAG, "Not finishing activity because controller resumed");
4313                        return false;
4314                    }
4315                }
4316            }
4317            final long origId = Binder.clearCallingIdentity();
4318            try {
4319                boolean res;
4320                if (finishTask && r == rootR) {
4321                    // If requested, remove the task that is associated to this activity only if it
4322                    // was the root activity in the task. The result code and data is ignored
4323                    // because we don't support returning them across task boundaries.
4324                    res = removeTaskByIdLocked(tr.taskId, false);
4325                    if (!res) {
4326                        Slog.i(TAG, "Removing task failed to finish activity");
4327                    }
4328                } else {
4329                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4330                            resultData, "app-request", true);
4331                    if (!res) {
4332                        Slog.i(TAG, "Failed to finish by app-request");
4333                    }
4334                }
4335                return res;
4336            } finally {
4337                Binder.restoreCallingIdentity(origId);
4338            }
4339        }
4340    }
4341
4342    @Override
4343    public final void finishHeavyWeightApp() {
4344        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4345                != PackageManager.PERMISSION_GRANTED) {
4346            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4347                    + Binder.getCallingPid()
4348                    + ", uid=" + Binder.getCallingUid()
4349                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4350            Slog.w(TAG, msg);
4351            throw new SecurityException(msg);
4352        }
4353
4354        synchronized(this) {
4355            if (mHeavyWeightProcess == null) {
4356                return;
4357            }
4358
4359            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4360                    mHeavyWeightProcess.activities);
4361            for (int i=0; i<activities.size(); i++) {
4362                ActivityRecord r = activities.get(i);
4363                if (!r.finishing) {
4364                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4365                            null, "finish-heavy", true);
4366                }
4367            }
4368
4369            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4370                    mHeavyWeightProcess.userId, 0));
4371            mHeavyWeightProcess = null;
4372        }
4373    }
4374
4375    @Override
4376    public void crashApplication(int uid, int initialPid, String packageName,
4377            String message) {
4378        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4379                != PackageManager.PERMISSION_GRANTED) {
4380            String msg = "Permission Denial: crashApplication() from pid="
4381                    + Binder.getCallingPid()
4382                    + ", uid=" + Binder.getCallingUid()
4383                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4384            Slog.w(TAG, msg);
4385            throw new SecurityException(msg);
4386        }
4387
4388        synchronized(this) {
4389            ProcessRecord proc = null;
4390
4391            // Figure out which process to kill.  We don't trust that initialPid
4392            // still has any relation to current pids, so must scan through the
4393            // list.
4394            synchronized (mPidsSelfLocked) {
4395                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4396                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4397                    if (p.uid != uid) {
4398                        continue;
4399                    }
4400                    if (p.pid == initialPid) {
4401                        proc = p;
4402                        break;
4403                    }
4404                    if (p.pkgList.containsKey(packageName)) {
4405                        proc = p;
4406                    }
4407                }
4408            }
4409
4410            if (proc == null) {
4411                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4412                        + " initialPid=" + initialPid
4413                        + " packageName=" + packageName);
4414                return;
4415            }
4416
4417            if (proc.thread != null) {
4418                if (proc.pid == Process.myPid()) {
4419                    Log.w(TAG, "crashApplication: trying to crash self!");
4420                    return;
4421                }
4422                long ident = Binder.clearCallingIdentity();
4423                try {
4424                    proc.thread.scheduleCrash(message);
4425                } catch (RemoteException e) {
4426                }
4427                Binder.restoreCallingIdentity(ident);
4428            }
4429        }
4430    }
4431
4432    @Override
4433    public final void finishSubActivity(IBinder token, String resultWho,
4434            int requestCode) {
4435        synchronized(this) {
4436            final long origId = Binder.clearCallingIdentity();
4437            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4438            if (r != null) {
4439                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4440            }
4441            Binder.restoreCallingIdentity(origId);
4442        }
4443    }
4444
4445    @Override
4446    public boolean finishActivityAffinity(IBinder token) {
4447        synchronized(this) {
4448            final long origId = Binder.clearCallingIdentity();
4449            try {
4450                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4451
4452                ActivityRecord rootR = r.task.getRootActivity();
4453                // Do not allow task to finish in Lock Task mode.
4454                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4455                    if (rootR == r) {
4456                        mStackSupervisor.showLockTaskToast();
4457                        return false;
4458                    }
4459                }
4460                boolean res = false;
4461                if (r != null) {
4462                    res = r.task.stack.finishActivityAffinityLocked(r);
4463                }
4464                return res;
4465            } finally {
4466                Binder.restoreCallingIdentity(origId);
4467            }
4468        }
4469    }
4470
4471    @Override
4472    public void finishVoiceTask(IVoiceInteractionSession session) {
4473        synchronized(this) {
4474            final long origId = Binder.clearCallingIdentity();
4475            try {
4476                mStackSupervisor.finishVoiceTask(session);
4477            } finally {
4478                Binder.restoreCallingIdentity(origId);
4479            }
4480        }
4481
4482    }
4483
4484    @Override
4485    public boolean releaseActivityInstance(IBinder token) {
4486        synchronized(this) {
4487            final long origId = Binder.clearCallingIdentity();
4488            try {
4489                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4490                if (r.task == null || r.task.stack == null) {
4491                    return false;
4492                }
4493                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4494            } finally {
4495                Binder.restoreCallingIdentity(origId);
4496            }
4497        }
4498    }
4499
4500    @Override
4501    public void releaseSomeActivities(IApplicationThread appInt) {
4502        synchronized(this) {
4503            final long origId = Binder.clearCallingIdentity();
4504            try {
4505                ProcessRecord app = getRecordForAppLocked(appInt);
4506                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4507            } finally {
4508                Binder.restoreCallingIdentity(origId);
4509            }
4510        }
4511    }
4512
4513    @Override
4514    public boolean willActivityBeVisible(IBinder token) {
4515        synchronized(this) {
4516            ActivityStack stack = ActivityRecord.getStackLocked(token);
4517            if (stack != null) {
4518                return stack.willActivityBeVisibleLocked(token);
4519            }
4520            return false;
4521        }
4522    }
4523
4524    @Override
4525    public void overridePendingTransition(IBinder token, String packageName,
4526            int enterAnim, int exitAnim) {
4527        synchronized(this) {
4528            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4529            if (self == null) {
4530                return;
4531            }
4532
4533            final long origId = Binder.clearCallingIdentity();
4534
4535            if (self.state == ActivityState.RESUMED
4536                    || self.state == ActivityState.PAUSING) {
4537                mWindowManager.overridePendingAppTransition(packageName,
4538                        enterAnim, exitAnim, null);
4539            }
4540
4541            Binder.restoreCallingIdentity(origId);
4542        }
4543    }
4544
4545    /**
4546     * Main function for removing an existing process from the activity manager
4547     * as a result of that process going away.  Clears out all connections
4548     * to the process.
4549     */
4550    private final void handleAppDiedLocked(ProcessRecord app,
4551            boolean restarting, boolean allowRestart) {
4552        int pid = app.pid;
4553        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4554        if (!kept && !restarting) {
4555            removeLruProcessLocked(app);
4556            if (pid > 0) {
4557                ProcessList.remove(pid);
4558            }
4559        }
4560
4561        if (mProfileProc == app) {
4562            clearProfilerLocked();
4563        }
4564
4565        // Remove this application's activities from active lists.
4566        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4567
4568        app.activities.clear();
4569
4570        if (app.instrumentationClass != null) {
4571            Slog.w(TAG, "Crash of app " + app.processName
4572                  + " running instrumentation " + app.instrumentationClass);
4573            Bundle info = new Bundle();
4574            info.putString("shortMsg", "Process crashed.");
4575            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4576        }
4577
4578        if (!restarting) {
4579            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4580                // If there was nothing to resume, and we are not already
4581                // restarting this process, but there is a visible activity that
4582                // is hosted by the process...  then make sure all visible
4583                // activities are running, taking care of restarting this
4584                // process.
4585                if (hasVisibleActivities) {
4586                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4587                }
4588            }
4589        }
4590    }
4591
4592    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4593        IBinder threadBinder = thread.asBinder();
4594        // Find the application record.
4595        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4596            ProcessRecord rec = mLruProcesses.get(i);
4597            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4598                return i;
4599            }
4600        }
4601        return -1;
4602    }
4603
4604    final ProcessRecord getRecordForAppLocked(
4605            IApplicationThread thread) {
4606        if (thread == null) {
4607            return null;
4608        }
4609
4610        int appIndex = getLRURecordIndexForAppLocked(thread);
4611        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4612    }
4613
4614    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4615        // If there are no longer any background processes running,
4616        // and the app that died was not running instrumentation,
4617        // then tell everyone we are now low on memory.
4618        boolean haveBg = false;
4619        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4620            ProcessRecord rec = mLruProcesses.get(i);
4621            if (rec.thread != null
4622                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4623                haveBg = true;
4624                break;
4625            }
4626        }
4627
4628        if (!haveBg) {
4629            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4630            if (doReport) {
4631                long now = SystemClock.uptimeMillis();
4632                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4633                    doReport = false;
4634                } else {
4635                    mLastMemUsageReportTime = now;
4636                }
4637            }
4638            final ArrayList<ProcessMemInfo> memInfos
4639                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4640            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4641            long now = SystemClock.uptimeMillis();
4642            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4643                ProcessRecord rec = mLruProcesses.get(i);
4644                if (rec == dyingProc || rec.thread == null) {
4645                    continue;
4646                }
4647                if (doReport) {
4648                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4649                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4650                }
4651                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4652                    // The low memory report is overriding any current
4653                    // state for a GC request.  Make sure to do
4654                    // heavy/important/visible/foreground processes first.
4655                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4656                        rec.lastRequestedGc = 0;
4657                    } else {
4658                        rec.lastRequestedGc = rec.lastLowMemory;
4659                    }
4660                    rec.reportLowMemory = true;
4661                    rec.lastLowMemory = now;
4662                    mProcessesToGc.remove(rec);
4663                    addProcessToGcListLocked(rec);
4664                }
4665            }
4666            if (doReport) {
4667                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4668                mHandler.sendMessage(msg);
4669            }
4670            scheduleAppGcsLocked();
4671        }
4672    }
4673
4674    final void appDiedLocked(ProcessRecord app) {
4675       appDiedLocked(app, app.pid, app.thread);
4676    }
4677
4678    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4679        // First check if this ProcessRecord is actually active for the pid.
4680        synchronized (mPidsSelfLocked) {
4681            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4682            if (curProc != app) {
4683                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4684                return;
4685            }
4686        }
4687
4688        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4689        synchronized (stats) {
4690            stats.noteProcessDiedLocked(app.info.uid, pid);
4691        }
4692
4693        Process.killProcessQuiet(pid);
4694        Process.killProcessGroup(app.info.uid, pid);
4695        app.killed = true;
4696
4697        // Clean up already done if the process has been re-started.
4698        if (app.pid == pid && app.thread != null &&
4699                app.thread.asBinder() == thread.asBinder()) {
4700            boolean doLowMem = app.instrumentationClass == null;
4701            boolean doOomAdj = doLowMem;
4702            if (!app.killedByAm) {
4703                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4704                        + ") has died");
4705                mAllowLowerMemLevel = true;
4706            } else {
4707                // Note that we always want to do oom adj to update our state with the
4708                // new number of procs.
4709                mAllowLowerMemLevel = false;
4710                doLowMem = false;
4711            }
4712            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4713            if (DEBUG_CLEANUP) Slog.v(
4714                TAG, "Dying app: " + app + ", pid: " + pid
4715                + ", thread: " + thread.asBinder());
4716            handleAppDiedLocked(app, false, true);
4717
4718            if (doOomAdj) {
4719                updateOomAdjLocked();
4720            }
4721            if (doLowMem) {
4722                doLowMemReportIfNeededLocked(app);
4723            }
4724        } else if (app.pid != pid) {
4725            // A new process has already been started.
4726            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4727                    + ") has died and restarted (pid " + app.pid + ").");
4728            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4729        } else if (DEBUG_PROCESSES) {
4730            Slog.d(TAG, "Received spurious death notification for thread "
4731                    + thread.asBinder());
4732        }
4733    }
4734
4735    /**
4736     * If a stack trace dump file is configured, dump process stack traces.
4737     * @param clearTraces causes the dump file to be erased prior to the new
4738     *    traces being written, if true; when false, the new traces will be
4739     *    appended to any existing file content.
4740     * @param firstPids of dalvik VM processes to dump stack traces for first
4741     * @param lastPids of dalvik VM processes to dump stack traces for last
4742     * @param nativeProcs optional list of native process names to dump stack crawls
4743     * @return file containing stack traces, or null if no dump file is configured
4744     */
4745    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4746            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4747        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4748        if (tracesPath == null || tracesPath.length() == 0) {
4749            return null;
4750        }
4751
4752        File tracesFile = new File(tracesPath);
4753        try {
4754            File tracesDir = tracesFile.getParentFile();
4755            if (!tracesDir.exists()) {
4756                tracesDir.mkdirs();
4757                if (!SELinux.restorecon(tracesDir)) {
4758                    return null;
4759                }
4760            }
4761            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4762
4763            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4764            tracesFile.createNewFile();
4765            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4766        } catch (IOException e) {
4767            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4768            return null;
4769        }
4770
4771        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4772        return tracesFile;
4773    }
4774
4775    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4776            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4777        // Use a FileObserver to detect when traces finish writing.
4778        // The order of traces is considered important to maintain for legibility.
4779        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4780            @Override
4781            public synchronized void onEvent(int event, String path) { notify(); }
4782        };
4783
4784        try {
4785            observer.startWatching();
4786
4787            // First collect all of the stacks of the most important pids.
4788            if (firstPids != null) {
4789                try {
4790                    int num = firstPids.size();
4791                    for (int i = 0; i < num; i++) {
4792                        synchronized (observer) {
4793                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4794                            observer.wait(200);  // Wait for write-close, give up after 200msec
4795                        }
4796                    }
4797                } catch (InterruptedException e) {
4798                    Slog.wtf(TAG, e);
4799                }
4800            }
4801
4802            // Next collect the stacks of the native pids
4803            if (nativeProcs != null) {
4804                int[] pids = Process.getPidsForCommands(nativeProcs);
4805                if (pids != null) {
4806                    for (int pid : pids) {
4807                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4808                    }
4809                }
4810            }
4811
4812            // Lastly, measure CPU usage.
4813            if (processCpuTracker != null) {
4814                processCpuTracker.init();
4815                System.gc();
4816                processCpuTracker.update();
4817                try {
4818                    synchronized (processCpuTracker) {
4819                        processCpuTracker.wait(500); // measure over 1/2 second.
4820                    }
4821                } catch (InterruptedException e) {
4822                }
4823                processCpuTracker.update();
4824
4825                // We'll take the stack crawls of just the top apps using CPU.
4826                final int N = processCpuTracker.countWorkingStats();
4827                int numProcs = 0;
4828                for (int i=0; i<N && numProcs<5; i++) {
4829                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4830                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4831                        numProcs++;
4832                        try {
4833                            synchronized (observer) {
4834                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4835                                observer.wait(200);  // Wait for write-close, give up after 200msec
4836                            }
4837                        } catch (InterruptedException e) {
4838                            Slog.wtf(TAG, e);
4839                        }
4840
4841                    }
4842                }
4843            }
4844        } finally {
4845            observer.stopWatching();
4846        }
4847    }
4848
4849    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4850        if (true || IS_USER_BUILD) {
4851            return;
4852        }
4853        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4854        if (tracesPath == null || tracesPath.length() == 0) {
4855            return;
4856        }
4857
4858        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4859        StrictMode.allowThreadDiskWrites();
4860        try {
4861            final File tracesFile = new File(tracesPath);
4862            final File tracesDir = tracesFile.getParentFile();
4863            final File tracesTmp = new File(tracesDir, "__tmp__");
4864            try {
4865                if (!tracesDir.exists()) {
4866                    tracesDir.mkdirs();
4867                    if (!SELinux.restorecon(tracesDir.getPath())) {
4868                        return;
4869                    }
4870                }
4871                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4872
4873                if (tracesFile.exists()) {
4874                    tracesTmp.delete();
4875                    tracesFile.renameTo(tracesTmp);
4876                }
4877                StringBuilder sb = new StringBuilder();
4878                Time tobj = new Time();
4879                tobj.set(System.currentTimeMillis());
4880                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4881                sb.append(": ");
4882                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4883                sb.append(" since ");
4884                sb.append(msg);
4885                FileOutputStream fos = new FileOutputStream(tracesFile);
4886                fos.write(sb.toString().getBytes());
4887                if (app == null) {
4888                    fos.write("\n*** No application process!".getBytes());
4889                }
4890                fos.close();
4891                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4892            } catch (IOException e) {
4893                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4894                return;
4895            }
4896
4897            if (app != null) {
4898                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4899                firstPids.add(app.pid);
4900                dumpStackTraces(tracesPath, firstPids, null, null, null);
4901            }
4902
4903            File lastTracesFile = null;
4904            File curTracesFile = null;
4905            for (int i=9; i>=0; i--) {
4906                String name = String.format(Locale.US, "slow%02d.txt", i);
4907                curTracesFile = new File(tracesDir, name);
4908                if (curTracesFile.exists()) {
4909                    if (lastTracesFile != null) {
4910                        curTracesFile.renameTo(lastTracesFile);
4911                    } else {
4912                        curTracesFile.delete();
4913                    }
4914                }
4915                lastTracesFile = curTracesFile;
4916            }
4917            tracesFile.renameTo(curTracesFile);
4918            if (tracesTmp.exists()) {
4919                tracesTmp.renameTo(tracesFile);
4920            }
4921        } finally {
4922            StrictMode.setThreadPolicy(oldPolicy);
4923        }
4924    }
4925
4926    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4927            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4928        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4929        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4930
4931        if (mController != null) {
4932            try {
4933                // 0 == continue, -1 = kill process immediately
4934                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4935                if (res < 0 && app.pid != MY_PID) {
4936                    app.kill("anr", true);
4937                }
4938            } catch (RemoteException e) {
4939                mController = null;
4940                Watchdog.getInstance().setActivityController(null);
4941            }
4942        }
4943
4944        long anrTime = SystemClock.uptimeMillis();
4945        if (MONITOR_CPU_USAGE) {
4946            updateCpuStatsNow();
4947        }
4948
4949        synchronized (this) {
4950            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4951            if (mShuttingDown) {
4952                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4953                return;
4954            } else if (app.notResponding) {
4955                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4956                return;
4957            } else if (app.crashing) {
4958                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4959                return;
4960            }
4961
4962            // In case we come through here for the same app before completing
4963            // this one, mark as anring now so we will bail out.
4964            app.notResponding = true;
4965
4966            // Log the ANR to the event log.
4967            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4968                    app.processName, app.info.flags, annotation);
4969
4970            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4971            firstPids.add(app.pid);
4972
4973            int parentPid = app.pid;
4974            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4975            if (parentPid != app.pid) firstPids.add(parentPid);
4976
4977            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4978
4979            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4980                ProcessRecord r = mLruProcesses.get(i);
4981                if (r != null && r.thread != null) {
4982                    int pid = r.pid;
4983                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4984                        if (r.persistent) {
4985                            firstPids.add(pid);
4986                        } else {
4987                            lastPids.put(pid, Boolean.TRUE);
4988                        }
4989                    }
4990                }
4991            }
4992        }
4993
4994        // Log the ANR to the main log.
4995        StringBuilder info = new StringBuilder();
4996        info.setLength(0);
4997        info.append("ANR in ").append(app.processName);
4998        if (activity != null && activity.shortComponentName != null) {
4999            info.append(" (").append(activity.shortComponentName).append(")");
5000        }
5001        info.append("\n");
5002        info.append("PID: ").append(app.pid).append("\n");
5003        if (annotation != null) {
5004            info.append("Reason: ").append(annotation).append("\n");
5005        }
5006        if (parent != null && parent != activity) {
5007            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5008        }
5009
5010        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5011
5012        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5013                NATIVE_STACKS_OF_INTEREST);
5014
5015        String cpuInfo = null;
5016        if (MONITOR_CPU_USAGE) {
5017            updateCpuStatsNow();
5018            synchronized (mProcessCpuTracker) {
5019                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5020            }
5021            info.append(processCpuTracker.printCurrentLoad());
5022            info.append(cpuInfo);
5023        }
5024
5025        info.append(processCpuTracker.printCurrentState(anrTime));
5026
5027        Slog.e(TAG, info.toString());
5028        if (tracesFile == null) {
5029            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5030            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5031        }
5032
5033        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5034                cpuInfo, tracesFile, null);
5035
5036        if (mController != null) {
5037            try {
5038                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5039                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5040                if (res != 0) {
5041                    if (res < 0 && app.pid != MY_PID) {
5042                        app.kill("anr", true);
5043                    } else {
5044                        synchronized (this) {
5045                            mServices.scheduleServiceTimeoutLocked(app);
5046                        }
5047                    }
5048                    return;
5049                }
5050            } catch (RemoteException e) {
5051                mController = null;
5052                Watchdog.getInstance().setActivityController(null);
5053            }
5054        }
5055
5056        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5057        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5058                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5059
5060        synchronized (this) {
5061            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5062                app.kill("bg anr", true);
5063                return;
5064            }
5065
5066            // Set the app's notResponding state, and look up the errorReportReceiver
5067            makeAppNotRespondingLocked(app,
5068                    activity != null ? activity.shortComponentName : null,
5069                    annotation != null ? "ANR " + annotation : "ANR",
5070                    info.toString());
5071
5072            // Bring up the infamous App Not Responding dialog
5073            Message msg = Message.obtain();
5074            HashMap<String, Object> map = new HashMap<String, Object>();
5075            msg.what = SHOW_NOT_RESPONDING_MSG;
5076            msg.obj = map;
5077            msg.arg1 = aboveSystem ? 1 : 0;
5078            map.put("app", app);
5079            if (activity != null) {
5080                map.put("activity", activity);
5081            }
5082
5083            mHandler.sendMessage(msg);
5084        }
5085    }
5086
5087    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5088        if (!mLaunchWarningShown) {
5089            mLaunchWarningShown = true;
5090            mHandler.post(new Runnable() {
5091                @Override
5092                public void run() {
5093                    synchronized (ActivityManagerService.this) {
5094                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5095                        d.show();
5096                        mHandler.postDelayed(new Runnable() {
5097                            @Override
5098                            public void run() {
5099                                synchronized (ActivityManagerService.this) {
5100                                    d.dismiss();
5101                                    mLaunchWarningShown = false;
5102                                }
5103                            }
5104                        }, 4000);
5105                    }
5106                }
5107            });
5108        }
5109    }
5110
5111    @Override
5112    public boolean clearApplicationUserData(final String packageName,
5113            final IPackageDataObserver observer, int userId) {
5114        enforceNotIsolatedCaller("clearApplicationUserData");
5115        int uid = Binder.getCallingUid();
5116        int pid = Binder.getCallingPid();
5117        userId = handleIncomingUser(pid, uid,
5118                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5119        long callingId = Binder.clearCallingIdentity();
5120        try {
5121            IPackageManager pm = AppGlobals.getPackageManager();
5122            int pkgUid = -1;
5123            synchronized(this) {
5124                try {
5125                    pkgUid = pm.getPackageUid(packageName, userId);
5126                } catch (RemoteException e) {
5127                }
5128                if (pkgUid == -1) {
5129                    Slog.w(TAG, "Invalid packageName: " + packageName);
5130                    if (observer != null) {
5131                        try {
5132                            observer.onRemoveCompleted(packageName, false);
5133                        } catch (RemoteException e) {
5134                            Slog.i(TAG, "Observer no longer exists.");
5135                        }
5136                    }
5137                    return false;
5138                }
5139                if (uid == pkgUid || checkComponentPermission(
5140                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5141                        pid, uid, -1, true)
5142                        == PackageManager.PERMISSION_GRANTED) {
5143                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5144                } else {
5145                    throw new SecurityException("PID " + pid + " does not have permission "
5146                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5147                                    + " of package " + packageName);
5148                }
5149
5150                // Remove all tasks match the cleared application package and user
5151                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5152                    final TaskRecord tr = mRecentTasks.get(i);
5153                    final String taskPackageName =
5154                            tr.getBaseIntent().getComponent().getPackageName();
5155                    if (tr.userId != userId) continue;
5156                    if (!taskPackageName.equals(packageName)) continue;
5157                    removeTaskByIdLocked(tr.taskId, false);
5158                }
5159            }
5160
5161            try {
5162                // Clear application user data
5163                pm.clearApplicationUserData(packageName, observer, userId);
5164
5165                synchronized(this) {
5166                    // Remove all permissions granted from/to this package
5167                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5168                }
5169
5170                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5171                        Uri.fromParts("package", packageName, null));
5172                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5173                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5174                        null, null, 0, null, null, null, false, false, userId);
5175            } catch (RemoteException e) {
5176            }
5177        } finally {
5178            Binder.restoreCallingIdentity(callingId);
5179        }
5180        return true;
5181    }
5182
5183    @Override
5184    public void killBackgroundProcesses(final String packageName, int userId) {
5185        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5186                != PackageManager.PERMISSION_GRANTED &&
5187                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5188                        != PackageManager.PERMISSION_GRANTED) {
5189            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5190                    + Binder.getCallingPid()
5191                    + ", uid=" + Binder.getCallingUid()
5192                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5193            Slog.w(TAG, msg);
5194            throw new SecurityException(msg);
5195        }
5196
5197        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5198                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5199        long callingId = Binder.clearCallingIdentity();
5200        try {
5201            IPackageManager pm = AppGlobals.getPackageManager();
5202            synchronized(this) {
5203                int appId = -1;
5204                try {
5205                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5206                } catch (RemoteException e) {
5207                }
5208                if (appId == -1) {
5209                    Slog.w(TAG, "Invalid packageName: " + packageName);
5210                    return;
5211                }
5212                killPackageProcessesLocked(packageName, appId, userId,
5213                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5214            }
5215        } finally {
5216            Binder.restoreCallingIdentity(callingId);
5217        }
5218    }
5219
5220    @Override
5221    public void killAllBackgroundProcesses() {
5222        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5223                != PackageManager.PERMISSION_GRANTED) {
5224            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5225                    + Binder.getCallingPid()
5226                    + ", uid=" + Binder.getCallingUid()
5227                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5228            Slog.w(TAG, msg);
5229            throw new SecurityException(msg);
5230        }
5231
5232        long callingId = Binder.clearCallingIdentity();
5233        try {
5234            synchronized(this) {
5235                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5236                final int NP = mProcessNames.getMap().size();
5237                for (int ip=0; ip<NP; ip++) {
5238                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5239                    final int NA = apps.size();
5240                    for (int ia=0; ia<NA; ia++) {
5241                        ProcessRecord app = apps.valueAt(ia);
5242                        if (app.persistent) {
5243                            // we don't kill persistent processes
5244                            continue;
5245                        }
5246                        if (app.removed) {
5247                            procs.add(app);
5248                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5249                            app.removed = true;
5250                            procs.add(app);
5251                        }
5252                    }
5253                }
5254
5255                int N = procs.size();
5256                for (int i=0; i<N; i++) {
5257                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5258                }
5259                mAllowLowerMemLevel = true;
5260                updateOomAdjLocked();
5261                doLowMemReportIfNeededLocked(null);
5262            }
5263        } finally {
5264            Binder.restoreCallingIdentity(callingId);
5265        }
5266    }
5267
5268    @Override
5269    public void forceStopPackage(final String packageName, int userId) {
5270        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5271                != PackageManager.PERMISSION_GRANTED) {
5272            String msg = "Permission Denial: forceStopPackage() from pid="
5273                    + Binder.getCallingPid()
5274                    + ", uid=" + Binder.getCallingUid()
5275                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5276            Slog.w(TAG, msg);
5277            throw new SecurityException(msg);
5278        }
5279        final int callingPid = Binder.getCallingPid();
5280        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5281                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5282        long callingId = Binder.clearCallingIdentity();
5283        try {
5284            IPackageManager pm = AppGlobals.getPackageManager();
5285            synchronized(this) {
5286                int[] users = userId == UserHandle.USER_ALL
5287                        ? getUsersLocked() : new int[] { userId };
5288                for (int user : users) {
5289                    int pkgUid = -1;
5290                    try {
5291                        pkgUid = pm.getPackageUid(packageName, user);
5292                    } catch (RemoteException e) {
5293                    }
5294                    if (pkgUid == -1) {
5295                        Slog.w(TAG, "Invalid packageName: " + packageName);
5296                        continue;
5297                    }
5298                    try {
5299                        pm.setPackageStoppedState(packageName, true, user);
5300                    } catch (RemoteException e) {
5301                    } catch (IllegalArgumentException e) {
5302                        Slog.w(TAG, "Failed trying to unstop package "
5303                                + packageName + ": " + e);
5304                    }
5305                    if (isUserRunningLocked(user, false)) {
5306                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5307                    }
5308                }
5309            }
5310        } finally {
5311            Binder.restoreCallingIdentity(callingId);
5312        }
5313    }
5314
5315    @Override
5316    public void addPackageDependency(String packageName) {
5317        synchronized (this) {
5318            int callingPid = Binder.getCallingPid();
5319            if (callingPid == Process.myPid()) {
5320                //  Yeah, um, no.
5321                Slog.w(TAG, "Can't addPackageDependency on system process");
5322                return;
5323            }
5324            ProcessRecord proc;
5325            synchronized (mPidsSelfLocked) {
5326                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5327            }
5328            if (proc != null) {
5329                if (proc.pkgDeps == null) {
5330                    proc.pkgDeps = new ArraySet<String>(1);
5331                }
5332                proc.pkgDeps.add(packageName);
5333            }
5334        }
5335    }
5336
5337    /*
5338     * The pkg name and app id have to be specified.
5339     */
5340    @Override
5341    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5342        if (pkg == null) {
5343            return;
5344        }
5345        // Make sure the uid is valid.
5346        if (appid < 0) {
5347            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5348            return;
5349        }
5350        int callerUid = Binder.getCallingUid();
5351        // Only the system server can kill an application
5352        if (callerUid == Process.SYSTEM_UID) {
5353            // Post an aysnc message to kill the application
5354            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5355            msg.arg1 = appid;
5356            msg.arg2 = 0;
5357            Bundle bundle = new Bundle();
5358            bundle.putString("pkg", pkg);
5359            bundle.putString("reason", reason);
5360            msg.obj = bundle;
5361            mHandler.sendMessage(msg);
5362        } else {
5363            throw new SecurityException(callerUid + " cannot kill pkg: " +
5364                    pkg);
5365        }
5366    }
5367
5368    @Override
5369    public void closeSystemDialogs(String reason) {
5370        enforceNotIsolatedCaller("closeSystemDialogs");
5371
5372        final int pid = Binder.getCallingPid();
5373        final int uid = Binder.getCallingUid();
5374        final long origId = Binder.clearCallingIdentity();
5375        try {
5376            synchronized (this) {
5377                // Only allow this from foreground processes, so that background
5378                // applications can't abuse it to prevent system UI from being shown.
5379                if (uid >= Process.FIRST_APPLICATION_UID) {
5380                    ProcessRecord proc;
5381                    synchronized (mPidsSelfLocked) {
5382                        proc = mPidsSelfLocked.get(pid);
5383                    }
5384                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5385                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5386                                + " from background process " + proc);
5387                        return;
5388                    }
5389                }
5390                closeSystemDialogsLocked(reason);
5391            }
5392        } finally {
5393            Binder.restoreCallingIdentity(origId);
5394        }
5395    }
5396
5397    void closeSystemDialogsLocked(String reason) {
5398        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5399        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5400                | Intent.FLAG_RECEIVER_FOREGROUND);
5401        if (reason != null) {
5402            intent.putExtra("reason", reason);
5403        }
5404        mWindowManager.closeSystemDialogs(reason);
5405
5406        mStackSupervisor.closeSystemDialogsLocked();
5407
5408        broadcastIntentLocked(null, null, intent, null,
5409                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5410                Process.SYSTEM_UID, UserHandle.USER_ALL);
5411    }
5412
5413    @Override
5414    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5415        enforceNotIsolatedCaller("getProcessMemoryInfo");
5416        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5417        for (int i=pids.length-1; i>=0; i--) {
5418            ProcessRecord proc;
5419            int oomAdj;
5420            synchronized (this) {
5421                synchronized (mPidsSelfLocked) {
5422                    proc = mPidsSelfLocked.get(pids[i]);
5423                    oomAdj = proc != null ? proc.setAdj : 0;
5424                }
5425            }
5426            infos[i] = new Debug.MemoryInfo();
5427            Debug.getMemoryInfo(pids[i], infos[i]);
5428            if (proc != null) {
5429                synchronized (this) {
5430                    if (proc.thread != null && proc.setAdj == oomAdj) {
5431                        // Record this for posterity if the process has been stable.
5432                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5433                                infos[i].getTotalUss(), false, proc.pkgList);
5434                    }
5435                }
5436            }
5437        }
5438        return infos;
5439    }
5440
5441    @Override
5442    public long[] getProcessPss(int[] pids) {
5443        enforceNotIsolatedCaller("getProcessPss");
5444        long[] pss = new long[pids.length];
5445        for (int i=pids.length-1; i>=0; i--) {
5446            ProcessRecord proc;
5447            int oomAdj;
5448            synchronized (this) {
5449                synchronized (mPidsSelfLocked) {
5450                    proc = mPidsSelfLocked.get(pids[i]);
5451                    oomAdj = proc != null ? proc.setAdj : 0;
5452                }
5453            }
5454            long[] tmpUss = new long[1];
5455            pss[i] = Debug.getPss(pids[i], tmpUss);
5456            if (proc != null) {
5457                synchronized (this) {
5458                    if (proc.thread != null && proc.setAdj == oomAdj) {
5459                        // Record this for posterity if the process has been stable.
5460                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5461                    }
5462                }
5463            }
5464        }
5465        return pss;
5466    }
5467
5468    @Override
5469    public void killApplicationProcess(String processName, int uid) {
5470        if (processName == null) {
5471            return;
5472        }
5473
5474        int callerUid = Binder.getCallingUid();
5475        // Only the system server can kill an application
5476        if (callerUid == Process.SYSTEM_UID) {
5477            synchronized (this) {
5478                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5479                if (app != null && app.thread != null) {
5480                    try {
5481                        app.thread.scheduleSuicide();
5482                    } catch (RemoteException e) {
5483                        // If the other end already died, then our work here is done.
5484                    }
5485                } else {
5486                    Slog.w(TAG, "Process/uid not found attempting kill of "
5487                            + processName + " / " + uid);
5488                }
5489            }
5490        } else {
5491            throw new SecurityException(callerUid + " cannot kill app process: " +
5492                    processName);
5493        }
5494    }
5495
5496    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5497        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5498                false, true, false, false, UserHandle.getUserId(uid), reason);
5499        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5500                Uri.fromParts("package", packageName, null));
5501        if (!mProcessesReady) {
5502            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5503                    | Intent.FLAG_RECEIVER_FOREGROUND);
5504        }
5505        intent.putExtra(Intent.EXTRA_UID, uid);
5506        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5507        broadcastIntentLocked(null, null, intent,
5508                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5509                false, false,
5510                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5511    }
5512
5513    private void forceStopUserLocked(int userId, String reason) {
5514        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5515        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5516        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5517                | Intent.FLAG_RECEIVER_FOREGROUND);
5518        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5519        broadcastIntentLocked(null, null, intent,
5520                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5521                false, false,
5522                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5523    }
5524
5525    private final boolean killPackageProcessesLocked(String packageName, int appId,
5526            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5527            boolean doit, boolean evenPersistent, String reason) {
5528        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5529
5530        // Remove all processes this package may have touched: all with the
5531        // same UID (except for the system or root user), and all whose name
5532        // matches the package name.
5533        final int NP = mProcessNames.getMap().size();
5534        for (int ip=0; ip<NP; ip++) {
5535            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5536            final int NA = apps.size();
5537            for (int ia=0; ia<NA; ia++) {
5538                ProcessRecord app = apps.valueAt(ia);
5539                if (app.persistent && !evenPersistent) {
5540                    // we don't kill persistent processes
5541                    continue;
5542                }
5543                if (app.removed) {
5544                    if (doit) {
5545                        procs.add(app);
5546                    }
5547                    continue;
5548                }
5549
5550                // Skip process if it doesn't meet our oom adj requirement.
5551                if (app.setAdj < minOomAdj) {
5552                    continue;
5553                }
5554
5555                // If no package is specified, we call all processes under the
5556                // give user id.
5557                if (packageName == null) {
5558                    if (app.userId != userId) {
5559                        continue;
5560                    }
5561                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5562                        continue;
5563                    }
5564                // Package has been specified, we want to hit all processes
5565                // that match it.  We need to qualify this by the processes
5566                // that are running under the specified app and user ID.
5567                } else {
5568                    final boolean isDep = app.pkgDeps != null
5569                            && app.pkgDeps.contains(packageName);
5570                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5571                        continue;
5572                    }
5573                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5574                        continue;
5575                    }
5576                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5577                        continue;
5578                    }
5579                }
5580
5581                // Process has passed all conditions, kill it!
5582                if (!doit) {
5583                    return true;
5584                }
5585                app.removed = true;
5586                procs.add(app);
5587            }
5588        }
5589
5590        int N = procs.size();
5591        for (int i=0; i<N; i++) {
5592            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5593        }
5594        updateOomAdjLocked();
5595        return N > 0;
5596    }
5597
5598    private final boolean forceStopPackageLocked(String name, int appId,
5599            boolean callerWillRestart, boolean purgeCache, boolean doit,
5600            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5601        int i;
5602        int N;
5603
5604        if (userId == UserHandle.USER_ALL && name == null) {
5605            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5606        }
5607
5608        if (appId < 0 && name != null) {
5609            try {
5610                appId = UserHandle.getAppId(
5611                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5612            } catch (RemoteException e) {
5613            }
5614        }
5615
5616        if (doit) {
5617            if (name != null) {
5618                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5619                        + " user=" + userId + ": " + reason);
5620            } else {
5621                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5622            }
5623
5624            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5625            for (int ip=pmap.size()-1; ip>=0; ip--) {
5626                SparseArray<Long> ba = pmap.valueAt(ip);
5627                for (i=ba.size()-1; i>=0; i--) {
5628                    boolean remove = false;
5629                    final int entUid = ba.keyAt(i);
5630                    if (name != null) {
5631                        if (userId == UserHandle.USER_ALL) {
5632                            if (UserHandle.getAppId(entUid) == appId) {
5633                                remove = true;
5634                            }
5635                        } else {
5636                            if (entUid == UserHandle.getUid(userId, appId)) {
5637                                remove = true;
5638                            }
5639                        }
5640                    } else if (UserHandle.getUserId(entUid) == userId) {
5641                        remove = true;
5642                    }
5643                    if (remove) {
5644                        ba.removeAt(i);
5645                    }
5646                }
5647                if (ba.size() == 0) {
5648                    pmap.removeAt(ip);
5649                }
5650            }
5651        }
5652
5653        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5654                -100, callerWillRestart, true, doit, evenPersistent,
5655                name == null ? ("stop user " + userId) : ("stop " + name));
5656
5657        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5658            if (!doit) {
5659                return true;
5660            }
5661            didSomething = true;
5662        }
5663
5664        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5665            if (!doit) {
5666                return true;
5667            }
5668            didSomething = true;
5669        }
5670
5671        if (name == null) {
5672            // Remove all sticky broadcasts from this user.
5673            mStickyBroadcasts.remove(userId);
5674        }
5675
5676        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5677        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5678                userId, providers)) {
5679            if (!doit) {
5680                return true;
5681            }
5682            didSomething = true;
5683        }
5684        N = providers.size();
5685        for (i=0; i<N; i++) {
5686            removeDyingProviderLocked(null, providers.get(i), true);
5687        }
5688
5689        // Remove transient permissions granted from/to this package/user
5690        removeUriPermissionsForPackageLocked(name, userId, false);
5691
5692        if (name == null || uninstalling) {
5693            // Remove pending intents.  For now we only do this when force
5694            // stopping users, because we have some problems when doing this
5695            // for packages -- app widgets are not currently cleaned up for
5696            // such packages, so they can be left with bad pending intents.
5697            if (mIntentSenderRecords.size() > 0) {
5698                Iterator<WeakReference<PendingIntentRecord>> it
5699                        = mIntentSenderRecords.values().iterator();
5700                while (it.hasNext()) {
5701                    WeakReference<PendingIntentRecord> wpir = it.next();
5702                    if (wpir == null) {
5703                        it.remove();
5704                        continue;
5705                    }
5706                    PendingIntentRecord pir = wpir.get();
5707                    if (pir == null) {
5708                        it.remove();
5709                        continue;
5710                    }
5711                    if (name == null) {
5712                        // Stopping user, remove all objects for the user.
5713                        if (pir.key.userId != userId) {
5714                            // Not the same user, skip it.
5715                            continue;
5716                        }
5717                    } else {
5718                        if (UserHandle.getAppId(pir.uid) != appId) {
5719                            // Different app id, skip it.
5720                            continue;
5721                        }
5722                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5723                            // Different user, skip it.
5724                            continue;
5725                        }
5726                        if (!pir.key.packageName.equals(name)) {
5727                            // Different package, skip it.
5728                            continue;
5729                        }
5730                    }
5731                    if (!doit) {
5732                        return true;
5733                    }
5734                    didSomething = true;
5735                    it.remove();
5736                    pir.canceled = true;
5737                    if (pir.key.activity != null) {
5738                        pir.key.activity.pendingResults.remove(pir.ref);
5739                    }
5740                }
5741            }
5742        }
5743
5744        if (doit) {
5745            if (purgeCache && name != null) {
5746                AttributeCache ac = AttributeCache.instance();
5747                if (ac != null) {
5748                    ac.removePackage(name);
5749                }
5750            }
5751            if (mBooted) {
5752                mStackSupervisor.resumeTopActivitiesLocked();
5753                mStackSupervisor.scheduleIdleLocked();
5754            }
5755        }
5756
5757        return didSomething;
5758    }
5759
5760    private final boolean removeProcessLocked(ProcessRecord app,
5761            boolean callerWillRestart, boolean allowRestart, String reason) {
5762        final String name = app.processName;
5763        final int uid = app.uid;
5764        if (DEBUG_PROCESSES) Slog.d(
5765            TAG, "Force removing proc " + app.toShortString() + " (" + name
5766            + "/" + uid + ")");
5767
5768        mProcessNames.remove(name, uid);
5769        mIsolatedProcesses.remove(app.uid);
5770        if (mHeavyWeightProcess == app) {
5771            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5772                    mHeavyWeightProcess.userId, 0));
5773            mHeavyWeightProcess = null;
5774        }
5775        boolean needRestart = false;
5776        if (app.pid > 0 && app.pid != MY_PID) {
5777            int pid = app.pid;
5778            synchronized (mPidsSelfLocked) {
5779                mPidsSelfLocked.remove(pid);
5780                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5781            }
5782            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5783            if (app.isolated) {
5784                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5785            }
5786            app.kill(reason, true);
5787            handleAppDiedLocked(app, true, allowRestart);
5788            removeLruProcessLocked(app);
5789
5790            if (app.persistent && !app.isolated) {
5791                if (!callerWillRestart) {
5792                    addAppLocked(app.info, false, null /* ABI override */);
5793                } else {
5794                    needRestart = true;
5795                }
5796            }
5797        } else {
5798            mRemovedProcesses.add(app);
5799        }
5800
5801        return needRestart;
5802    }
5803
5804    private final void processStartTimedOutLocked(ProcessRecord app) {
5805        final int pid = app.pid;
5806        boolean gone = false;
5807        synchronized (mPidsSelfLocked) {
5808            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5809            if (knownApp != null && knownApp.thread == null) {
5810                mPidsSelfLocked.remove(pid);
5811                gone = true;
5812            }
5813        }
5814
5815        if (gone) {
5816            Slog.w(TAG, "Process " + app + " failed to attach");
5817            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5818                    pid, app.uid, app.processName);
5819            mProcessNames.remove(app.processName, app.uid);
5820            mIsolatedProcesses.remove(app.uid);
5821            if (mHeavyWeightProcess == app) {
5822                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5823                        mHeavyWeightProcess.userId, 0));
5824                mHeavyWeightProcess = null;
5825            }
5826            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5827            if (app.isolated) {
5828                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5829            }
5830            // Take care of any launching providers waiting for this process.
5831            checkAppInLaunchingProvidersLocked(app, true);
5832            // Take care of any services that are waiting for the process.
5833            mServices.processStartTimedOutLocked(app);
5834            app.kill("start timeout", true);
5835            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5836                Slog.w(TAG, "Unattached app died before backup, skipping");
5837                try {
5838                    IBackupManager bm = IBackupManager.Stub.asInterface(
5839                            ServiceManager.getService(Context.BACKUP_SERVICE));
5840                    bm.agentDisconnected(app.info.packageName);
5841                } catch (RemoteException e) {
5842                    // Can't happen; the backup manager is local
5843                }
5844            }
5845            if (isPendingBroadcastProcessLocked(pid)) {
5846                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5847                skipPendingBroadcastLocked(pid);
5848            }
5849        } else {
5850            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5851        }
5852    }
5853
5854    private final boolean attachApplicationLocked(IApplicationThread thread,
5855            int pid) {
5856
5857        // Find the application record that is being attached...  either via
5858        // the pid if we are running in multiple processes, or just pull the
5859        // next app record if we are emulating process with anonymous threads.
5860        ProcessRecord app;
5861        if (pid != MY_PID && pid >= 0) {
5862            synchronized (mPidsSelfLocked) {
5863                app = mPidsSelfLocked.get(pid);
5864            }
5865        } else {
5866            app = null;
5867        }
5868
5869        if (app == null) {
5870            Slog.w(TAG, "No pending application record for pid " + pid
5871                    + " (IApplicationThread " + thread + "); dropping process");
5872            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5873            if (pid > 0 && pid != MY_PID) {
5874                Process.killProcessQuiet(pid);
5875                //TODO: Process.killProcessGroup(app.info.uid, pid);
5876            } else {
5877                try {
5878                    thread.scheduleExit();
5879                } catch (Exception e) {
5880                    // Ignore exceptions.
5881                }
5882            }
5883            return false;
5884        }
5885
5886        // If this application record is still attached to a previous
5887        // process, clean it up now.
5888        if (app.thread != null) {
5889            handleAppDiedLocked(app, true, true);
5890        }
5891
5892        // Tell the process all about itself.
5893
5894        if (localLOGV) Slog.v(
5895                TAG, "Binding process pid " + pid + " to record " + app);
5896
5897        final String processName = app.processName;
5898        try {
5899            AppDeathRecipient adr = new AppDeathRecipient(
5900                    app, pid, thread);
5901            thread.asBinder().linkToDeath(adr, 0);
5902            app.deathRecipient = adr;
5903        } catch (RemoteException e) {
5904            app.resetPackageList(mProcessStats);
5905            startProcessLocked(app, "link fail", processName);
5906            return false;
5907        }
5908
5909        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5910
5911        app.makeActive(thread, mProcessStats);
5912        app.curAdj = app.setAdj = -100;
5913        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5914        app.forcingToForeground = null;
5915        updateProcessForegroundLocked(app, false, false);
5916        app.hasShownUi = false;
5917        app.debugging = false;
5918        app.cached = false;
5919
5920        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5921
5922        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5923        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5924
5925        if (!normalMode) {
5926            Slog.i(TAG, "Launching preboot mode app: " + app);
5927        }
5928
5929        if (localLOGV) Slog.v(
5930            TAG, "New app record " + app
5931            + " thread=" + thread.asBinder() + " pid=" + pid);
5932        try {
5933            int testMode = IApplicationThread.DEBUG_OFF;
5934            if (mDebugApp != null && mDebugApp.equals(processName)) {
5935                testMode = mWaitForDebugger
5936                    ? IApplicationThread.DEBUG_WAIT
5937                    : IApplicationThread.DEBUG_ON;
5938                app.debugging = true;
5939                if (mDebugTransient) {
5940                    mDebugApp = mOrigDebugApp;
5941                    mWaitForDebugger = mOrigWaitForDebugger;
5942                }
5943            }
5944            String profileFile = app.instrumentationProfileFile;
5945            ParcelFileDescriptor profileFd = null;
5946            int samplingInterval = 0;
5947            boolean profileAutoStop = false;
5948            if (mProfileApp != null && mProfileApp.equals(processName)) {
5949                mProfileProc = app;
5950                profileFile = mProfileFile;
5951                profileFd = mProfileFd;
5952                samplingInterval = mSamplingInterval;
5953                profileAutoStop = mAutoStopProfiler;
5954            }
5955            boolean enableOpenGlTrace = false;
5956            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5957                enableOpenGlTrace = true;
5958                mOpenGlTraceApp = null;
5959            }
5960
5961            // If the app is being launched for restore or full backup, set it up specially
5962            boolean isRestrictedBackupMode = false;
5963            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5964                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5965                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5966                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5967            }
5968
5969            ensurePackageDexOpt(app.instrumentationInfo != null
5970                    ? app.instrumentationInfo.packageName
5971                    : app.info.packageName);
5972            if (app.instrumentationClass != null) {
5973                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5974            }
5975            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5976                    + processName + " with config " + mConfiguration);
5977            ApplicationInfo appInfo = app.instrumentationInfo != null
5978                    ? app.instrumentationInfo : app.info;
5979            app.compat = compatibilityInfoForPackageLocked(appInfo);
5980            if (profileFd != null) {
5981                profileFd = profileFd.dup();
5982            }
5983            ProfilerInfo profilerInfo = profileFile == null ? null
5984                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5985            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5986                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5987                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5988                    isRestrictedBackupMode || !normalMode, app.persistent,
5989                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5990                    mCoreSettingsObserver.getCoreSettingsLocked());
5991            updateLruProcessLocked(app, false, null);
5992            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5993        } catch (Exception e) {
5994            // todo: Yikes!  What should we do?  For now we will try to
5995            // start another process, but that could easily get us in
5996            // an infinite loop of restarting processes...
5997            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
5998
5999            app.resetPackageList(mProcessStats);
6000            app.unlinkDeathRecipient();
6001            startProcessLocked(app, "bind fail", processName);
6002            return false;
6003        }
6004
6005        // Remove this record from the list of starting applications.
6006        mPersistentStartingProcesses.remove(app);
6007        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6008                "Attach application locked removing on hold: " + app);
6009        mProcessesOnHold.remove(app);
6010
6011        boolean badApp = false;
6012        boolean didSomething = false;
6013
6014        // See if the top visible activity is waiting to run in this process...
6015        if (normalMode) {
6016            try {
6017                if (mStackSupervisor.attachApplicationLocked(app)) {
6018                    didSomething = true;
6019                }
6020            } catch (Exception e) {
6021                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6022                badApp = true;
6023            }
6024        }
6025
6026        // Find any services that should be running in this process...
6027        if (!badApp) {
6028            try {
6029                didSomething |= mServices.attachApplicationLocked(app, processName);
6030            } catch (Exception e) {
6031                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6032                badApp = true;
6033            }
6034        }
6035
6036        // Check if a next-broadcast receiver is in this process...
6037        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6038            try {
6039                didSomething |= sendPendingBroadcastsLocked(app);
6040            } catch (Exception e) {
6041                // If the app died trying to launch the receiver we declare it 'bad'
6042                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6043                badApp = true;
6044            }
6045        }
6046
6047        // Check whether the next backup agent is in this process...
6048        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6049            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6050            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6051            try {
6052                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6053                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6054                        mBackupTarget.backupMode);
6055            } catch (Exception e) {
6056                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6057                badApp = true;
6058            }
6059        }
6060
6061        if (badApp) {
6062            app.kill("error during init", true);
6063            handleAppDiedLocked(app, false, true);
6064            return false;
6065        }
6066
6067        if (!didSomething) {
6068            updateOomAdjLocked();
6069        }
6070
6071        return true;
6072    }
6073
6074    @Override
6075    public final void attachApplication(IApplicationThread thread) {
6076        synchronized (this) {
6077            int callingPid = Binder.getCallingPid();
6078            final long origId = Binder.clearCallingIdentity();
6079            attachApplicationLocked(thread, callingPid);
6080            Binder.restoreCallingIdentity(origId);
6081        }
6082    }
6083
6084    @Override
6085    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6086        final long origId = Binder.clearCallingIdentity();
6087        synchronized (this) {
6088            ActivityStack stack = ActivityRecord.getStackLocked(token);
6089            if (stack != null) {
6090                ActivityRecord r =
6091                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6092                if (stopProfiling) {
6093                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6094                        try {
6095                            mProfileFd.close();
6096                        } catch (IOException e) {
6097                        }
6098                        clearProfilerLocked();
6099                    }
6100                }
6101            }
6102        }
6103        Binder.restoreCallingIdentity(origId);
6104    }
6105
6106    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6107        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6108                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6109    }
6110
6111    void enableScreenAfterBoot() {
6112        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6113                SystemClock.uptimeMillis());
6114        mWindowManager.enableScreenAfterBoot();
6115
6116        synchronized (this) {
6117            updateEventDispatchingLocked();
6118        }
6119    }
6120
6121    @Override
6122    public void showBootMessage(final CharSequence msg, final boolean always) {
6123        enforceNotIsolatedCaller("showBootMessage");
6124        mWindowManager.showBootMessage(msg, always);
6125    }
6126
6127    @Override
6128    public void keyguardWaitingForActivityDrawn() {
6129        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6130        final long token = Binder.clearCallingIdentity();
6131        try {
6132            synchronized (this) {
6133                if (DEBUG_LOCKSCREEN) logLockScreen("");
6134                mWindowManager.keyguardWaitingForActivityDrawn();
6135                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6136                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6137                }
6138            }
6139        } finally {
6140            Binder.restoreCallingIdentity(token);
6141        }
6142    }
6143
6144    final void finishBooting() {
6145        synchronized (this) {
6146            if (!mBootAnimationComplete) {
6147                mCallFinishBooting = true;
6148                return;
6149            }
6150            mCallFinishBooting = false;
6151        }
6152
6153        // Register receivers to handle package update events
6154        mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false);
6155
6156        // Let system services know.
6157        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6158
6159        synchronized (this) {
6160            // Ensure that any processes we had put on hold are now started
6161            // up.
6162            final int NP = mProcessesOnHold.size();
6163            if (NP > 0) {
6164                ArrayList<ProcessRecord> procs =
6165                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6166                for (int ip=0; ip<NP; ip++) {
6167                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6168                            + procs.get(ip));
6169                    startProcessLocked(procs.get(ip), "on-hold", null);
6170                }
6171            }
6172
6173            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6174                // Start looking for apps that are abusing wake locks.
6175                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6176                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6177                // Tell anyone interested that we are done booting!
6178                SystemProperties.set("sys.boot_completed", "1");
6179
6180                // And trigger dev.bootcomplete if we are not showing encryption progress
6181                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6182                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6183                    SystemProperties.set("dev.bootcomplete", "1");
6184                }
6185                for (int i=0; i<mStartedUsers.size(); i++) {
6186                    UserStartedState uss = mStartedUsers.valueAt(i);
6187                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6188                        uss.mState = UserStartedState.STATE_RUNNING;
6189                        final int userId = mStartedUsers.keyAt(i);
6190                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6191                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6192                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6193                        broadcastIntentLocked(null, null, intent, null,
6194                                new IIntentReceiver.Stub() {
6195                                    @Override
6196                                    public void performReceive(Intent intent, int resultCode,
6197                                            String data, Bundle extras, boolean ordered,
6198                                            boolean sticky, int sendingUser) {
6199                                        synchronized (ActivityManagerService.this) {
6200                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6201                                                    true, false);
6202                                        }
6203                                    }
6204                                },
6205                                0, null, null,
6206                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6207                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6208                                userId);
6209                    }
6210                }
6211                scheduleStartProfilesLocked();
6212            }
6213        }
6214    }
6215
6216    @Override
6217    public void bootAnimationComplete() {
6218        final boolean callFinishBooting;
6219        synchronized (this) {
6220            callFinishBooting = mCallFinishBooting;
6221            mBootAnimationComplete = true;
6222        }
6223        if (callFinishBooting) {
6224            finishBooting();
6225        }
6226    }
6227
6228    final void ensureBootCompleted() {
6229        boolean booting;
6230        boolean enableScreen;
6231        synchronized (this) {
6232            booting = mBooting;
6233            mBooting = false;
6234            enableScreen = !mBooted;
6235            mBooted = true;
6236        }
6237
6238        if (booting) {
6239            finishBooting();
6240        }
6241
6242        if (enableScreen) {
6243            enableScreenAfterBoot();
6244        }
6245    }
6246
6247    @Override
6248    public final void activityResumed(IBinder token) {
6249        final long origId = Binder.clearCallingIdentity();
6250        synchronized(this) {
6251            ActivityStack stack = ActivityRecord.getStackLocked(token);
6252            if (stack != null) {
6253                ActivityRecord.activityResumedLocked(token);
6254            }
6255        }
6256        Binder.restoreCallingIdentity(origId);
6257    }
6258
6259    @Override
6260    public final void activityPaused(IBinder token) {
6261        final long origId = Binder.clearCallingIdentity();
6262        synchronized(this) {
6263            ActivityStack stack = ActivityRecord.getStackLocked(token);
6264            if (stack != null) {
6265                stack.activityPausedLocked(token, false);
6266            }
6267        }
6268        Binder.restoreCallingIdentity(origId);
6269    }
6270
6271    @Override
6272    public final void activityStopped(IBinder token, Bundle icicle,
6273            PersistableBundle persistentState, CharSequence description) {
6274        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6275
6276        // Refuse possible leaked file descriptors
6277        if (icicle != null && icicle.hasFileDescriptors()) {
6278            throw new IllegalArgumentException("File descriptors passed in Bundle");
6279        }
6280
6281        final long origId = Binder.clearCallingIdentity();
6282
6283        synchronized (this) {
6284            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6285            if (r != null) {
6286                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6287            }
6288        }
6289
6290        trimApplications();
6291
6292        Binder.restoreCallingIdentity(origId);
6293    }
6294
6295    @Override
6296    public final void activityDestroyed(IBinder token) {
6297        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6298        synchronized (this) {
6299            ActivityStack stack = ActivityRecord.getStackLocked(token);
6300            if (stack != null) {
6301                stack.activityDestroyedLocked(token);
6302            }
6303        }
6304    }
6305
6306    @Override
6307    public final void backgroundResourcesReleased(IBinder token) {
6308        final long origId = Binder.clearCallingIdentity();
6309        try {
6310            synchronized (this) {
6311                ActivityStack stack = ActivityRecord.getStackLocked(token);
6312                if (stack != null) {
6313                    stack.backgroundResourcesReleased(token);
6314                }
6315            }
6316        } finally {
6317            Binder.restoreCallingIdentity(origId);
6318        }
6319    }
6320
6321    @Override
6322    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6323        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6324    }
6325
6326    @Override
6327    public final void notifyEnterAnimationComplete(IBinder token) {
6328        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6329    }
6330
6331    @Override
6332    public String getCallingPackage(IBinder token) {
6333        synchronized (this) {
6334            ActivityRecord r = getCallingRecordLocked(token);
6335            return r != null ? r.info.packageName : null;
6336        }
6337    }
6338
6339    @Override
6340    public ComponentName getCallingActivity(IBinder token) {
6341        synchronized (this) {
6342            ActivityRecord r = getCallingRecordLocked(token);
6343            return r != null ? r.intent.getComponent() : null;
6344        }
6345    }
6346
6347    private ActivityRecord getCallingRecordLocked(IBinder token) {
6348        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6349        if (r == null) {
6350            return null;
6351        }
6352        return r.resultTo;
6353    }
6354
6355    @Override
6356    public ComponentName getActivityClassForToken(IBinder token) {
6357        synchronized(this) {
6358            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6359            if (r == null) {
6360                return null;
6361            }
6362            return r.intent.getComponent();
6363        }
6364    }
6365
6366    @Override
6367    public String getPackageForToken(IBinder token) {
6368        synchronized(this) {
6369            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6370            if (r == null) {
6371                return null;
6372            }
6373            return r.packageName;
6374        }
6375    }
6376
6377    @Override
6378    public IIntentSender getIntentSender(int type,
6379            String packageName, IBinder token, String resultWho,
6380            int requestCode, Intent[] intents, String[] resolvedTypes,
6381            int flags, Bundle options, int userId) {
6382        enforceNotIsolatedCaller("getIntentSender");
6383        // Refuse possible leaked file descriptors
6384        if (intents != null) {
6385            if (intents.length < 1) {
6386                throw new IllegalArgumentException("Intents array length must be >= 1");
6387            }
6388            for (int i=0; i<intents.length; i++) {
6389                Intent intent = intents[i];
6390                if (intent != null) {
6391                    if (intent.hasFileDescriptors()) {
6392                        throw new IllegalArgumentException("File descriptors passed in Intent");
6393                    }
6394                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6395                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6396                        throw new IllegalArgumentException(
6397                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6398                    }
6399                    intents[i] = new Intent(intent);
6400                }
6401            }
6402            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6403                throw new IllegalArgumentException(
6404                        "Intent array length does not match resolvedTypes length");
6405            }
6406        }
6407        if (options != null) {
6408            if (options.hasFileDescriptors()) {
6409                throw new IllegalArgumentException("File descriptors passed in options");
6410            }
6411        }
6412
6413        synchronized(this) {
6414            int callingUid = Binder.getCallingUid();
6415            int origUserId = userId;
6416            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6417                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6418                    ALLOW_NON_FULL, "getIntentSender", null);
6419            if (origUserId == UserHandle.USER_CURRENT) {
6420                // We don't want to evaluate this until the pending intent is
6421                // actually executed.  However, we do want to always do the
6422                // security checking for it above.
6423                userId = UserHandle.USER_CURRENT;
6424            }
6425            try {
6426                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6427                    int uid = AppGlobals.getPackageManager()
6428                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6429                    if (!UserHandle.isSameApp(callingUid, uid)) {
6430                        String msg = "Permission Denial: getIntentSender() from pid="
6431                            + Binder.getCallingPid()
6432                            + ", uid=" + Binder.getCallingUid()
6433                            + ", (need uid=" + uid + ")"
6434                            + " is not allowed to send as package " + packageName;
6435                        Slog.w(TAG, msg);
6436                        throw new SecurityException(msg);
6437                    }
6438                }
6439
6440                return getIntentSenderLocked(type, packageName, callingUid, userId,
6441                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6442
6443            } catch (RemoteException e) {
6444                throw new SecurityException(e);
6445            }
6446        }
6447    }
6448
6449    IIntentSender getIntentSenderLocked(int type, String packageName,
6450            int callingUid, int userId, IBinder token, String resultWho,
6451            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6452            Bundle options) {
6453        if (DEBUG_MU)
6454            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6455        ActivityRecord activity = null;
6456        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6457            activity = ActivityRecord.isInStackLocked(token);
6458            if (activity == null) {
6459                return null;
6460            }
6461            if (activity.finishing) {
6462                return null;
6463            }
6464        }
6465
6466        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6467        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6468        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6469        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6470                |PendingIntent.FLAG_UPDATE_CURRENT);
6471
6472        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6473                type, packageName, activity, resultWho,
6474                requestCode, intents, resolvedTypes, flags, options, userId);
6475        WeakReference<PendingIntentRecord> ref;
6476        ref = mIntentSenderRecords.get(key);
6477        PendingIntentRecord rec = ref != null ? ref.get() : null;
6478        if (rec != null) {
6479            if (!cancelCurrent) {
6480                if (updateCurrent) {
6481                    if (rec.key.requestIntent != null) {
6482                        rec.key.requestIntent.replaceExtras(intents != null ?
6483                                intents[intents.length - 1] : null);
6484                    }
6485                    if (intents != null) {
6486                        intents[intents.length-1] = rec.key.requestIntent;
6487                        rec.key.allIntents = intents;
6488                        rec.key.allResolvedTypes = resolvedTypes;
6489                    } else {
6490                        rec.key.allIntents = null;
6491                        rec.key.allResolvedTypes = null;
6492                    }
6493                }
6494                return rec;
6495            }
6496            rec.canceled = true;
6497            mIntentSenderRecords.remove(key);
6498        }
6499        if (noCreate) {
6500            return rec;
6501        }
6502        rec = new PendingIntentRecord(this, key, callingUid);
6503        mIntentSenderRecords.put(key, rec.ref);
6504        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6505            if (activity.pendingResults == null) {
6506                activity.pendingResults
6507                        = new HashSet<WeakReference<PendingIntentRecord>>();
6508            }
6509            activity.pendingResults.add(rec.ref);
6510        }
6511        return rec;
6512    }
6513
6514    @Override
6515    public void cancelIntentSender(IIntentSender sender) {
6516        if (!(sender instanceof PendingIntentRecord)) {
6517            return;
6518        }
6519        synchronized(this) {
6520            PendingIntentRecord rec = (PendingIntentRecord)sender;
6521            try {
6522                int uid = AppGlobals.getPackageManager()
6523                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6524                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6525                    String msg = "Permission Denial: cancelIntentSender() from pid="
6526                        + Binder.getCallingPid()
6527                        + ", uid=" + Binder.getCallingUid()
6528                        + " is not allowed to cancel packges "
6529                        + rec.key.packageName;
6530                    Slog.w(TAG, msg);
6531                    throw new SecurityException(msg);
6532                }
6533            } catch (RemoteException e) {
6534                throw new SecurityException(e);
6535            }
6536            cancelIntentSenderLocked(rec, true);
6537        }
6538    }
6539
6540    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6541        rec.canceled = true;
6542        mIntentSenderRecords.remove(rec.key);
6543        if (cleanActivity && rec.key.activity != null) {
6544            rec.key.activity.pendingResults.remove(rec.ref);
6545        }
6546    }
6547
6548    @Override
6549    public String getPackageForIntentSender(IIntentSender pendingResult) {
6550        if (!(pendingResult instanceof PendingIntentRecord)) {
6551            return null;
6552        }
6553        try {
6554            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6555            return res.key.packageName;
6556        } catch (ClassCastException e) {
6557        }
6558        return null;
6559    }
6560
6561    @Override
6562    public int getUidForIntentSender(IIntentSender sender) {
6563        if (sender instanceof PendingIntentRecord) {
6564            try {
6565                PendingIntentRecord res = (PendingIntentRecord)sender;
6566                return res.uid;
6567            } catch (ClassCastException e) {
6568            }
6569        }
6570        return -1;
6571    }
6572
6573    @Override
6574    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6575        if (!(pendingResult instanceof PendingIntentRecord)) {
6576            return false;
6577        }
6578        try {
6579            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6580            if (res.key.allIntents == null) {
6581                return false;
6582            }
6583            for (int i=0; i<res.key.allIntents.length; i++) {
6584                Intent intent = res.key.allIntents[i];
6585                if (intent.getPackage() != null && intent.getComponent() != null) {
6586                    return false;
6587                }
6588            }
6589            return true;
6590        } catch (ClassCastException e) {
6591        }
6592        return false;
6593    }
6594
6595    @Override
6596    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6597        if (!(pendingResult instanceof PendingIntentRecord)) {
6598            return false;
6599        }
6600        try {
6601            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6602            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6603                return true;
6604            }
6605            return false;
6606        } catch (ClassCastException e) {
6607        }
6608        return false;
6609    }
6610
6611    @Override
6612    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6613        if (!(pendingResult instanceof PendingIntentRecord)) {
6614            return null;
6615        }
6616        try {
6617            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6618            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6619        } catch (ClassCastException e) {
6620        }
6621        return null;
6622    }
6623
6624    @Override
6625    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6626        if (!(pendingResult instanceof PendingIntentRecord)) {
6627            return null;
6628        }
6629        try {
6630            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6631            Intent intent = res.key.requestIntent;
6632            if (intent != null) {
6633                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6634                        || res.lastTagPrefix.equals(prefix))) {
6635                    return res.lastTag;
6636                }
6637                res.lastTagPrefix = prefix;
6638                StringBuilder sb = new StringBuilder(128);
6639                if (prefix != null) {
6640                    sb.append(prefix);
6641                }
6642                if (intent.getAction() != null) {
6643                    sb.append(intent.getAction());
6644                } else if (intent.getComponent() != null) {
6645                    intent.getComponent().appendShortString(sb);
6646                } else {
6647                    sb.append("?");
6648                }
6649                return res.lastTag = sb.toString();
6650            }
6651        } catch (ClassCastException e) {
6652        }
6653        return null;
6654    }
6655
6656    @Override
6657    public void setProcessLimit(int max) {
6658        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6659                "setProcessLimit()");
6660        synchronized (this) {
6661            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6662            mProcessLimitOverride = max;
6663        }
6664        trimApplications();
6665    }
6666
6667    @Override
6668    public int getProcessLimit() {
6669        synchronized (this) {
6670            return mProcessLimitOverride;
6671        }
6672    }
6673
6674    void foregroundTokenDied(ForegroundToken token) {
6675        synchronized (ActivityManagerService.this) {
6676            synchronized (mPidsSelfLocked) {
6677                ForegroundToken cur
6678                    = mForegroundProcesses.get(token.pid);
6679                if (cur != token) {
6680                    return;
6681                }
6682                mForegroundProcesses.remove(token.pid);
6683                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6684                if (pr == null) {
6685                    return;
6686                }
6687                pr.forcingToForeground = null;
6688                updateProcessForegroundLocked(pr, false, false);
6689            }
6690            updateOomAdjLocked();
6691        }
6692    }
6693
6694    @Override
6695    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6696        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6697                "setProcessForeground()");
6698        synchronized(this) {
6699            boolean changed = false;
6700
6701            synchronized (mPidsSelfLocked) {
6702                ProcessRecord pr = mPidsSelfLocked.get(pid);
6703                if (pr == null && isForeground) {
6704                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6705                    return;
6706                }
6707                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6708                if (oldToken != null) {
6709                    oldToken.token.unlinkToDeath(oldToken, 0);
6710                    mForegroundProcesses.remove(pid);
6711                    if (pr != null) {
6712                        pr.forcingToForeground = null;
6713                    }
6714                    changed = true;
6715                }
6716                if (isForeground && token != null) {
6717                    ForegroundToken newToken = new ForegroundToken() {
6718                        @Override
6719                        public void binderDied() {
6720                            foregroundTokenDied(this);
6721                        }
6722                    };
6723                    newToken.pid = pid;
6724                    newToken.token = token;
6725                    try {
6726                        token.linkToDeath(newToken, 0);
6727                        mForegroundProcesses.put(pid, newToken);
6728                        pr.forcingToForeground = token;
6729                        changed = true;
6730                    } catch (RemoteException e) {
6731                        // If the process died while doing this, we will later
6732                        // do the cleanup with the process death link.
6733                    }
6734                }
6735            }
6736
6737            if (changed) {
6738                updateOomAdjLocked();
6739            }
6740        }
6741    }
6742
6743    // =========================================================
6744    // PERMISSIONS
6745    // =========================================================
6746
6747    static class PermissionController extends IPermissionController.Stub {
6748        ActivityManagerService mActivityManagerService;
6749        PermissionController(ActivityManagerService activityManagerService) {
6750            mActivityManagerService = activityManagerService;
6751        }
6752
6753        @Override
6754        public boolean checkPermission(String permission, int pid, int uid) {
6755            return mActivityManagerService.checkPermission(permission, pid,
6756                    uid) == PackageManager.PERMISSION_GRANTED;
6757        }
6758    }
6759
6760    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6761        @Override
6762        public int checkComponentPermission(String permission, int pid, int uid,
6763                int owningUid, boolean exported) {
6764            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6765                    owningUid, exported);
6766        }
6767
6768        @Override
6769        public Object getAMSLock() {
6770            return ActivityManagerService.this;
6771        }
6772    }
6773
6774    /**
6775     * This can be called with or without the global lock held.
6776     */
6777    int checkComponentPermission(String permission, int pid, int uid,
6778            int owningUid, boolean exported) {
6779        // We might be performing an operation on behalf of an indirect binder
6780        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6781        // client identity accordingly before proceeding.
6782        Identity tlsIdentity = sCallerIdentity.get();
6783        if (tlsIdentity != null) {
6784            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6785                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6786            uid = tlsIdentity.uid;
6787            pid = tlsIdentity.pid;
6788        }
6789
6790        if (pid == MY_PID) {
6791            return PackageManager.PERMISSION_GRANTED;
6792        }
6793
6794        return ActivityManager.checkComponentPermission(permission, uid,
6795                owningUid, exported);
6796    }
6797
6798    /**
6799     * As the only public entry point for permissions checking, this method
6800     * can enforce the semantic that requesting a check on a null global
6801     * permission is automatically denied.  (Internally a null permission
6802     * string is used when calling {@link #checkComponentPermission} in cases
6803     * when only uid-based security is needed.)
6804     *
6805     * This can be called with or without the global lock held.
6806     */
6807    @Override
6808    public int checkPermission(String permission, int pid, int uid) {
6809        if (permission == null) {
6810            return PackageManager.PERMISSION_DENIED;
6811        }
6812        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6813    }
6814
6815    /**
6816     * Binder IPC calls go through the public entry point.
6817     * This can be called with or without the global lock held.
6818     */
6819    int checkCallingPermission(String permission) {
6820        return checkPermission(permission,
6821                Binder.getCallingPid(),
6822                UserHandle.getAppId(Binder.getCallingUid()));
6823    }
6824
6825    /**
6826     * This can be called with or without the global lock held.
6827     */
6828    void enforceCallingPermission(String permission, String func) {
6829        if (checkCallingPermission(permission)
6830                == PackageManager.PERMISSION_GRANTED) {
6831            return;
6832        }
6833
6834        String msg = "Permission Denial: " + func + " from pid="
6835                + Binder.getCallingPid()
6836                + ", uid=" + Binder.getCallingUid()
6837                + " requires " + permission;
6838        Slog.w(TAG, msg);
6839        throw new SecurityException(msg);
6840    }
6841
6842    /**
6843     * Determine if UID is holding permissions required to access {@link Uri} in
6844     * the given {@link ProviderInfo}. Final permission checking is always done
6845     * in {@link ContentProvider}.
6846     */
6847    private final boolean checkHoldingPermissionsLocked(
6848            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6849        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6850                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6851        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6852            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6853                    != PERMISSION_GRANTED) {
6854                return false;
6855            }
6856        }
6857        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6858    }
6859
6860    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6861            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6862        if (pi.applicationInfo.uid == uid) {
6863            return true;
6864        } else if (!pi.exported) {
6865            return false;
6866        }
6867
6868        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6869        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6870        try {
6871            // check if target holds top-level <provider> permissions
6872            if (!readMet && pi.readPermission != null && considerUidPermissions
6873                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6874                readMet = true;
6875            }
6876            if (!writeMet && pi.writePermission != null && considerUidPermissions
6877                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6878                writeMet = true;
6879            }
6880
6881            // track if unprotected read/write is allowed; any denied
6882            // <path-permission> below removes this ability
6883            boolean allowDefaultRead = pi.readPermission == null;
6884            boolean allowDefaultWrite = pi.writePermission == null;
6885
6886            // check if target holds any <path-permission> that match uri
6887            final PathPermission[] pps = pi.pathPermissions;
6888            if (pps != null) {
6889                final String path = grantUri.uri.getPath();
6890                int i = pps.length;
6891                while (i > 0 && (!readMet || !writeMet)) {
6892                    i--;
6893                    PathPermission pp = pps[i];
6894                    if (pp.match(path)) {
6895                        if (!readMet) {
6896                            final String pprperm = pp.getReadPermission();
6897                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6898                                    + pprperm + " for " + pp.getPath()
6899                                    + ": match=" + pp.match(path)
6900                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6901                            if (pprperm != null) {
6902                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6903                                        == PERMISSION_GRANTED) {
6904                                    readMet = true;
6905                                } else {
6906                                    allowDefaultRead = false;
6907                                }
6908                            }
6909                        }
6910                        if (!writeMet) {
6911                            final String ppwperm = pp.getWritePermission();
6912                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6913                                    + ppwperm + " for " + pp.getPath()
6914                                    + ": match=" + pp.match(path)
6915                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6916                            if (ppwperm != null) {
6917                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6918                                        == PERMISSION_GRANTED) {
6919                                    writeMet = true;
6920                                } else {
6921                                    allowDefaultWrite = false;
6922                                }
6923                            }
6924                        }
6925                    }
6926                }
6927            }
6928
6929            // grant unprotected <provider> read/write, if not blocked by
6930            // <path-permission> above
6931            if (allowDefaultRead) readMet = true;
6932            if (allowDefaultWrite) writeMet = true;
6933
6934        } catch (RemoteException e) {
6935            return false;
6936        }
6937
6938        return readMet && writeMet;
6939    }
6940
6941    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6942        ProviderInfo pi = null;
6943        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6944        if (cpr != null) {
6945            pi = cpr.info;
6946        } else {
6947            try {
6948                pi = AppGlobals.getPackageManager().resolveContentProvider(
6949                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6950            } catch (RemoteException ex) {
6951            }
6952        }
6953        return pi;
6954    }
6955
6956    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6957        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6958        if (targetUris != null) {
6959            return targetUris.get(grantUri);
6960        }
6961        return null;
6962    }
6963
6964    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6965            String targetPkg, int targetUid, GrantUri grantUri) {
6966        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6967        if (targetUris == null) {
6968            targetUris = Maps.newArrayMap();
6969            mGrantedUriPermissions.put(targetUid, targetUris);
6970        }
6971
6972        UriPermission perm = targetUris.get(grantUri);
6973        if (perm == null) {
6974            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6975            targetUris.put(grantUri, perm);
6976        }
6977
6978        return perm;
6979    }
6980
6981    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6982            final int modeFlags) {
6983        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6984        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6985                : UriPermission.STRENGTH_OWNED;
6986
6987        // Root gets to do everything.
6988        if (uid == 0) {
6989            return true;
6990        }
6991
6992        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6993        if (perms == null) return false;
6994
6995        // First look for exact match
6996        final UriPermission exactPerm = perms.get(grantUri);
6997        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6998            return true;
6999        }
7000
7001        // No exact match, look for prefixes
7002        final int N = perms.size();
7003        for (int i = 0; i < N; i++) {
7004            final UriPermission perm = perms.valueAt(i);
7005            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7006                    && perm.getStrength(modeFlags) >= minStrength) {
7007                return true;
7008            }
7009        }
7010
7011        return false;
7012    }
7013
7014    /**
7015     * @param uri This uri must NOT contain an embedded userId.
7016     * @param userId The userId in which the uri is to be resolved.
7017     */
7018    @Override
7019    public int checkUriPermission(Uri uri, int pid, int uid,
7020            final int modeFlags, int userId) {
7021        enforceNotIsolatedCaller("checkUriPermission");
7022
7023        // Another redirected-binder-call permissions check as in
7024        // {@link checkComponentPermission}.
7025        Identity tlsIdentity = sCallerIdentity.get();
7026        if (tlsIdentity != null) {
7027            uid = tlsIdentity.uid;
7028            pid = tlsIdentity.pid;
7029        }
7030
7031        // Our own process gets to do everything.
7032        if (pid == MY_PID) {
7033            return PackageManager.PERMISSION_GRANTED;
7034        }
7035        synchronized (this) {
7036            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7037                    ? PackageManager.PERMISSION_GRANTED
7038                    : PackageManager.PERMISSION_DENIED;
7039        }
7040    }
7041
7042    /**
7043     * Check if the targetPkg can be granted permission to access uri by
7044     * the callingUid using the given modeFlags.  Throws a security exception
7045     * if callingUid is not allowed to do this.  Returns the uid of the target
7046     * if the URI permission grant should be performed; returns -1 if it is not
7047     * needed (for example targetPkg already has permission to access the URI).
7048     * If you already know the uid of the target, you can supply it in
7049     * lastTargetUid else set that to -1.
7050     */
7051    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7052            final int modeFlags, int lastTargetUid) {
7053        if (!Intent.isAccessUriMode(modeFlags)) {
7054            return -1;
7055        }
7056
7057        if (targetPkg != null) {
7058            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7059                    "Checking grant " + targetPkg + " permission to " + grantUri);
7060        }
7061
7062        final IPackageManager pm = AppGlobals.getPackageManager();
7063
7064        // If this is not a content: uri, we can't do anything with it.
7065        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7066            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7067                    "Can't grant URI permission for non-content URI: " + grantUri);
7068            return -1;
7069        }
7070
7071        final String authority = grantUri.uri.getAuthority();
7072        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7073        if (pi == null) {
7074            Slog.w(TAG, "No content provider found for permission check: " +
7075                    grantUri.uri.toSafeString());
7076            return -1;
7077        }
7078
7079        int targetUid = lastTargetUid;
7080        if (targetUid < 0 && targetPkg != null) {
7081            try {
7082                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7083                if (targetUid < 0) {
7084                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7085                            "Can't grant URI permission no uid for: " + targetPkg);
7086                    return -1;
7087                }
7088            } catch (RemoteException ex) {
7089                return -1;
7090            }
7091        }
7092
7093        if (targetUid >= 0) {
7094            // First...  does the target actually need this permission?
7095            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7096                // No need to grant the target this permission.
7097                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7098                        "Target " + targetPkg + " already has full permission to " + grantUri);
7099                return -1;
7100            }
7101        } else {
7102            // First...  there is no target package, so can anyone access it?
7103            boolean allowed = pi.exported;
7104            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7105                if (pi.readPermission != null) {
7106                    allowed = false;
7107                }
7108            }
7109            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7110                if (pi.writePermission != null) {
7111                    allowed = false;
7112                }
7113            }
7114            if (allowed) {
7115                return -1;
7116            }
7117        }
7118
7119        /* There is a special cross user grant if:
7120         * - The target is on another user.
7121         * - Apps on the current user can access the uri without any uid permissions.
7122         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7123         * grant uri permissions.
7124         */
7125        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7126                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7127                modeFlags, false /*without considering the uid permissions*/);
7128
7129        // Second...  is the provider allowing granting of URI permissions?
7130        if (!specialCrossUserGrant) {
7131            if (!pi.grantUriPermissions) {
7132                throw new SecurityException("Provider " + pi.packageName
7133                        + "/" + pi.name
7134                        + " does not allow granting of Uri permissions (uri "
7135                        + grantUri + ")");
7136            }
7137            if (pi.uriPermissionPatterns != null) {
7138                final int N = pi.uriPermissionPatterns.length;
7139                boolean allowed = false;
7140                for (int i=0; i<N; i++) {
7141                    if (pi.uriPermissionPatterns[i] != null
7142                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7143                        allowed = true;
7144                        break;
7145                    }
7146                }
7147                if (!allowed) {
7148                    throw new SecurityException("Provider " + pi.packageName
7149                            + "/" + pi.name
7150                            + " does not allow granting of permission to path of Uri "
7151                            + grantUri);
7152                }
7153            }
7154        }
7155
7156        // Third...  does the caller itself have permission to access
7157        // this uri?
7158        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7159            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7160                // Require they hold a strong enough Uri permission
7161                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7162                    throw new SecurityException("Uid " + callingUid
7163                            + " does not have permission to uri " + grantUri);
7164                }
7165            }
7166        }
7167        return targetUid;
7168    }
7169
7170    /**
7171     * @param uri This uri must NOT contain an embedded userId.
7172     * @param userId The userId in which the uri is to be resolved.
7173     */
7174    @Override
7175    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7176            final int modeFlags, int userId) {
7177        enforceNotIsolatedCaller("checkGrantUriPermission");
7178        synchronized(this) {
7179            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7180                    new GrantUri(userId, uri, false), modeFlags, -1);
7181        }
7182    }
7183
7184    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7185            final int modeFlags, UriPermissionOwner owner) {
7186        if (!Intent.isAccessUriMode(modeFlags)) {
7187            return;
7188        }
7189
7190        // So here we are: the caller has the assumed permission
7191        // to the uri, and the target doesn't.  Let's now give this to
7192        // the target.
7193
7194        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7195                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7196
7197        final String authority = grantUri.uri.getAuthority();
7198        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7199        if (pi == null) {
7200            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7201            return;
7202        }
7203
7204        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7205            grantUri.prefix = true;
7206        }
7207        final UriPermission perm = findOrCreateUriPermissionLocked(
7208                pi.packageName, targetPkg, targetUid, grantUri);
7209        perm.grantModes(modeFlags, owner);
7210    }
7211
7212    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7213            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7214        if (targetPkg == null) {
7215            throw new NullPointerException("targetPkg");
7216        }
7217        int targetUid;
7218        final IPackageManager pm = AppGlobals.getPackageManager();
7219        try {
7220            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7221        } catch (RemoteException ex) {
7222            return;
7223        }
7224
7225        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7226                targetUid);
7227        if (targetUid < 0) {
7228            return;
7229        }
7230
7231        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7232                owner);
7233    }
7234
7235    static class NeededUriGrants extends ArrayList<GrantUri> {
7236        final String targetPkg;
7237        final int targetUid;
7238        final int flags;
7239
7240        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7241            this.targetPkg = targetPkg;
7242            this.targetUid = targetUid;
7243            this.flags = flags;
7244        }
7245    }
7246
7247    /**
7248     * Like checkGrantUriPermissionLocked, but takes an Intent.
7249     */
7250    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7251            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7252        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7253                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7254                + " clip=" + (intent != null ? intent.getClipData() : null)
7255                + " from " + intent + "; flags=0x"
7256                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7257
7258        if (targetPkg == null) {
7259            throw new NullPointerException("targetPkg");
7260        }
7261
7262        if (intent == null) {
7263            return null;
7264        }
7265        Uri data = intent.getData();
7266        ClipData clip = intent.getClipData();
7267        if (data == null && clip == null) {
7268            return null;
7269        }
7270        // Default userId for uris in the intent (if they don't specify it themselves)
7271        int contentUserHint = intent.getContentUserHint();
7272        if (contentUserHint == UserHandle.USER_CURRENT) {
7273            contentUserHint = UserHandle.getUserId(callingUid);
7274        }
7275        final IPackageManager pm = AppGlobals.getPackageManager();
7276        int targetUid;
7277        if (needed != null) {
7278            targetUid = needed.targetUid;
7279        } else {
7280            try {
7281                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7282            } catch (RemoteException ex) {
7283                return null;
7284            }
7285            if (targetUid < 0) {
7286                if (DEBUG_URI_PERMISSION) {
7287                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7288                            + " on user " + targetUserId);
7289                }
7290                return null;
7291            }
7292        }
7293        if (data != null) {
7294            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7295            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7296                    targetUid);
7297            if (targetUid > 0) {
7298                if (needed == null) {
7299                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7300                }
7301                needed.add(grantUri);
7302            }
7303        }
7304        if (clip != null) {
7305            for (int i=0; i<clip.getItemCount(); i++) {
7306                Uri uri = clip.getItemAt(i).getUri();
7307                if (uri != null) {
7308                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7309                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7310                            targetUid);
7311                    if (targetUid > 0) {
7312                        if (needed == null) {
7313                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7314                        }
7315                        needed.add(grantUri);
7316                    }
7317                } else {
7318                    Intent clipIntent = clip.getItemAt(i).getIntent();
7319                    if (clipIntent != null) {
7320                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7321                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7322                        if (newNeeded != null) {
7323                            needed = newNeeded;
7324                        }
7325                    }
7326                }
7327            }
7328        }
7329
7330        return needed;
7331    }
7332
7333    /**
7334     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7335     */
7336    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7337            UriPermissionOwner owner) {
7338        if (needed != null) {
7339            for (int i=0; i<needed.size(); i++) {
7340                GrantUri grantUri = needed.get(i);
7341                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7342                        grantUri, needed.flags, owner);
7343            }
7344        }
7345    }
7346
7347    void grantUriPermissionFromIntentLocked(int callingUid,
7348            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7349        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7350                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7351        if (needed == null) {
7352            return;
7353        }
7354
7355        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7356    }
7357
7358    /**
7359     * @param uri This uri must NOT contain an embedded userId.
7360     * @param userId The userId in which the uri is to be resolved.
7361     */
7362    @Override
7363    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7364            final int modeFlags, int userId) {
7365        enforceNotIsolatedCaller("grantUriPermission");
7366        GrantUri grantUri = new GrantUri(userId, uri, false);
7367        synchronized(this) {
7368            final ProcessRecord r = getRecordForAppLocked(caller);
7369            if (r == null) {
7370                throw new SecurityException("Unable to find app for caller "
7371                        + caller
7372                        + " when granting permission to uri " + grantUri);
7373            }
7374            if (targetPkg == null) {
7375                throw new IllegalArgumentException("null target");
7376            }
7377            if (grantUri == null) {
7378                throw new IllegalArgumentException("null uri");
7379            }
7380
7381            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7382                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7383                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7384                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7385
7386            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7387                    UserHandle.getUserId(r.uid));
7388        }
7389    }
7390
7391    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7392        if (perm.modeFlags == 0) {
7393            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7394                    perm.targetUid);
7395            if (perms != null) {
7396                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7397                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7398
7399                perms.remove(perm.uri);
7400                if (perms.isEmpty()) {
7401                    mGrantedUriPermissions.remove(perm.targetUid);
7402                }
7403            }
7404        }
7405    }
7406
7407    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7408        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7409
7410        final IPackageManager pm = AppGlobals.getPackageManager();
7411        final String authority = grantUri.uri.getAuthority();
7412        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7413        if (pi == null) {
7414            Slog.w(TAG, "No content provider found for permission revoke: "
7415                    + grantUri.toSafeString());
7416            return;
7417        }
7418
7419        // Does the caller have this permission on the URI?
7420        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7421            // If they don't have direct access to the URI, then revoke any
7422            // ownerless URI permissions that have been granted to them.
7423            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7424            if (perms != null) {
7425                boolean persistChanged = false;
7426                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7427                    final UriPermission perm = it.next();
7428                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7429                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7430                        if (DEBUG_URI_PERMISSION)
7431                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7432                                    " permission to " + perm.uri);
7433                        persistChanged |= perm.revokeModes(
7434                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7435                        if (perm.modeFlags == 0) {
7436                            it.remove();
7437                        }
7438                    }
7439                }
7440                if (perms.isEmpty()) {
7441                    mGrantedUriPermissions.remove(callingUid);
7442                }
7443                if (persistChanged) {
7444                    schedulePersistUriGrants();
7445                }
7446            }
7447            return;
7448        }
7449
7450        boolean persistChanged = false;
7451
7452        // Go through all of the permissions and remove any that match.
7453        int N = mGrantedUriPermissions.size();
7454        for (int i = 0; i < N; i++) {
7455            final int targetUid = mGrantedUriPermissions.keyAt(i);
7456            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7457
7458            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7459                final UriPermission perm = it.next();
7460                if (perm.uri.sourceUserId == grantUri.sourceUserId
7461                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7462                    if (DEBUG_URI_PERMISSION)
7463                        Slog.v(TAG,
7464                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7465                    persistChanged |= perm.revokeModes(
7466                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7467                    if (perm.modeFlags == 0) {
7468                        it.remove();
7469                    }
7470                }
7471            }
7472
7473            if (perms.isEmpty()) {
7474                mGrantedUriPermissions.remove(targetUid);
7475                N--;
7476                i--;
7477            }
7478        }
7479
7480        if (persistChanged) {
7481            schedulePersistUriGrants();
7482        }
7483    }
7484
7485    /**
7486     * @param uri This uri must NOT contain an embedded userId.
7487     * @param userId The userId in which the uri is to be resolved.
7488     */
7489    @Override
7490    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7491            int userId) {
7492        enforceNotIsolatedCaller("revokeUriPermission");
7493        synchronized(this) {
7494            final ProcessRecord r = getRecordForAppLocked(caller);
7495            if (r == null) {
7496                throw new SecurityException("Unable to find app for caller "
7497                        + caller
7498                        + " when revoking permission to uri " + uri);
7499            }
7500            if (uri == null) {
7501                Slog.w(TAG, "revokeUriPermission: null uri");
7502                return;
7503            }
7504
7505            if (!Intent.isAccessUriMode(modeFlags)) {
7506                return;
7507            }
7508
7509            final IPackageManager pm = AppGlobals.getPackageManager();
7510            final String authority = uri.getAuthority();
7511            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7512            if (pi == null) {
7513                Slog.w(TAG, "No content provider found for permission revoke: "
7514                        + uri.toSafeString());
7515                return;
7516            }
7517
7518            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7519        }
7520    }
7521
7522    /**
7523     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7524     * given package.
7525     *
7526     * @param packageName Package name to match, or {@code null} to apply to all
7527     *            packages.
7528     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7529     *            to all users.
7530     * @param persistable If persistable grants should be removed.
7531     */
7532    private void removeUriPermissionsForPackageLocked(
7533            String packageName, int userHandle, boolean persistable) {
7534        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7535            throw new IllegalArgumentException("Must narrow by either package or user");
7536        }
7537
7538        boolean persistChanged = false;
7539
7540        int N = mGrantedUriPermissions.size();
7541        for (int i = 0; i < N; i++) {
7542            final int targetUid = mGrantedUriPermissions.keyAt(i);
7543            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7544
7545            // Only inspect grants matching user
7546            if (userHandle == UserHandle.USER_ALL
7547                    || userHandle == UserHandle.getUserId(targetUid)) {
7548                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7549                    final UriPermission perm = it.next();
7550
7551                    // Only inspect grants matching package
7552                    if (packageName == null || perm.sourcePkg.equals(packageName)
7553                            || perm.targetPkg.equals(packageName)) {
7554                        persistChanged |= perm.revokeModes(persistable
7555                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7556
7557                        // Only remove when no modes remain; any persisted grants
7558                        // will keep this alive.
7559                        if (perm.modeFlags == 0) {
7560                            it.remove();
7561                        }
7562                    }
7563                }
7564
7565                if (perms.isEmpty()) {
7566                    mGrantedUriPermissions.remove(targetUid);
7567                    N--;
7568                    i--;
7569                }
7570            }
7571        }
7572
7573        if (persistChanged) {
7574            schedulePersistUriGrants();
7575        }
7576    }
7577
7578    @Override
7579    public IBinder newUriPermissionOwner(String name) {
7580        enforceNotIsolatedCaller("newUriPermissionOwner");
7581        synchronized(this) {
7582            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7583            return owner.getExternalTokenLocked();
7584        }
7585    }
7586
7587    /**
7588     * @param uri This uri must NOT contain an embedded userId.
7589     * @param sourceUserId The userId in which the uri is to be resolved.
7590     * @param targetUserId The userId of the app that receives the grant.
7591     */
7592    @Override
7593    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7594            final int modeFlags, int sourceUserId, int targetUserId) {
7595        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7596                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7597        synchronized(this) {
7598            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7599            if (owner == null) {
7600                throw new IllegalArgumentException("Unknown owner: " + token);
7601            }
7602            if (fromUid != Binder.getCallingUid()) {
7603                if (Binder.getCallingUid() != Process.myUid()) {
7604                    // Only system code can grant URI permissions on behalf
7605                    // of other users.
7606                    throw new SecurityException("nice try");
7607                }
7608            }
7609            if (targetPkg == null) {
7610                throw new IllegalArgumentException("null target");
7611            }
7612            if (uri == null) {
7613                throw new IllegalArgumentException("null uri");
7614            }
7615
7616            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7617                    modeFlags, owner, targetUserId);
7618        }
7619    }
7620
7621    /**
7622     * @param uri This uri must NOT contain an embedded userId.
7623     * @param userId The userId in which the uri is to be resolved.
7624     */
7625    @Override
7626    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7627        synchronized(this) {
7628            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7629            if (owner == null) {
7630                throw new IllegalArgumentException("Unknown owner: " + token);
7631            }
7632
7633            if (uri == null) {
7634                owner.removeUriPermissionsLocked(mode);
7635            } else {
7636                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7637            }
7638        }
7639    }
7640
7641    private void schedulePersistUriGrants() {
7642        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7643            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7644                    10 * DateUtils.SECOND_IN_MILLIS);
7645        }
7646    }
7647
7648    private void writeGrantedUriPermissions() {
7649        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7650
7651        // Snapshot permissions so we can persist without lock
7652        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7653        synchronized (this) {
7654            final int size = mGrantedUriPermissions.size();
7655            for (int i = 0; i < size; i++) {
7656                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7657                for (UriPermission perm : perms.values()) {
7658                    if (perm.persistedModeFlags != 0) {
7659                        persist.add(perm.snapshot());
7660                    }
7661                }
7662            }
7663        }
7664
7665        FileOutputStream fos = null;
7666        try {
7667            fos = mGrantFile.startWrite();
7668
7669            XmlSerializer out = new FastXmlSerializer();
7670            out.setOutput(fos, "utf-8");
7671            out.startDocument(null, true);
7672            out.startTag(null, TAG_URI_GRANTS);
7673            for (UriPermission.Snapshot perm : persist) {
7674                out.startTag(null, TAG_URI_GRANT);
7675                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7676                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7677                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7678                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7679                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7680                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7681                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7682                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7683                out.endTag(null, TAG_URI_GRANT);
7684            }
7685            out.endTag(null, TAG_URI_GRANTS);
7686            out.endDocument();
7687
7688            mGrantFile.finishWrite(fos);
7689        } catch (IOException e) {
7690            if (fos != null) {
7691                mGrantFile.failWrite(fos);
7692            }
7693        }
7694    }
7695
7696    private void readGrantedUriPermissionsLocked() {
7697        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7698
7699        final long now = System.currentTimeMillis();
7700
7701        FileInputStream fis = null;
7702        try {
7703            fis = mGrantFile.openRead();
7704            final XmlPullParser in = Xml.newPullParser();
7705            in.setInput(fis, null);
7706
7707            int type;
7708            while ((type = in.next()) != END_DOCUMENT) {
7709                final String tag = in.getName();
7710                if (type == START_TAG) {
7711                    if (TAG_URI_GRANT.equals(tag)) {
7712                        final int sourceUserId;
7713                        final int targetUserId;
7714                        final int userHandle = readIntAttribute(in,
7715                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7716                        if (userHandle != UserHandle.USER_NULL) {
7717                            // For backwards compatibility.
7718                            sourceUserId = userHandle;
7719                            targetUserId = userHandle;
7720                        } else {
7721                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7722                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7723                        }
7724                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7725                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7726                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7727                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7728                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7729                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7730
7731                        // Sanity check that provider still belongs to source package
7732                        final ProviderInfo pi = getProviderInfoLocked(
7733                                uri.getAuthority(), sourceUserId);
7734                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7735                            int targetUid = -1;
7736                            try {
7737                                targetUid = AppGlobals.getPackageManager()
7738                                        .getPackageUid(targetPkg, targetUserId);
7739                            } catch (RemoteException e) {
7740                            }
7741                            if (targetUid != -1) {
7742                                final UriPermission perm = findOrCreateUriPermissionLocked(
7743                                        sourcePkg, targetPkg, targetUid,
7744                                        new GrantUri(sourceUserId, uri, prefix));
7745                                perm.initPersistedModes(modeFlags, createdTime);
7746                            }
7747                        } else {
7748                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7749                                    + " but instead found " + pi);
7750                        }
7751                    }
7752                }
7753            }
7754        } catch (FileNotFoundException e) {
7755            // Missing grants is okay
7756        } catch (IOException e) {
7757            Slog.wtf(TAG, "Failed reading Uri grants", e);
7758        } catch (XmlPullParserException e) {
7759            Slog.wtf(TAG, "Failed reading Uri grants", e);
7760        } finally {
7761            IoUtils.closeQuietly(fis);
7762        }
7763    }
7764
7765    /**
7766     * @param uri This uri must NOT contain an embedded userId.
7767     * @param userId The userId in which the uri is to be resolved.
7768     */
7769    @Override
7770    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7771        enforceNotIsolatedCaller("takePersistableUriPermission");
7772
7773        Preconditions.checkFlagsArgument(modeFlags,
7774                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7775
7776        synchronized (this) {
7777            final int callingUid = Binder.getCallingUid();
7778            boolean persistChanged = false;
7779            GrantUri grantUri = new GrantUri(userId, uri, false);
7780
7781            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7782                    new GrantUri(userId, uri, false));
7783            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7784                    new GrantUri(userId, uri, true));
7785
7786            final boolean exactValid = (exactPerm != null)
7787                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7788            final boolean prefixValid = (prefixPerm != null)
7789                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7790
7791            if (!(exactValid || prefixValid)) {
7792                throw new SecurityException("No persistable permission grants found for UID "
7793                        + callingUid + " and Uri " + grantUri.toSafeString());
7794            }
7795
7796            if (exactValid) {
7797                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7798            }
7799            if (prefixValid) {
7800                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7801            }
7802
7803            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7804
7805            if (persistChanged) {
7806                schedulePersistUriGrants();
7807            }
7808        }
7809    }
7810
7811    /**
7812     * @param uri This uri must NOT contain an embedded userId.
7813     * @param userId The userId in which the uri is to be resolved.
7814     */
7815    @Override
7816    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7817        enforceNotIsolatedCaller("releasePersistableUriPermission");
7818
7819        Preconditions.checkFlagsArgument(modeFlags,
7820                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7821
7822        synchronized (this) {
7823            final int callingUid = Binder.getCallingUid();
7824            boolean persistChanged = false;
7825
7826            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7827                    new GrantUri(userId, uri, false));
7828            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7829                    new GrantUri(userId, uri, true));
7830            if (exactPerm == null && prefixPerm == null) {
7831                throw new SecurityException("No permission grants found for UID " + callingUid
7832                        + " and Uri " + uri.toSafeString());
7833            }
7834
7835            if (exactPerm != null) {
7836                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7837                removeUriPermissionIfNeededLocked(exactPerm);
7838            }
7839            if (prefixPerm != null) {
7840                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7841                removeUriPermissionIfNeededLocked(prefixPerm);
7842            }
7843
7844            if (persistChanged) {
7845                schedulePersistUriGrants();
7846            }
7847        }
7848    }
7849
7850    /**
7851     * Prune any older {@link UriPermission} for the given UID until outstanding
7852     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7853     *
7854     * @return if any mutations occured that require persisting.
7855     */
7856    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7857        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7858        if (perms == null) return false;
7859        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7860
7861        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7862        for (UriPermission perm : perms.values()) {
7863            if (perm.persistedModeFlags != 0) {
7864                persisted.add(perm);
7865            }
7866        }
7867
7868        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7869        if (trimCount <= 0) return false;
7870
7871        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7872        for (int i = 0; i < trimCount; i++) {
7873            final UriPermission perm = persisted.get(i);
7874
7875            if (DEBUG_URI_PERMISSION) {
7876                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7877            }
7878
7879            perm.releasePersistableModes(~0);
7880            removeUriPermissionIfNeededLocked(perm);
7881        }
7882
7883        return true;
7884    }
7885
7886    @Override
7887    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7888            String packageName, boolean incoming) {
7889        enforceNotIsolatedCaller("getPersistedUriPermissions");
7890        Preconditions.checkNotNull(packageName, "packageName");
7891
7892        final int callingUid = Binder.getCallingUid();
7893        final IPackageManager pm = AppGlobals.getPackageManager();
7894        try {
7895            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7896            if (packageUid != callingUid) {
7897                throw new SecurityException(
7898                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7899            }
7900        } catch (RemoteException e) {
7901            throw new SecurityException("Failed to verify package name ownership");
7902        }
7903
7904        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7905        synchronized (this) {
7906            if (incoming) {
7907                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7908                        callingUid);
7909                if (perms == null) {
7910                    Slog.w(TAG, "No permission grants found for " + packageName);
7911                } else {
7912                    for (UriPermission perm : perms.values()) {
7913                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7914                            result.add(perm.buildPersistedPublicApiObject());
7915                        }
7916                    }
7917                }
7918            } else {
7919                final int size = mGrantedUriPermissions.size();
7920                for (int i = 0; i < size; i++) {
7921                    final ArrayMap<GrantUri, UriPermission> perms =
7922                            mGrantedUriPermissions.valueAt(i);
7923                    for (UriPermission perm : perms.values()) {
7924                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7925                            result.add(perm.buildPersistedPublicApiObject());
7926                        }
7927                    }
7928                }
7929            }
7930        }
7931        return new ParceledListSlice<android.content.UriPermission>(result);
7932    }
7933
7934    @Override
7935    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7936        synchronized (this) {
7937            ProcessRecord app =
7938                who != null ? getRecordForAppLocked(who) : null;
7939            if (app == null) return;
7940
7941            Message msg = Message.obtain();
7942            msg.what = WAIT_FOR_DEBUGGER_MSG;
7943            msg.obj = app;
7944            msg.arg1 = waiting ? 1 : 0;
7945            mHandler.sendMessage(msg);
7946        }
7947    }
7948
7949    @Override
7950    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7951        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7952        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7953        outInfo.availMem = Process.getFreeMemory();
7954        outInfo.totalMem = Process.getTotalMemory();
7955        outInfo.threshold = homeAppMem;
7956        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7957        outInfo.hiddenAppThreshold = cachedAppMem;
7958        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7959                ProcessList.SERVICE_ADJ);
7960        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7961                ProcessList.VISIBLE_APP_ADJ);
7962        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7963                ProcessList.FOREGROUND_APP_ADJ);
7964    }
7965
7966    // =========================================================
7967    // TASK MANAGEMENT
7968    // =========================================================
7969
7970    @Override
7971    public List<IAppTask> getAppTasks(String callingPackage) {
7972        int callingUid = Binder.getCallingUid();
7973        long ident = Binder.clearCallingIdentity();
7974
7975        synchronized(this) {
7976            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7977            try {
7978                if (localLOGV) Slog.v(TAG, "getAppTasks");
7979
7980                final int N = mRecentTasks.size();
7981                for (int i = 0; i < N; i++) {
7982                    TaskRecord tr = mRecentTasks.get(i);
7983                    // Skip tasks that do not match the caller.  We don't need to verify
7984                    // callingPackage, because we are also limiting to callingUid and know
7985                    // that will limit to the correct security sandbox.
7986                    if (tr.effectiveUid != callingUid) {
7987                        continue;
7988                    }
7989                    Intent intent = tr.getBaseIntent();
7990                    if (intent == null ||
7991                            !callingPackage.equals(intent.getComponent().getPackageName())) {
7992                        continue;
7993                    }
7994                    ActivityManager.RecentTaskInfo taskInfo =
7995                            createRecentTaskInfoFromTaskRecord(tr);
7996                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7997                    list.add(taskImpl);
7998                }
7999            } finally {
8000                Binder.restoreCallingIdentity(ident);
8001            }
8002            return list;
8003        }
8004    }
8005
8006    @Override
8007    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8008        final int callingUid = Binder.getCallingUid();
8009        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8010
8011        synchronized(this) {
8012            if (localLOGV) Slog.v(
8013                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8014
8015            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8016                    callingUid);
8017
8018            // TODO: Improve with MRU list from all ActivityStacks.
8019            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8020        }
8021
8022        return list;
8023    }
8024
8025    TaskRecord getMostRecentTask() {
8026        return mRecentTasks.get(0);
8027    }
8028
8029    /**
8030     * Creates a new RecentTaskInfo from a TaskRecord.
8031     */
8032    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8033        // Update the task description to reflect any changes in the task stack
8034        tr.updateTaskDescription();
8035
8036        // Compose the recent task info
8037        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8038        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8039        rti.persistentId = tr.taskId;
8040        rti.baseIntent = new Intent(tr.getBaseIntent());
8041        rti.origActivity = tr.origActivity;
8042        rti.description = tr.lastDescription;
8043        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8044        rti.userId = tr.userId;
8045        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8046        rti.firstActiveTime = tr.firstActiveTime;
8047        rti.lastActiveTime = tr.lastActiveTime;
8048        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8049        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8050        return rti;
8051    }
8052
8053    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8054        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8055                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8056        if (!allowed) {
8057            if (checkPermission(android.Manifest.permission.GET_TASKS,
8058                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8059                // Temporary compatibility: some existing apps on the system image may
8060                // still be requesting the old permission and not switched to the new
8061                // one; if so, we'll still allow them full access.  This means we need
8062                // to see if they are holding the old permission and are a system app.
8063                try {
8064                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8065                        allowed = true;
8066                        Slog.w(TAG, caller + ": caller " + callingUid
8067                                + " is using old GET_TASKS but privileged; allowing");
8068                    }
8069                } catch (RemoteException e) {
8070                }
8071            }
8072        }
8073        if (!allowed) {
8074            Slog.w(TAG, caller + ": caller " + callingUid
8075                    + " does not hold GET_TASKS; limiting output");
8076        }
8077        return allowed;
8078    }
8079
8080    @Override
8081    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8082        final int callingUid = Binder.getCallingUid();
8083        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8084                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8085
8086        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8087        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8088        synchronized (this) {
8089            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8090                    callingUid);
8091            final boolean detailed = checkCallingPermission(
8092                    android.Manifest.permission.GET_DETAILED_TASKS)
8093                    == PackageManager.PERMISSION_GRANTED;
8094
8095            final int N = mRecentTasks.size();
8096            ArrayList<ActivityManager.RecentTaskInfo> res
8097                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8098                            maxNum < N ? maxNum : N);
8099
8100            final Set<Integer> includedUsers;
8101            if (includeProfiles) {
8102                includedUsers = getProfileIdsLocked(userId);
8103            } else {
8104                includedUsers = new HashSet<Integer>();
8105            }
8106            includedUsers.add(Integer.valueOf(userId));
8107
8108            for (int i=0; i<N && maxNum > 0; i++) {
8109                TaskRecord tr = mRecentTasks.get(i);
8110                // Only add calling user or related users recent tasks
8111                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8112                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8113                    continue;
8114                }
8115
8116                // Return the entry if desired by the caller.  We always return
8117                // the first entry, because callers always expect this to be the
8118                // foreground app.  We may filter others if the caller has
8119                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8120                // we should exclude the entry.
8121
8122                if (i == 0
8123                        || withExcluded
8124                        || (tr.intent == null)
8125                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8126                                == 0)) {
8127                    if (!allowed) {
8128                        // If the caller doesn't have the GET_TASKS permission, then only
8129                        // allow them to see a small subset of tasks -- their own and home.
8130                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8131                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8132                            continue;
8133                        }
8134                    }
8135                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8136                        if (tr.stack != null && tr.stack.isHomeStack()) {
8137                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8138                            continue;
8139                        }
8140                    }
8141                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8142                        // Don't include auto remove tasks that are finished or finishing.
8143                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8144                                + tr);
8145                        continue;
8146                    }
8147                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8148                            && !tr.isAvailable) {
8149                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8150                        continue;
8151                    }
8152
8153                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8154                    if (!detailed) {
8155                        rti.baseIntent.replaceExtras((Bundle)null);
8156                    }
8157
8158                    res.add(rti);
8159                    maxNum--;
8160                }
8161            }
8162            return res;
8163        }
8164    }
8165
8166    private TaskRecord recentTaskForIdLocked(int id) {
8167        final int N = mRecentTasks.size();
8168            for (int i=0; i<N; i++) {
8169                TaskRecord tr = mRecentTasks.get(i);
8170                if (tr.taskId == id) {
8171                    return tr;
8172                }
8173            }
8174            return null;
8175    }
8176
8177    @Override
8178    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8179        synchronized (this) {
8180            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8181                    "getTaskThumbnail()");
8182            TaskRecord tr = recentTaskForIdLocked(id);
8183            if (tr != null) {
8184                return tr.getTaskThumbnailLocked();
8185            }
8186        }
8187        return null;
8188    }
8189
8190    @Override
8191    public int addAppTask(IBinder activityToken, Intent intent,
8192            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8193        final int callingUid = Binder.getCallingUid();
8194        final long callingIdent = Binder.clearCallingIdentity();
8195
8196        try {
8197            synchronized (this) {
8198                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8199                if (r == null) {
8200                    throw new IllegalArgumentException("Activity does not exist; token="
8201                            + activityToken);
8202                }
8203                ComponentName comp = intent.getComponent();
8204                if (comp == null) {
8205                    throw new IllegalArgumentException("Intent " + intent
8206                            + " must specify explicit component");
8207                }
8208                if (thumbnail.getWidth() != mThumbnailWidth
8209                        || thumbnail.getHeight() != mThumbnailHeight) {
8210                    throw new IllegalArgumentException("Bad thumbnail size: got "
8211                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8212                            + mThumbnailWidth + "x" + mThumbnailHeight);
8213                }
8214                if (intent.getSelector() != null) {
8215                    intent.setSelector(null);
8216                }
8217                if (intent.getSourceBounds() != null) {
8218                    intent.setSourceBounds(null);
8219                }
8220                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8221                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8222                        // The caller has added this as an auto-remove task...  that makes no
8223                        // sense, so turn off auto-remove.
8224                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8225                    }
8226                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8227                    // Must be a new task.
8228                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8229                }
8230                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8231                    mLastAddedTaskActivity = null;
8232                }
8233                ActivityInfo ainfo = mLastAddedTaskActivity;
8234                if (ainfo == null) {
8235                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8236                            comp, 0, UserHandle.getUserId(callingUid));
8237                    if (ainfo.applicationInfo.uid != callingUid) {
8238                        throw new SecurityException(
8239                                "Can't add task for another application: target uid="
8240                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8241                    }
8242                }
8243
8244                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8245                        intent, description);
8246
8247                int trimIdx = trimRecentsForTask(task, false);
8248                if (trimIdx >= 0) {
8249                    // If this would have caused a trim, then we'll abort because that
8250                    // means it would be added at the end of the list but then just removed.
8251                    return -1;
8252                }
8253
8254                final int N = mRecentTasks.size();
8255                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8256                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8257                    tr.removedFromRecents(mTaskPersister);
8258                }
8259
8260                task.inRecents = true;
8261                mRecentTasks.add(task);
8262                r.task.stack.addTask(task, false, false);
8263
8264                task.setLastThumbnail(thumbnail);
8265                task.freeLastThumbnail();
8266
8267                return task.taskId;
8268            }
8269        } finally {
8270            Binder.restoreCallingIdentity(callingIdent);
8271        }
8272    }
8273
8274    @Override
8275    public Point getAppTaskThumbnailSize() {
8276        synchronized (this) {
8277            return new Point(mThumbnailWidth,  mThumbnailHeight);
8278        }
8279    }
8280
8281    @Override
8282    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8283        synchronized (this) {
8284            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8285            if (r != null) {
8286                r.setTaskDescription(td);
8287                r.task.updateTaskDescription();
8288            }
8289        }
8290    }
8291
8292    @Override
8293    public Bitmap getTaskDescriptionIcon(String filename) {
8294        if (!FileUtils.isValidExtFilename(filename)
8295                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8296            throw new IllegalArgumentException("Bad filename: " + filename);
8297        }
8298        return mTaskPersister.getTaskDescriptionIcon(filename);
8299    }
8300
8301    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8302        mRecentTasks.remove(tr);
8303        tr.removedFromRecents(mTaskPersister);
8304        ComponentName component = tr.getBaseIntent().getComponent();
8305        if (component == null) {
8306            Slog.w(TAG, "No component for base intent of task: " + tr);
8307            return;
8308        }
8309
8310        if (!killProcess) {
8311            return;
8312        }
8313
8314        // Determine if the process(es) for this task should be killed.
8315        final String pkg = component.getPackageName();
8316        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8317        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8318        for (int i = 0; i < pmap.size(); i++) {
8319
8320            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8321            for (int j = 0; j < uids.size(); j++) {
8322                ProcessRecord proc = uids.valueAt(j);
8323                if (proc.userId != tr.userId) {
8324                    // Don't kill process for a different user.
8325                    continue;
8326                }
8327                if (proc == mHomeProcess) {
8328                    // Don't kill the home process along with tasks from the same package.
8329                    continue;
8330                }
8331                if (!proc.pkgList.containsKey(pkg)) {
8332                    // Don't kill process that is not associated with this task.
8333                    continue;
8334                }
8335
8336                for (int k = 0; k < proc.activities.size(); k++) {
8337                    TaskRecord otherTask = proc.activities.get(k).task;
8338                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8339                        // Don't kill process(es) that has an activity in a different task that is
8340                        // also in recents.
8341                        return;
8342                    }
8343                }
8344
8345                // Add process to kill list.
8346                procsToKill.add(proc);
8347            }
8348        }
8349
8350        // Find any running services associated with this app and stop if needed.
8351        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8352
8353        // Kill the running processes.
8354        for (int i = 0; i < procsToKill.size(); i++) {
8355            ProcessRecord pr = procsToKill.get(i);
8356            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8357                pr.kill("remove task", true);
8358            } else {
8359                pr.waitingToKill = "remove task";
8360            }
8361        }
8362    }
8363
8364    /**
8365     * Removes the task with the specified task id.
8366     *
8367     * @param taskId Identifier of the task to be removed.
8368     * @param killProcess Kill any process associated with the task if possible.
8369     * @return Returns true if the given task was found and removed.
8370     */
8371    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8372        TaskRecord tr = recentTaskForIdLocked(taskId);
8373        if (tr != null) {
8374            tr.removeTaskActivitiesLocked();
8375            cleanUpRemovedTaskLocked(tr, killProcess);
8376            if (tr.isPersistable) {
8377                notifyTaskPersisterLocked(null, true);
8378            }
8379            return true;
8380        }
8381        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8382        return false;
8383    }
8384
8385    @Override
8386    public boolean removeTask(int taskId) {
8387        synchronized (this) {
8388            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8389                    "removeTask()");
8390            long ident = Binder.clearCallingIdentity();
8391            try {
8392                return removeTaskByIdLocked(taskId, true);
8393            } finally {
8394                Binder.restoreCallingIdentity(ident);
8395            }
8396        }
8397    }
8398
8399    /**
8400     * TODO: Add mController hook
8401     */
8402    @Override
8403    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8404        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8405                "moveTaskToFront()");
8406
8407        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8408        synchronized(this) {
8409            moveTaskToFrontLocked(taskId, flags, options);
8410        }
8411    }
8412
8413    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8414        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8415                Binder.getCallingUid(), -1, -1, "Task to front")) {
8416            ActivityOptions.abort(options);
8417            return;
8418        }
8419        final long origId = Binder.clearCallingIdentity();
8420        try {
8421            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8422            if (task == null) {
8423                return;
8424            }
8425            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8426                mStackSupervisor.showLockTaskToast();
8427                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8428                return;
8429            }
8430            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8431            if (prev != null && prev.isRecentsActivity()) {
8432                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8433            }
8434            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8435        } finally {
8436            Binder.restoreCallingIdentity(origId);
8437        }
8438        ActivityOptions.abort(options);
8439    }
8440
8441    @Override
8442    public void moveTaskToBack(int taskId) {
8443        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8444                "moveTaskToBack()");
8445
8446        synchronized(this) {
8447            TaskRecord tr = recentTaskForIdLocked(taskId);
8448            if (tr != null) {
8449                if (tr == mStackSupervisor.mLockTaskModeTask) {
8450                    mStackSupervisor.showLockTaskToast();
8451                    return;
8452                }
8453                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8454                ActivityStack stack = tr.stack;
8455                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8456                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8457                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8458                        return;
8459                    }
8460                }
8461                final long origId = Binder.clearCallingIdentity();
8462                try {
8463                    stack.moveTaskToBackLocked(taskId, null);
8464                } finally {
8465                    Binder.restoreCallingIdentity(origId);
8466                }
8467            }
8468        }
8469    }
8470
8471    /**
8472     * Moves an activity, and all of the other activities within the same task, to the bottom
8473     * of the history stack.  The activity's order within the task is unchanged.
8474     *
8475     * @param token A reference to the activity we wish to move
8476     * @param nonRoot If false then this only works if the activity is the root
8477     *                of a task; if true it will work for any activity in a task.
8478     * @return Returns true if the move completed, false if not.
8479     */
8480    @Override
8481    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8482        enforceNotIsolatedCaller("moveActivityTaskToBack");
8483        synchronized(this) {
8484            final long origId = Binder.clearCallingIdentity();
8485            try {
8486                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8487                if (taskId >= 0) {
8488                    if ((mStackSupervisor.mLockTaskModeTask != null)
8489                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8490                        mStackSupervisor.showLockTaskToast();
8491                        return false;
8492                    }
8493                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8494                }
8495            } finally {
8496                Binder.restoreCallingIdentity(origId);
8497            }
8498        }
8499        return false;
8500    }
8501
8502    @Override
8503    public void moveTaskBackwards(int task) {
8504        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8505                "moveTaskBackwards()");
8506
8507        synchronized(this) {
8508            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8509                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8510                return;
8511            }
8512            final long origId = Binder.clearCallingIdentity();
8513            moveTaskBackwardsLocked(task);
8514            Binder.restoreCallingIdentity(origId);
8515        }
8516    }
8517
8518    private final void moveTaskBackwardsLocked(int task) {
8519        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8520    }
8521
8522    @Override
8523    public IBinder getHomeActivityToken() throws RemoteException {
8524        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8525                "getHomeActivityToken()");
8526        synchronized (this) {
8527            return mStackSupervisor.getHomeActivityToken();
8528        }
8529    }
8530
8531    @Override
8532    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8533            IActivityContainerCallback callback) throws RemoteException {
8534        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8535                "createActivityContainer()");
8536        synchronized (this) {
8537            if (parentActivityToken == null) {
8538                throw new IllegalArgumentException("parent token must not be null");
8539            }
8540            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8541            if (r == null) {
8542                return null;
8543            }
8544            if (callback == null) {
8545                throw new IllegalArgumentException("callback must not be null");
8546            }
8547            return mStackSupervisor.createActivityContainer(r, callback);
8548        }
8549    }
8550
8551    @Override
8552    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8553        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8554                "deleteActivityContainer()");
8555        synchronized (this) {
8556            mStackSupervisor.deleteActivityContainer(container);
8557        }
8558    }
8559
8560    @Override
8561    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8562            throws RemoteException {
8563        synchronized (this) {
8564            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8565            if (stack != null) {
8566                return stack.mActivityContainer;
8567            }
8568            return null;
8569        }
8570    }
8571
8572    @Override
8573    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8574        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8575                "moveTaskToStack()");
8576        if (stackId == HOME_STACK_ID) {
8577            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8578                    new RuntimeException("here").fillInStackTrace());
8579        }
8580        synchronized (this) {
8581            long ident = Binder.clearCallingIdentity();
8582            try {
8583                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8584                        + stackId + " toTop=" + toTop);
8585                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8586            } finally {
8587                Binder.restoreCallingIdentity(ident);
8588            }
8589        }
8590    }
8591
8592    @Override
8593    public void resizeStack(int stackBoxId, Rect bounds) {
8594        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8595                "resizeStackBox()");
8596        long ident = Binder.clearCallingIdentity();
8597        try {
8598            mWindowManager.resizeStack(stackBoxId, bounds);
8599        } finally {
8600            Binder.restoreCallingIdentity(ident);
8601        }
8602    }
8603
8604    @Override
8605    public List<StackInfo> getAllStackInfos() {
8606        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8607                "getAllStackInfos()");
8608        long ident = Binder.clearCallingIdentity();
8609        try {
8610            synchronized (this) {
8611                return mStackSupervisor.getAllStackInfosLocked();
8612            }
8613        } finally {
8614            Binder.restoreCallingIdentity(ident);
8615        }
8616    }
8617
8618    @Override
8619    public StackInfo getStackInfo(int stackId) {
8620        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8621                "getStackInfo()");
8622        long ident = Binder.clearCallingIdentity();
8623        try {
8624            synchronized (this) {
8625                return mStackSupervisor.getStackInfoLocked(stackId);
8626            }
8627        } finally {
8628            Binder.restoreCallingIdentity(ident);
8629        }
8630    }
8631
8632    @Override
8633    public boolean isInHomeStack(int taskId) {
8634        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8635                "getStackInfo()");
8636        long ident = Binder.clearCallingIdentity();
8637        try {
8638            synchronized (this) {
8639                TaskRecord tr = recentTaskForIdLocked(taskId);
8640                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8641            }
8642        } finally {
8643            Binder.restoreCallingIdentity(ident);
8644        }
8645    }
8646
8647    @Override
8648    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8649        synchronized(this) {
8650            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8651        }
8652    }
8653
8654    private boolean isLockTaskAuthorized(String pkg) {
8655        final DevicePolicyManager dpm = (DevicePolicyManager)
8656                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8657        try {
8658            int uid = mContext.getPackageManager().getPackageUid(pkg,
8659                    Binder.getCallingUserHandle().getIdentifier());
8660            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8661        } catch (NameNotFoundException e) {
8662            return false;
8663        }
8664    }
8665
8666    void startLockTaskMode(TaskRecord task) {
8667        final String pkg;
8668        synchronized (this) {
8669            pkg = task.intent.getComponent().getPackageName();
8670        }
8671        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8672        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8673            final TaskRecord taskRecord = task;
8674            mHandler.post(new Runnable() {
8675                @Override
8676                public void run() {
8677                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8678                }
8679            });
8680            return;
8681        }
8682        long ident = Binder.clearCallingIdentity();
8683        try {
8684            synchronized (this) {
8685                // Since we lost lock on task, make sure it is still there.
8686                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8687                if (task != null) {
8688                    if (!isSystemInitiated
8689                            && ((mStackSupervisor.getFocusedStack() == null)
8690                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8691                        throw new IllegalArgumentException("Invalid task, not in foreground");
8692                    }
8693                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8694                }
8695            }
8696        } finally {
8697            Binder.restoreCallingIdentity(ident);
8698        }
8699    }
8700
8701    @Override
8702    public void startLockTaskMode(int taskId) {
8703        final TaskRecord task;
8704        long ident = Binder.clearCallingIdentity();
8705        try {
8706            synchronized (this) {
8707                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8708            }
8709        } finally {
8710            Binder.restoreCallingIdentity(ident);
8711        }
8712        if (task != null) {
8713            startLockTaskMode(task);
8714        }
8715    }
8716
8717    @Override
8718    public void startLockTaskMode(IBinder token) {
8719        final TaskRecord task;
8720        long ident = Binder.clearCallingIdentity();
8721        try {
8722            synchronized (this) {
8723                final ActivityRecord r = ActivityRecord.forToken(token);
8724                if (r == null) {
8725                    return;
8726                }
8727                task = r.task;
8728            }
8729        } finally {
8730            Binder.restoreCallingIdentity(ident);
8731        }
8732        if (task != null) {
8733            startLockTaskMode(task);
8734        }
8735    }
8736
8737    @Override
8738    public void startLockTaskModeOnCurrent() throws RemoteException {
8739        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8740                "startLockTaskModeOnCurrent");
8741        ActivityRecord r = null;
8742        synchronized (this) {
8743            r = mStackSupervisor.topRunningActivityLocked();
8744        }
8745        startLockTaskMode(r.task);
8746    }
8747
8748    @Override
8749    public void stopLockTaskMode() {
8750        // Verify that the user matches the package of the intent for the TaskRecord
8751        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8752        // and stopLockTaskMode.
8753        final int callingUid = Binder.getCallingUid();
8754        if (callingUid != Process.SYSTEM_UID) {
8755            try {
8756                String pkg =
8757                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8758                int uid = mContext.getPackageManager().getPackageUid(pkg,
8759                        Binder.getCallingUserHandle().getIdentifier());
8760                if (uid != callingUid) {
8761                    throw new SecurityException("Invalid uid, expected " + uid);
8762                }
8763            } catch (NameNotFoundException e) {
8764                Log.d(TAG, "stopLockTaskMode " + e);
8765                return;
8766            }
8767        }
8768        long ident = Binder.clearCallingIdentity();
8769        try {
8770            Log.d(TAG, "stopLockTaskMode");
8771            // Stop lock task
8772            synchronized (this) {
8773                mStackSupervisor.setLockTaskModeLocked(null, false);
8774            }
8775        } finally {
8776            Binder.restoreCallingIdentity(ident);
8777        }
8778    }
8779
8780    @Override
8781    public void stopLockTaskModeOnCurrent() throws RemoteException {
8782        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8783                "stopLockTaskModeOnCurrent");
8784        long ident = Binder.clearCallingIdentity();
8785        try {
8786            stopLockTaskMode();
8787        } finally {
8788            Binder.restoreCallingIdentity(ident);
8789        }
8790    }
8791
8792    @Override
8793    public boolean isInLockTaskMode() {
8794        synchronized (this) {
8795            return mStackSupervisor.isInLockTaskMode();
8796        }
8797    }
8798
8799    // =========================================================
8800    // CONTENT PROVIDERS
8801    // =========================================================
8802
8803    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8804        List<ProviderInfo> providers = null;
8805        try {
8806            providers = AppGlobals.getPackageManager().
8807                queryContentProviders(app.processName, app.uid,
8808                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8809        } catch (RemoteException ex) {
8810        }
8811        if (DEBUG_MU)
8812            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8813        int userId = app.userId;
8814        if (providers != null) {
8815            int N = providers.size();
8816            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8817            for (int i=0; i<N; i++) {
8818                ProviderInfo cpi =
8819                    (ProviderInfo)providers.get(i);
8820                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8821                        cpi.name, cpi.flags);
8822                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8823                    // This is a singleton provider, but a user besides the
8824                    // default user is asking to initialize a process it runs
8825                    // in...  well, no, it doesn't actually run in this process,
8826                    // it runs in the process of the default user.  Get rid of it.
8827                    providers.remove(i);
8828                    N--;
8829                    i--;
8830                    continue;
8831                }
8832
8833                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8834                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8835                if (cpr == null) {
8836                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8837                    mProviderMap.putProviderByClass(comp, cpr);
8838                }
8839                if (DEBUG_MU)
8840                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8841                app.pubProviders.put(cpi.name, cpr);
8842                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8843                    // Don't add this if it is a platform component that is marked
8844                    // to run in multiple processes, because this is actually
8845                    // part of the framework so doesn't make sense to track as a
8846                    // separate apk in the process.
8847                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8848                            mProcessStats);
8849                }
8850                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8851            }
8852        }
8853        return providers;
8854    }
8855
8856    /**
8857     * Check if {@link ProcessRecord} has a possible chance at accessing the
8858     * given {@link ProviderInfo}. Final permission checking is always done
8859     * in {@link ContentProvider}.
8860     */
8861    private final String checkContentProviderPermissionLocked(
8862            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8863        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8864        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8865        boolean checkedGrants = false;
8866        if (checkUser) {
8867            // Looking for cross-user grants before enforcing the typical cross-users permissions
8868            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8869            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8870                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8871                    return null;
8872                }
8873                checkedGrants = true;
8874            }
8875            userId = handleIncomingUser(callingPid, callingUid, userId,
8876                    false, ALLOW_NON_FULL,
8877                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8878            if (userId != tmpTargetUserId) {
8879                // When we actually went to determine the final targer user ID, this ended
8880                // up different than our initial check for the authority.  This is because
8881                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8882                // SELF.  So we need to re-check the grants again.
8883                checkedGrants = false;
8884            }
8885        }
8886        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8887                cpi.applicationInfo.uid, cpi.exported)
8888                == PackageManager.PERMISSION_GRANTED) {
8889            return null;
8890        }
8891        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8892                cpi.applicationInfo.uid, cpi.exported)
8893                == PackageManager.PERMISSION_GRANTED) {
8894            return null;
8895        }
8896
8897        PathPermission[] pps = cpi.pathPermissions;
8898        if (pps != null) {
8899            int i = pps.length;
8900            while (i > 0) {
8901                i--;
8902                PathPermission pp = pps[i];
8903                String pprperm = pp.getReadPermission();
8904                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8905                        cpi.applicationInfo.uid, cpi.exported)
8906                        == PackageManager.PERMISSION_GRANTED) {
8907                    return null;
8908                }
8909                String ppwperm = pp.getWritePermission();
8910                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8911                        cpi.applicationInfo.uid, cpi.exported)
8912                        == PackageManager.PERMISSION_GRANTED) {
8913                    return null;
8914                }
8915            }
8916        }
8917        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8918            return null;
8919        }
8920
8921        String msg;
8922        if (!cpi.exported) {
8923            msg = "Permission Denial: opening provider " + cpi.name
8924                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8925                    + ", uid=" + callingUid + ") that is not exported from uid "
8926                    + cpi.applicationInfo.uid;
8927        } else {
8928            msg = "Permission Denial: opening provider " + cpi.name
8929                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8930                    + ", uid=" + callingUid + ") requires "
8931                    + cpi.readPermission + " or " + cpi.writePermission;
8932        }
8933        Slog.w(TAG, msg);
8934        return msg;
8935    }
8936
8937    /**
8938     * Returns if the ContentProvider has granted a uri to callingUid
8939     */
8940    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8941        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8942        if (perms != null) {
8943            for (int i=perms.size()-1; i>=0; i--) {
8944                GrantUri grantUri = perms.keyAt(i);
8945                if (grantUri.sourceUserId == userId || !checkUser) {
8946                    if (matchesProvider(grantUri.uri, cpi)) {
8947                        return true;
8948                    }
8949                }
8950            }
8951        }
8952        return false;
8953    }
8954
8955    /**
8956     * Returns true if the uri authority is one of the authorities specified in the provider.
8957     */
8958    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8959        String uriAuth = uri.getAuthority();
8960        String cpiAuth = cpi.authority;
8961        if (cpiAuth.indexOf(';') == -1) {
8962            return cpiAuth.equals(uriAuth);
8963        }
8964        String[] cpiAuths = cpiAuth.split(";");
8965        int length = cpiAuths.length;
8966        for (int i = 0; i < length; i++) {
8967            if (cpiAuths[i].equals(uriAuth)) return true;
8968        }
8969        return false;
8970    }
8971
8972    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8973            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8974        if (r != null) {
8975            for (int i=0; i<r.conProviders.size(); i++) {
8976                ContentProviderConnection conn = r.conProviders.get(i);
8977                if (conn.provider == cpr) {
8978                    if (DEBUG_PROVIDER) Slog.v(TAG,
8979                            "Adding provider requested by "
8980                            + r.processName + " from process "
8981                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8982                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8983                    if (stable) {
8984                        conn.stableCount++;
8985                        conn.numStableIncs++;
8986                    } else {
8987                        conn.unstableCount++;
8988                        conn.numUnstableIncs++;
8989                    }
8990                    return conn;
8991                }
8992            }
8993            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8994            if (stable) {
8995                conn.stableCount = 1;
8996                conn.numStableIncs = 1;
8997            } else {
8998                conn.unstableCount = 1;
8999                conn.numUnstableIncs = 1;
9000            }
9001            cpr.connections.add(conn);
9002            r.conProviders.add(conn);
9003            return conn;
9004        }
9005        cpr.addExternalProcessHandleLocked(externalProcessToken);
9006        return null;
9007    }
9008
9009    boolean decProviderCountLocked(ContentProviderConnection conn,
9010            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9011        if (conn != null) {
9012            cpr = conn.provider;
9013            if (DEBUG_PROVIDER) Slog.v(TAG,
9014                    "Removing provider requested by "
9015                    + conn.client.processName + " from process "
9016                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9017                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9018            if (stable) {
9019                conn.stableCount--;
9020            } else {
9021                conn.unstableCount--;
9022            }
9023            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9024                cpr.connections.remove(conn);
9025                conn.client.conProviders.remove(conn);
9026                return true;
9027            }
9028            return false;
9029        }
9030        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9031        return false;
9032    }
9033
9034    private void checkTime(long startTime, String where) {
9035        long now = SystemClock.elapsedRealtime();
9036        if ((now-startTime) > 1000) {
9037            // If we are taking more than a second, log about it.
9038            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9039        }
9040    }
9041
9042    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9043            String name, IBinder token, boolean stable, int userId) {
9044        ContentProviderRecord cpr;
9045        ContentProviderConnection conn = null;
9046        ProviderInfo cpi = null;
9047
9048        synchronized(this) {
9049            long startTime = SystemClock.elapsedRealtime();
9050
9051            ProcessRecord r = null;
9052            if (caller != null) {
9053                r = getRecordForAppLocked(caller);
9054                if (r == null) {
9055                    throw new SecurityException(
9056                            "Unable to find app for caller " + caller
9057                          + " (pid=" + Binder.getCallingPid()
9058                          + ") when getting content provider " + name);
9059                }
9060            }
9061
9062            boolean checkCrossUser = true;
9063
9064            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9065
9066            // First check if this content provider has been published...
9067            cpr = mProviderMap.getProviderByName(name, userId);
9068            // If that didn't work, check if it exists for user 0 and then
9069            // verify that it's a singleton provider before using it.
9070            if (cpr == null && userId != UserHandle.USER_OWNER) {
9071                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9072                if (cpr != null) {
9073                    cpi = cpr.info;
9074                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9075                            cpi.name, cpi.flags)
9076                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9077                        userId = UserHandle.USER_OWNER;
9078                        checkCrossUser = false;
9079                    } else {
9080                        cpr = null;
9081                        cpi = null;
9082                    }
9083                }
9084            }
9085
9086            boolean providerRunning = cpr != null;
9087            if (providerRunning) {
9088                cpi = cpr.info;
9089                String msg;
9090                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9091                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9092                        != null) {
9093                    throw new SecurityException(msg);
9094                }
9095                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9096
9097                if (r != null && cpr.canRunHere(r)) {
9098                    // This provider has been published or is in the process
9099                    // of being published...  but it is also allowed to run
9100                    // in the caller's process, so don't make a connection
9101                    // and just let the caller instantiate its own instance.
9102                    ContentProviderHolder holder = cpr.newHolder(null);
9103                    // don't give caller the provider object, it needs
9104                    // to make its own.
9105                    holder.provider = null;
9106                    return holder;
9107                }
9108
9109                final long origId = Binder.clearCallingIdentity();
9110
9111                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9112
9113                // In this case the provider instance already exists, so we can
9114                // return it right away.
9115                conn = incProviderCountLocked(r, cpr, token, stable);
9116                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9117                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9118                        // If this is a perceptible app accessing the provider,
9119                        // make sure to count it as being accessed and thus
9120                        // back up on the LRU list.  This is good because
9121                        // content providers are often expensive to start.
9122                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9123                        updateLruProcessLocked(cpr.proc, false, null);
9124                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9125                    }
9126                }
9127
9128                if (cpr.proc != null) {
9129                    if (false) {
9130                        if (cpr.name.flattenToShortString().equals(
9131                                "com.android.providers.calendar/.CalendarProvider2")) {
9132                            Slog.v(TAG, "****************** KILLING "
9133                                + cpr.name.flattenToShortString());
9134                            Process.killProcess(cpr.proc.pid);
9135                        }
9136                    }
9137                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9138                    boolean success = updateOomAdjLocked(cpr.proc);
9139                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9140                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9141                    // NOTE: there is still a race here where a signal could be
9142                    // pending on the process even though we managed to update its
9143                    // adj level.  Not sure what to do about this, but at least
9144                    // the race is now smaller.
9145                    if (!success) {
9146                        // Uh oh...  it looks like the provider's process
9147                        // has been killed on us.  We need to wait for a new
9148                        // process to be started, and make sure its death
9149                        // doesn't kill our process.
9150                        Slog.i(TAG,
9151                                "Existing provider " + cpr.name.flattenToShortString()
9152                                + " is crashing; detaching " + r);
9153                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9154                        checkTime(startTime, "getContentProviderImpl: before appDied");
9155                        appDiedLocked(cpr.proc);
9156                        checkTime(startTime, "getContentProviderImpl: after appDied");
9157                        if (!lastRef) {
9158                            // This wasn't the last ref our process had on
9159                            // the provider...  we have now been killed, bail.
9160                            return null;
9161                        }
9162                        providerRunning = false;
9163                        conn = null;
9164                    }
9165                }
9166
9167                Binder.restoreCallingIdentity(origId);
9168            }
9169
9170            boolean singleton;
9171            if (!providerRunning) {
9172                try {
9173                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9174                    cpi = AppGlobals.getPackageManager().
9175                        resolveContentProvider(name,
9176                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9177                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9178                } catch (RemoteException ex) {
9179                }
9180                if (cpi == null) {
9181                    return null;
9182                }
9183                // If the provider is a singleton AND
9184                // (it's a call within the same user || the provider is a
9185                // privileged app)
9186                // Then allow connecting to the singleton provider
9187                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9188                        cpi.name, cpi.flags)
9189                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9190                if (singleton) {
9191                    userId = UserHandle.USER_OWNER;
9192                }
9193                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9194                checkTime(startTime, "getContentProviderImpl: got app info for user");
9195
9196                String msg;
9197                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9198                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9199                        != null) {
9200                    throw new SecurityException(msg);
9201                }
9202                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9203
9204                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9205                        && !cpi.processName.equals("system")) {
9206                    // If this content provider does not run in the system
9207                    // process, and the system is not yet ready to run other
9208                    // processes, then fail fast instead of hanging.
9209                    throw new IllegalArgumentException(
9210                            "Attempt to launch content provider before system ready");
9211                }
9212
9213                // Make sure that the user who owns this provider is started.  If not,
9214                // we don't want to allow it to run.
9215                if (mStartedUsers.get(userId) == null) {
9216                    Slog.w(TAG, "Unable to launch app "
9217                            + cpi.applicationInfo.packageName + "/"
9218                            + cpi.applicationInfo.uid + " for provider "
9219                            + name + ": user " + userId + " is stopped");
9220                    return null;
9221                }
9222
9223                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9224                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9225                cpr = mProviderMap.getProviderByClass(comp, userId);
9226                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9227                final boolean firstClass = cpr == null;
9228                if (firstClass) {
9229                    final long ident = Binder.clearCallingIdentity();
9230                    try {
9231                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9232                        ApplicationInfo ai =
9233                            AppGlobals.getPackageManager().
9234                                getApplicationInfo(
9235                                        cpi.applicationInfo.packageName,
9236                                        STOCK_PM_FLAGS, userId);
9237                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9238                        if (ai == null) {
9239                            Slog.w(TAG, "No package info for content provider "
9240                                    + cpi.name);
9241                            return null;
9242                        }
9243                        ai = getAppInfoForUser(ai, userId);
9244                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9245                    } catch (RemoteException ex) {
9246                        // pm is in same process, this will never happen.
9247                    } finally {
9248                        Binder.restoreCallingIdentity(ident);
9249                    }
9250                }
9251
9252                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9253
9254                if (r != null && cpr.canRunHere(r)) {
9255                    // If this is a multiprocess provider, then just return its
9256                    // info and allow the caller to instantiate it.  Only do
9257                    // this if the provider is the same user as the caller's
9258                    // process, or can run as root (so can be in any process).
9259                    return cpr.newHolder(null);
9260                }
9261
9262                if (DEBUG_PROVIDER) {
9263                    RuntimeException e = new RuntimeException("here");
9264                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9265                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9266                }
9267
9268                // This is single process, and our app is now connecting to it.
9269                // See if we are already in the process of launching this
9270                // provider.
9271                final int N = mLaunchingProviders.size();
9272                int i;
9273                for (i=0; i<N; i++) {
9274                    if (mLaunchingProviders.get(i) == cpr) {
9275                        break;
9276                    }
9277                }
9278
9279                // If the provider is not already being launched, then get it
9280                // started.
9281                if (i >= N) {
9282                    final long origId = Binder.clearCallingIdentity();
9283
9284                    try {
9285                        // Content provider is now in use, its package can't be stopped.
9286                        try {
9287                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9288                            AppGlobals.getPackageManager().setPackageStoppedState(
9289                                    cpr.appInfo.packageName, false, userId);
9290                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9291                        } catch (RemoteException e) {
9292                        } catch (IllegalArgumentException e) {
9293                            Slog.w(TAG, "Failed trying to unstop package "
9294                                    + cpr.appInfo.packageName + ": " + e);
9295                        }
9296
9297                        // Use existing process if already started
9298                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9299                        ProcessRecord proc = getProcessRecordLocked(
9300                                cpi.processName, cpr.appInfo.uid, false);
9301                        if (proc != null && proc.thread != null) {
9302                            if (DEBUG_PROVIDER) {
9303                                Slog.d(TAG, "Installing in existing process " + proc);
9304                            }
9305                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9306                            proc.pubProviders.put(cpi.name, cpr);
9307                            try {
9308                                proc.thread.scheduleInstallProvider(cpi);
9309                            } catch (RemoteException e) {
9310                            }
9311                        } else {
9312                            checkTime(startTime, "getContentProviderImpl: before start process");
9313                            proc = startProcessLocked(cpi.processName,
9314                                    cpr.appInfo, false, 0, "content provider",
9315                                    new ComponentName(cpi.applicationInfo.packageName,
9316                                            cpi.name), false, false, false);
9317                            checkTime(startTime, "getContentProviderImpl: after start process");
9318                            if (proc == null) {
9319                                Slog.w(TAG, "Unable to launch app "
9320                                        + cpi.applicationInfo.packageName + "/"
9321                                        + cpi.applicationInfo.uid + " for provider "
9322                                        + name + ": process is bad");
9323                                return null;
9324                            }
9325                        }
9326                        cpr.launchingApp = proc;
9327                        mLaunchingProviders.add(cpr);
9328                    } finally {
9329                        Binder.restoreCallingIdentity(origId);
9330                    }
9331                }
9332
9333                checkTime(startTime, "getContentProviderImpl: updating data structures");
9334
9335                // Make sure the provider is published (the same provider class
9336                // may be published under multiple names).
9337                if (firstClass) {
9338                    mProviderMap.putProviderByClass(comp, cpr);
9339                }
9340
9341                mProviderMap.putProviderByName(name, cpr);
9342                conn = incProviderCountLocked(r, cpr, token, stable);
9343                if (conn != null) {
9344                    conn.waiting = true;
9345                }
9346            }
9347            checkTime(startTime, "getContentProviderImpl: done!");
9348        }
9349
9350        // Wait for the provider to be published...
9351        synchronized (cpr) {
9352            while (cpr.provider == null) {
9353                if (cpr.launchingApp == null) {
9354                    Slog.w(TAG, "Unable to launch app "
9355                            + cpi.applicationInfo.packageName + "/"
9356                            + cpi.applicationInfo.uid + " for provider "
9357                            + name + ": launching app became null");
9358                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9359                            UserHandle.getUserId(cpi.applicationInfo.uid),
9360                            cpi.applicationInfo.packageName,
9361                            cpi.applicationInfo.uid, name);
9362                    return null;
9363                }
9364                try {
9365                    if (DEBUG_MU) {
9366                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9367                                + cpr.launchingApp);
9368                    }
9369                    if (conn != null) {
9370                        conn.waiting = true;
9371                    }
9372                    cpr.wait();
9373                } catch (InterruptedException ex) {
9374                } finally {
9375                    if (conn != null) {
9376                        conn.waiting = false;
9377                    }
9378                }
9379            }
9380        }
9381        return cpr != null ? cpr.newHolder(conn) : null;
9382    }
9383
9384    @Override
9385    public final ContentProviderHolder getContentProvider(
9386            IApplicationThread caller, String name, int userId, boolean stable) {
9387        enforceNotIsolatedCaller("getContentProvider");
9388        if (caller == null) {
9389            String msg = "null IApplicationThread when getting content provider "
9390                    + name;
9391            Slog.w(TAG, msg);
9392            throw new SecurityException(msg);
9393        }
9394        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9395        // with cross-user grant.
9396        return getContentProviderImpl(caller, name, null, stable, userId);
9397    }
9398
9399    public ContentProviderHolder getContentProviderExternal(
9400            String name, int userId, IBinder token) {
9401        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9402            "Do not have permission in call getContentProviderExternal()");
9403        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9404                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9405        return getContentProviderExternalUnchecked(name, token, userId);
9406    }
9407
9408    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9409            IBinder token, int userId) {
9410        return getContentProviderImpl(null, name, token, true, userId);
9411    }
9412
9413    /**
9414     * Drop a content provider from a ProcessRecord's bookkeeping
9415     */
9416    public void removeContentProvider(IBinder connection, boolean stable) {
9417        enforceNotIsolatedCaller("removeContentProvider");
9418        long ident = Binder.clearCallingIdentity();
9419        try {
9420            synchronized (this) {
9421                ContentProviderConnection conn;
9422                try {
9423                    conn = (ContentProviderConnection)connection;
9424                } catch (ClassCastException e) {
9425                    String msg ="removeContentProvider: " + connection
9426                            + " not a ContentProviderConnection";
9427                    Slog.w(TAG, msg);
9428                    throw new IllegalArgumentException(msg);
9429                }
9430                if (conn == null) {
9431                    throw new NullPointerException("connection is null");
9432                }
9433                if (decProviderCountLocked(conn, null, null, stable)) {
9434                    updateOomAdjLocked();
9435                }
9436            }
9437        } finally {
9438            Binder.restoreCallingIdentity(ident);
9439        }
9440    }
9441
9442    public void removeContentProviderExternal(String name, IBinder token) {
9443        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9444            "Do not have permission in call removeContentProviderExternal()");
9445        int userId = UserHandle.getCallingUserId();
9446        long ident = Binder.clearCallingIdentity();
9447        try {
9448            removeContentProviderExternalUnchecked(name, token, userId);
9449        } finally {
9450            Binder.restoreCallingIdentity(ident);
9451        }
9452    }
9453
9454    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9455        synchronized (this) {
9456            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9457            if(cpr == null) {
9458                //remove from mProvidersByClass
9459                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9460                return;
9461            }
9462
9463            //update content provider record entry info
9464            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9465            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9466            if (localCpr.hasExternalProcessHandles()) {
9467                if (localCpr.removeExternalProcessHandleLocked(token)) {
9468                    updateOomAdjLocked();
9469                } else {
9470                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9471                            + " with no external reference for token: "
9472                            + token + ".");
9473                }
9474            } else {
9475                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9476                        + " with no external references.");
9477            }
9478        }
9479    }
9480
9481    public final void publishContentProviders(IApplicationThread caller,
9482            List<ContentProviderHolder> providers) {
9483        if (providers == null) {
9484            return;
9485        }
9486
9487        enforceNotIsolatedCaller("publishContentProviders");
9488        synchronized (this) {
9489            final ProcessRecord r = getRecordForAppLocked(caller);
9490            if (DEBUG_MU)
9491                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9492            if (r == null) {
9493                throw new SecurityException(
9494                        "Unable to find app for caller " + caller
9495                      + " (pid=" + Binder.getCallingPid()
9496                      + ") when publishing content providers");
9497            }
9498
9499            final long origId = Binder.clearCallingIdentity();
9500
9501            final int N = providers.size();
9502            for (int i=0; i<N; i++) {
9503                ContentProviderHolder src = providers.get(i);
9504                if (src == null || src.info == null || src.provider == null) {
9505                    continue;
9506                }
9507                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9508                if (DEBUG_MU)
9509                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9510                if (dst != null) {
9511                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9512                    mProviderMap.putProviderByClass(comp, dst);
9513                    String names[] = dst.info.authority.split(";");
9514                    for (int j = 0; j < names.length; j++) {
9515                        mProviderMap.putProviderByName(names[j], dst);
9516                    }
9517
9518                    int NL = mLaunchingProviders.size();
9519                    int j;
9520                    for (j=0; j<NL; j++) {
9521                        if (mLaunchingProviders.get(j) == dst) {
9522                            mLaunchingProviders.remove(j);
9523                            j--;
9524                            NL--;
9525                        }
9526                    }
9527                    synchronized (dst) {
9528                        dst.provider = src.provider;
9529                        dst.proc = r;
9530                        dst.notifyAll();
9531                    }
9532                    updateOomAdjLocked(r);
9533                }
9534            }
9535
9536            Binder.restoreCallingIdentity(origId);
9537        }
9538    }
9539
9540    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9541        ContentProviderConnection conn;
9542        try {
9543            conn = (ContentProviderConnection)connection;
9544        } catch (ClassCastException e) {
9545            String msg ="refContentProvider: " + connection
9546                    + " not a ContentProviderConnection";
9547            Slog.w(TAG, msg);
9548            throw new IllegalArgumentException(msg);
9549        }
9550        if (conn == null) {
9551            throw new NullPointerException("connection is null");
9552        }
9553
9554        synchronized (this) {
9555            if (stable > 0) {
9556                conn.numStableIncs += stable;
9557            }
9558            stable = conn.stableCount + stable;
9559            if (stable < 0) {
9560                throw new IllegalStateException("stableCount < 0: " + stable);
9561            }
9562
9563            if (unstable > 0) {
9564                conn.numUnstableIncs += unstable;
9565            }
9566            unstable = conn.unstableCount + unstable;
9567            if (unstable < 0) {
9568                throw new IllegalStateException("unstableCount < 0: " + unstable);
9569            }
9570
9571            if ((stable+unstable) <= 0) {
9572                throw new IllegalStateException("ref counts can't go to zero here: stable="
9573                        + stable + " unstable=" + unstable);
9574            }
9575            conn.stableCount = stable;
9576            conn.unstableCount = unstable;
9577            return !conn.dead;
9578        }
9579    }
9580
9581    public void unstableProviderDied(IBinder connection) {
9582        ContentProviderConnection conn;
9583        try {
9584            conn = (ContentProviderConnection)connection;
9585        } catch (ClassCastException e) {
9586            String msg ="refContentProvider: " + connection
9587                    + " not a ContentProviderConnection";
9588            Slog.w(TAG, msg);
9589            throw new IllegalArgumentException(msg);
9590        }
9591        if (conn == null) {
9592            throw new NullPointerException("connection is null");
9593        }
9594
9595        // Safely retrieve the content provider associated with the connection.
9596        IContentProvider provider;
9597        synchronized (this) {
9598            provider = conn.provider.provider;
9599        }
9600
9601        if (provider == null) {
9602            // Um, yeah, we're way ahead of you.
9603            return;
9604        }
9605
9606        // Make sure the caller is being honest with us.
9607        if (provider.asBinder().pingBinder()) {
9608            // Er, no, still looks good to us.
9609            synchronized (this) {
9610                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9611                        + " says " + conn + " died, but we don't agree");
9612                return;
9613            }
9614        }
9615
9616        // Well look at that!  It's dead!
9617        synchronized (this) {
9618            if (conn.provider.provider != provider) {
9619                // But something changed...  good enough.
9620                return;
9621            }
9622
9623            ProcessRecord proc = conn.provider.proc;
9624            if (proc == null || proc.thread == null) {
9625                // Seems like the process is already cleaned up.
9626                return;
9627            }
9628
9629            // As far as we're concerned, this is just like receiving a
9630            // death notification...  just a bit prematurely.
9631            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9632                    + ") early provider death");
9633            final long ident = Binder.clearCallingIdentity();
9634            try {
9635                appDiedLocked(proc);
9636            } finally {
9637                Binder.restoreCallingIdentity(ident);
9638            }
9639        }
9640    }
9641
9642    @Override
9643    public void appNotRespondingViaProvider(IBinder connection) {
9644        enforceCallingPermission(
9645                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9646
9647        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9648        if (conn == null) {
9649            Slog.w(TAG, "ContentProviderConnection is null");
9650            return;
9651        }
9652
9653        final ProcessRecord host = conn.provider.proc;
9654        if (host == null) {
9655            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9656            return;
9657        }
9658
9659        final long token = Binder.clearCallingIdentity();
9660        try {
9661            appNotResponding(host, null, null, false, "ContentProvider not responding");
9662        } finally {
9663            Binder.restoreCallingIdentity(token);
9664        }
9665    }
9666
9667    public final void installSystemProviders() {
9668        List<ProviderInfo> providers;
9669        synchronized (this) {
9670            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9671            providers = generateApplicationProvidersLocked(app);
9672            if (providers != null) {
9673                for (int i=providers.size()-1; i>=0; i--) {
9674                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9675                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9676                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9677                                + ": not system .apk");
9678                        providers.remove(i);
9679                    }
9680                }
9681            }
9682        }
9683        if (providers != null) {
9684            mSystemThread.installSystemProviders(providers);
9685        }
9686
9687        mCoreSettingsObserver = new CoreSettingsObserver(this);
9688
9689        //mUsageStatsService.monitorPackages();
9690    }
9691
9692    /**
9693     * Allows apps to retrieve the MIME type of a URI.
9694     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9695     * users, then it does not need permission to access the ContentProvider.
9696     * Either, it needs cross-user uri grants.
9697     *
9698     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9699     *
9700     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9701     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9702     */
9703    public String getProviderMimeType(Uri uri, int userId) {
9704        enforceNotIsolatedCaller("getProviderMimeType");
9705        final String name = uri.getAuthority();
9706        int callingUid = Binder.getCallingUid();
9707        int callingPid = Binder.getCallingPid();
9708        long ident = 0;
9709        boolean clearedIdentity = false;
9710        userId = unsafeConvertIncomingUser(userId);
9711        if (canClearIdentity(callingPid, callingUid, userId)) {
9712            clearedIdentity = true;
9713            ident = Binder.clearCallingIdentity();
9714        }
9715        ContentProviderHolder holder = null;
9716        try {
9717            holder = getContentProviderExternalUnchecked(name, null, userId);
9718            if (holder != null) {
9719                return holder.provider.getType(uri);
9720            }
9721        } catch (RemoteException e) {
9722            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9723            return null;
9724        } finally {
9725            // We need to clear the identity to call removeContentProviderExternalUnchecked
9726            if (!clearedIdentity) {
9727                ident = Binder.clearCallingIdentity();
9728            }
9729            try {
9730                if (holder != null) {
9731                    removeContentProviderExternalUnchecked(name, null, userId);
9732                }
9733            } finally {
9734                Binder.restoreCallingIdentity(ident);
9735            }
9736        }
9737
9738        return null;
9739    }
9740
9741    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9742        if (UserHandle.getUserId(callingUid) == userId) {
9743            return true;
9744        }
9745        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9746                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9747                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9748                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9749                return true;
9750        }
9751        return false;
9752    }
9753
9754    // =========================================================
9755    // GLOBAL MANAGEMENT
9756    // =========================================================
9757
9758    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9759            boolean isolated, int isolatedUid) {
9760        String proc = customProcess != null ? customProcess : info.processName;
9761        BatteryStatsImpl.Uid.Proc ps = null;
9762        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9763        int uid = info.uid;
9764        if (isolated) {
9765            if (isolatedUid == 0) {
9766                int userId = UserHandle.getUserId(uid);
9767                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9768                while (true) {
9769                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9770                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9771                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9772                    }
9773                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9774                    mNextIsolatedProcessUid++;
9775                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9776                        // No process for this uid, use it.
9777                        break;
9778                    }
9779                    stepsLeft--;
9780                    if (stepsLeft <= 0) {
9781                        return null;
9782                    }
9783                }
9784            } else {
9785                // Special case for startIsolatedProcess (internal only), where
9786                // the uid of the isolated process is specified by the caller.
9787                uid = isolatedUid;
9788            }
9789        }
9790        return new ProcessRecord(stats, info, proc, uid);
9791    }
9792
9793    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9794            String abiOverride) {
9795        ProcessRecord app;
9796        if (!isolated) {
9797            app = getProcessRecordLocked(info.processName, info.uid, true);
9798        } else {
9799            app = null;
9800        }
9801
9802        if (app == null) {
9803            app = newProcessRecordLocked(info, null, isolated, 0);
9804            mProcessNames.put(info.processName, app.uid, app);
9805            if (isolated) {
9806                mIsolatedProcesses.put(app.uid, app);
9807            }
9808            updateLruProcessLocked(app, false, null);
9809            updateOomAdjLocked();
9810        }
9811
9812        // This package really, really can not be stopped.
9813        try {
9814            AppGlobals.getPackageManager().setPackageStoppedState(
9815                    info.packageName, false, UserHandle.getUserId(app.uid));
9816        } catch (RemoteException e) {
9817        } catch (IllegalArgumentException e) {
9818            Slog.w(TAG, "Failed trying to unstop package "
9819                    + info.packageName + ": " + e);
9820        }
9821
9822        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9823                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9824            app.persistent = true;
9825            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9826        }
9827        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9828            mPersistentStartingProcesses.add(app);
9829            startProcessLocked(app, "added application", app.processName, abiOverride,
9830                    null /* entryPoint */, null /* entryPointArgs */);
9831        }
9832
9833        return app;
9834    }
9835
9836    public void unhandledBack() {
9837        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9838                "unhandledBack()");
9839
9840        synchronized(this) {
9841            final long origId = Binder.clearCallingIdentity();
9842            try {
9843                getFocusedStack().unhandledBackLocked();
9844            } finally {
9845                Binder.restoreCallingIdentity(origId);
9846            }
9847        }
9848    }
9849
9850    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9851        enforceNotIsolatedCaller("openContentUri");
9852        final int userId = UserHandle.getCallingUserId();
9853        String name = uri.getAuthority();
9854        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9855        ParcelFileDescriptor pfd = null;
9856        if (cph != null) {
9857            // We record the binder invoker's uid in thread-local storage before
9858            // going to the content provider to open the file.  Later, in the code
9859            // that handles all permissions checks, we look for this uid and use
9860            // that rather than the Activity Manager's own uid.  The effect is that
9861            // we do the check against the caller's permissions even though it looks
9862            // to the content provider like the Activity Manager itself is making
9863            // the request.
9864            sCallerIdentity.set(new Identity(
9865                    Binder.getCallingPid(), Binder.getCallingUid()));
9866            try {
9867                pfd = cph.provider.openFile(null, uri, "r", null);
9868            } catch (FileNotFoundException e) {
9869                // do nothing; pfd will be returned null
9870            } finally {
9871                // Ensure that whatever happens, we clean up the identity state
9872                sCallerIdentity.remove();
9873            }
9874
9875            // We've got the fd now, so we're done with the provider.
9876            removeContentProviderExternalUnchecked(name, null, userId);
9877        } else {
9878            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9879        }
9880        return pfd;
9881    }
9882
9883    // Actually is sleeping or shutting down or whatever else in the future
9884    // is an inactive state.
9885    public boolean isSleepingOrShuttingDown() {
9886        return isSleeping() || mShuttingDown;
9887    }
9888
9889    public boolean isSleeping() {
9890        return mSleeping;
9891    }
9892
9893    void goingToSleep() {
9894        synchronized(this) {
9895            mWentToSleep = true;
9896            goToSleepIfNeededLocked();
9897        }
9898    }
9899
9900    void finishRunningVoiceLocked() {
9901        if (mRunningVoice) {
9902            mRunningVoice = false;
9903            goToSleepIfNeededLocked();
9904        }
9905    }
9906
9907    void goToSleepIfNeededLocked() {
9908        if (mWentToSleep && !mRunningVoice) {
9909            if (!mSleeping) {
9910                mSleeping = true;
9911                mStackSupervisor.goingToSleepLocked();
9912
9913                // Initialize the wake times of all processes.
9914                checkExcessivePowerUsageLocked(false);
9915                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9916                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9917                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9918            }
9919        }
9920    }
9921
9922    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9923        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9924            // Never persist the home stack.
9925            return;
9926        }
9927        mTaskPersister.wakeup(task, flush);
9928    }
9929
9930    @Override
9931    public boolean shutdown(int timeout) {
9932        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9933                != PackageManager.PERMISSION_GRANTED) {
9934            throw new SecurityException("Requires permission "
9935                    + android.Manifest.permission.SHUTDOWN);
9936        }
9937
9938        boolean timedout = false;
9939
9940        synchronized(this) {
9941            mShuttingDown = true;
9942            updateEventDispatchingLocked();
9943            timedout = mStackSupervisor.shutdownLocked(timeout);
9944        }
9945
9946        mAppOpsService.shutdown();
9947        if (mUsageStatsService != null) {
9948            mUsageStatsService.prepareShutdown();
9949        }
9950        mBatteryStatsService.shutdown();
9951        synchronized (this) {
9952            mProcessStats.shutdownLocked();
9953        }
9954        notifyTaskPersisterLocked(null, true);
9955
9956        return timedout;
9957    }
9958
9959    public final void activitySlept(IBinder token) {
9960        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9961
9962        final long origId = Binder.clearCallingIdentity();
9963
9964        synchronized (this) {
9965            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9966            if (r != null) {
9967                mStackSupervisor.activitySleptLocked(r);
9968            }
9969        }
9970
9971        Binder.restoreCallingIdentity(origId);
9972    }
9973
9974    private String lockScreenShownToString() {
9975        switch (mLockScreenShown) {
9976            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
9977            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
9978            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
9979            default: return "Unknown=" + mLockScreenShown;
9980        }
9981    }
9982
9983    void logLockScreen(String msg) {
9984        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9985                " mLockScreenShown=" + lockScreenShownToString() + " mWentToSleep=" +
9986                mWentToSleep + " mSleeping=" + mSleeping);
9987    }
9988
9989    void comeOutOfSleepIfNeededLocked() {
9990        if ((!mWentToSleep && mLockScreenShown == LOCK_SCREEN_HIDDEN) || mRunningVoice) {
9991            if (mSleeping) {
9992                mSleeping = false;
9993                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9994            }
9995        }
9996    }
9997
9998    void wakingUp() {
9999        synchronized(this) {
10000            mWentToSleep = false;
10001            comeOutOfSleepIfNeededLocked();
10002        }
10003    }
10004
10005    void startRunningVoiceLocked() {
10006        if (!mRunningVoice) {
10007            mRunningVoice = true;
10008            comeOutOfSleepIfNeededLocked();
10009        }
10010    }
10011
10012    private void updateEventDispatchingLocked() {
10013        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10014    }
10015
10016    public void setLockScreenShown(boolean shown) {
10017        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10018                != PackageManager.PERMISSION_GRANTED) {
10019            throw new SecurityException("Requires permission "
10020                    + android.Manifest.permission.DEVICE_POWER);
10021        }
10022
10023        synchronized(this) {
10024            long ident = Binder.clearCallingIdentity();
10025            try {
10026                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10027                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10028                comeOutOfSleepIfNeededLocked();
10029            } finally {
10030                Binder.restoreCallingIdentity(ident);
10031            }
10032        }
10033    }
10034
10035    @Override
10036    public void stopAppSwitches() {
10037        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10038                != PackageManager.PERMISSION_GRANTED) {
10039            throw new SecurityException("Requires permission "
10040                    + android.Manifest.permission.STOP_APP_SWITCHES);
10041        }
10042
10043        synchronized(this) {
10044            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10045                    + APP_SWITCH_DELAY_TIME;
10046            mDidAppSwitch = false;
10047            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10048            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10049            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10050        }
10051    }
10052
10053    public void resumeAppSwitches() {
10054        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10055                != PackageManager.PERMISSION_GRANTED) {
10056            throw new SecurityException("Requires permission "
10057                    + android.Manifest.permission.STOP_APP_SWITCHES);
10058        }
10059
10060        synchronized(this) {
10061            // Note that we don't execute any pending app switches... we will
10062            // let those wait until either the timeout, or the next start
10063            // activity request.
10064            mAppSwitchesAllowedTime = 0;
10065        }
10066    }
10067
10068    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10069            int callingPid, int callingUid, String name) {
10070        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10071            return true;
10072        }
10073
10074        int perm = checkComponentPermission(
10075                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10076                sourceUid, -1, true);
10077        if (perm == PackageManager.PERMISSION_GRANTED) {
10078            return true;
10079        }
10080
10081        // If the actual IPC caller is different from the logical source, then
10082        // also see if they are allowed to control app switches.
10083        if (callingUid != -1 && callingUid != sourceUid) {
10084            perm = checkComponentPermission(
10085                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10086                    callingUid, -1, true);
10087            if (perm == PackageManager.PERMISSION_GRANTED) {
10088                return true;
10089            }
10090        }
10091
10092        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10093        return false;
10094    }
10095
10096    public void setDebugApp(String packageName, boolean waitForDebugger,
10097            boolean persistent) {
10098        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10099                "setDebugApp()");
10100
10101        long ident = Binder.clearCallingIdentity();
10102        try {
10103            // Note that this is not really thread safe if there are multiple
10104            // callers into it at the same time, but that's not a situation we
10105            // care about.
10106            if (persistent) {
10107                final ContentResolver resolver = mContext.getContentResolver();
10108                Settings.Global.putString(
10109                    resolver, Settings.Global.DEBUG_APP,
10110                    packageName);
10111                Settings.Global.putInt(
10112                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10113                    waitForDebugger ? 1 : 0);
10114            }
10115
10116            synchronized (this) {
10117                if (!persistent) {
10118                    mOrigDebugApp = mDebugApp;
10119                    mOrigWaitForDebugger = mWaitForDebugger;
10120                }
10121                mDebugApp = packageName;
10122                mWaitForDebugger = waitForDebugger;
10123                mDebugTransient = !persistent;
10124                if (packageName != null) {
10125                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10126                            false, UserHandle.USER_ALL, "set debug app");
10127                }
10128            }
10129        } finally {
10130            Binder.restoreCallingIdentity(ident);
10131        }
10132    }
10133
10134    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10135        synchronized (this) {
10136            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10137            if (!isDebuggable) {
10138                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10139                    throw new SecurityException("Process not debuggable: " + app.packageName);
10140                }
10141            }
10142
10143            mOpenGlTraceApp = processName;
10144        }
10145    }
10146
10147    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10148        synchronized (this) {
10149            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10150            if (!isDebuggable) {
10151                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10152                    throw new SecurityException("Process not debuggable: " + app.packageName);
10153                }
10154            }
10155            mProfileApp = processName;
10156            mProfileFile = profilerInfo.profileFile;
10157            if (mProfileFd != null) {
10158                try {
10159                    mProfileFd.close();
10160                } catch (IOException e) {
10161                }
10162                mProfileFd = null;
10163            }
10164            mProfileFd = profilerInfo.profileFd;
10165            mSamplingInterval = profilerInfo.samplingInterval;
10166            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10167            mProfileType = 0;
10168        }
10169    }
10170
10171    @Override
10172    public void setAlwaysFinish(boolean enabled) {
10173        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10174                "setAlwaysFinish()");
10175
10176        Settings.Global.putInt(
10177                mContext.getContentResolver(),
10178                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10179
10180        synchronized (this) {
10181            mAlwaysFinishActivities = enabled;
10182        }
10183    }
10184
10185    @Override
10186    public void setActivityController(IActivityController controller) {
10187        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10188                "setActivityController()");
10189        synchronized (this) {
10190            mController = controller;
10191            Watchdog.getInstance().setActivityController(controller);
10192        }
10193    }
10194
10195    @Override
10196    public void setUserIsMonkey(boolean userIsMonkey) {
10197        synchronized (this) {
10198            synchronized (mPidsSelfLocked) {
10199                final int callingPid = Binder.getCallingPid();
10200                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10201                if (precessRecord == null) {
10202                    throw new SecurityException("Unknown process: " + callingPid);
10203                }
10204                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10205                    throw new SecurityException("Only an instrumentation process "
10206                            + "with a UiAutomation can call setUserIsMonkey");
10207                }
10208            }
10209            mUserIsMonkey = userIsMonkey;
10210        }
10211    }
10212
10213    @Override
10214    public boolean isUserAMonkey() {
10215        synchronized (this) {
10216            // If there is a controller also implies the user is a monkey.
10217            return (mUserIsMonkey || mController != null);
10218        }
10219    }
10220
10221    public void requestBugReport() {
10222        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10223        SystemProperties.set("ctl.start", "bugreport");
10224    }
10225
10226    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10227        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10228    }
10229
10230    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10231        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10232            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10233        }
10234        return KEY_DISPATCHING_TIMEOUT;
10235    }
10236
10237    @Override
10238    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10239        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10240                != PackageManager.PERMISSION_GRANTED) {
10241            throw new SecurityException("Requires permission "
10242                    + android.Manifest.permission.FILTER_EVENTS);
10243        }
10244        ProcessRecord proc;
10245        long timeout;
10246        synchronized (this) {
10247            synchronized (mPidsSelfLocked) {
10248                proc = mPidsSelfLocked.get(pid);
10249            }
10250            timeout = getInputDispatchingTimeoutLocked(proc);
10251        }
10252
10253        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10254            return -1;
10255        }
10256
10257        return timeout;
10258    }
10259
10260    /**
10261     * Handle input dispatching timeouts.
10262     * Returns whether input dispatching should be aborted or not.
10263     */
10264    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10265            final ActivityRecord activity, final ActivityRecord parent,
10266            final boolean aboveSystem, String reason) {
10267        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10268                != PackageManager.PERMISSION_GRANTED) {
10269            throw new SecurityException("Requires permission "
10270                    + android.Manifest.permission.FILTER_EVENTS);
10271        }
10272
10273        final String annotation;
10274        if (reason == null) {
10275            annotation = "Input dispatching timed out";
10276        } else {
10277            annotation = "Input dispatching timed out (" + reason + ")";
10278        }
10279
10280        if (proc != null) {
10281            synchronized (this) {
10282                if (proc.debugging) {
10283                    return false;
10284                }
10285
10286                if (mDidDexOpt) {
10287                    // Give more time since we were dexopting.
10288                    mDidDexOpt = false;
10289                    return false;
10290                }
10291
10292                if (proc.instrumentationClass != null) {
10293                    Bundle info = new Bundle();
10294                    info.putString("shortMsg", "keyDispatchingTimedOut");
10295                    info.putString("longMsg", annotation);
10296                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10297                    return true;
10298                }
10299            }
10300            mHandler.post(new Runnable() {
10301                @Override
10302                public void run() {
10303                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10304                }
10305            });
10306        }
10307
10308        return true;
10309    }
10310
10311    public Bundle getAssistContextExtras(int requestType) {
10312        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10313                UserHandle.getCallingUserId());
10314        if (pae == null) {
10315            return null;
10316        }
10317        synchronized (pae) {
10318            while (!pae.haveResult) {
10319                try {
10320                    pae.wait();
10321                } catch (InterruptedException e) {
10322                }
10323            }
10324            if (pae.result != null) {
10325                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10326            }
10327        }
10328        synchronized (this) {
10329            mPendingAssistExtras.remove(pae);
10330            mHandler.removeCallbacks(pae);
10331        }
10332        return pae.extras;
10333    }
10334
10335    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10336            int userHandle) {
10337        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10338                "getAssistContextExtras()");
10339        PendingAssistExtras pae;
10340        Bundle extras = new Bundle();
10341        synchronized (this) {
10342            ActivityRecord activity = getFocusedStack().mResumedActivity;
10343            if (activity == null) {
10344                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10345                return null;
10346            }
10347            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10348            if (activity.app == null || activity.app.thread == null) {
10349                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10350                return null;
10351            }
10352            if (activity.app.pid == Binder.getCallingPid()) {
10353                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10354                return null;
10355            }
10356            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10357            try {
10358                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10359                        requestType);
10360                mPendingAssistExtras.add(pae);
10361                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10362            } catch (RemoteException e) {
10363                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10364                return null;
10365            }
10366            return pae;
10367        }
10368    }
10369
10370    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10371        PendingAssistExtras pae = (PendingAssistExtras)token;
10372        synchronized (pae) {
10373            pae.result = extras;
10374            pae.haveResult = true;
10375            pae.notifyAll();
10376            if (pae.intent == null) {
10377                // Caller is just waiting for the result.
10378                return;
10379            }
10380        }
10381
10382        // We are now ready to launch the assist activity.
10383        synchronized (this) {
10384            boolean exists = mPendingAssistExtras.remove(pae);
10385            mHandler.removeCallbacks(pae);
10386            if (!exists) {
10387                // Timed out.
10388                return;
10389            }
10390        }
10391        pae.intent.replaceExtras(extras);
10392        if (pae.hint != null) {
10393            pae.intent.putExtra(pae.hint, true);
10394        }
10395        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10396                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10397                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10398        closeSystemDialogs("assist");
10399        try {
10400            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10401        } catch (ActivityNotFoundException e) {
10402            Slog.w(TAG, "No activity to handle assist action.", e);
10403        }
10404    }
10405
10406    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10407        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10408    }
10409
10410    public void registerProcessObserver(IProcessObserver observer) {
10411        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10412                "registerProcessObserver()");
10413        synchronized (this) {
10414            mProcessObservers.register(observer);
10415        }
10416    }
10417
10418    @Override
10419    public void unregisterProcessObserver(IProcessObserver observer) {
10420        synchronized (this) {
10421            mProcessObservers.unregister(observer);
10422        }
10423    }
10424
10425    @Override
10426    public boolean convertFromTranslucent(IBinder token) {
10427        final long origId = Binder.clearCallingIdentity();
10428        try {
10429            synchronized (this) {
10430                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10431                if (r == null) {
10432                    return false;
10433                }
10434                final boolean translucentChanged = r.changeWindowTranslucency(true);
10435                if (translucentChanged) {
10436                    r.task.stack.releaseBackgroundResources();
10437                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10438                }
10439                mWindowManager.setAppFullscreen(token, true);
10440                return translucentChanged;
10441            }
10442        } finally {
10443            Binder.restoreCallingIdentity(origId);
10444        }
10445    }
10446
10447    @Override
10448    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10449        final long origId = Binder.clearCallingIdentity();
10450        try {
10451            synchronized (this) {
10452                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10453                if (r == null) {
10454                    return false;
10455                }
10456                int index = r.task.mActivities.lastIndexOf(r);
10457                if (index > 0) {
10458                    ActivityRecord under = r.task.mActivities.get(index - 1);
10459                    under.returningOptions = options;
10460                }
10461                final boolean translucentChanged = r.changeWindowTranslucency(false);
10462                if (translucentChanged) {
10463                    r.task.stack.convertToTranslucent(r);
10464                }
10465                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10466                mWindowManager.setAppFullscreen(token, false);
10467                return translucentChanged;
10468            }
10469        } finally {
10470            Binder.restoreCallingIdentity(origId);
10471        }
10472    }
10473
10474    @Override
10475    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10476        final long origId = Binder.clearCallingIdentity();
10477        try {
10478            synchronized (this) {
10479                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10480                if (r != null) {
10481                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10482                }
10483            }
10484            return false;
10485        } finally {
10486            Binder.restoreCallingIdentity(origId);
10487        }
10488    }
10489
10490    @Override
10491    public boolean isBackgroundVisibleBehind(IBinder token) {
10492        final long origId = Binder.clearCallingIdentity();
10493        try {
10494            synchronized (this) {
10495                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10496                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10497                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10498                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10499                return visible;
10500            }
10501        } finally {
10502            Binder.restoreCallingIdentity(origId);
10503        }
10504    }
10505
10506    @Override
10507    public ActivityOptions getActivityOptions(IBinder token) {
10508        final long origId = Binder.clearCallingIdentity();
10509        try {
10510            synchronized (this) {
10511                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10512                if (r != null) {
10513                    final ActivityOptions activityOptions = r.pendingOptions;
10514                    r.pendingOptions = null;
10515                    return activityOptions;
10516                }
10517                return null;
10518            }
10519        } finally {
10520            Binder.restoreCallingIdentity(origId);
10521        }
10522    }
10523
10524    @Override
10525    public void setImmersive(IBinder token, boolean immersive) {
10526        synchronized(this) {
10527            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10528            if (r == null) {
10529                throw new IllegalArgumentException();
10530            }
10531            r.immersive = immersive;
10532
10533            // update associated state if we're frontmost
10534            if (r == mFocusedActivity) {
10535                if (DEBUG_IMMERSIVE) {
10536                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10537                }
10538                applyUpdateLockStateLocked(r);
10539            }
10540        }
10541    }
10542
10543    @Override
10544    public boolean isImmersive(IBinder token) {
10545        synchronized (this) {
10546            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10547            if (r == null) {
10548                throw new IllegalArgumentException();
10549            }
10550            return r.immersive;
10551        }
10552    }
10553
10554    public boolean isTopActivityImmersive() {
10555        enforceNotIsolatedCaller("startActivity");
10556        synchronized (this) {
10557            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10558            return (r != null) ? r.immersive : false;
10559        }
10560    }
10561
10562    @Override
10563    public boolean isTopOfTask(IBinder token) {
10564        synchronized (this) {
10565            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10566            if (r == null) {
10567                throw new IllegalArgumentException();
10568            }
10569            return r.task.getTopActivity() == r;
10570        }
10571    }
10572
10573    public final void enterSafeMode() {
10574        synchronized(this) {
10575            // It only makes sense to do this before the system is ready
10576            // and started launching other packages.
10577            if (!mSystemReady) {
10578                try {
10579                    AppGlobals.getPackageManager().enterSafeMode();
10580                } catch (RemoteException e) {
10581                }
10582            }
10583
10584            mSafeMode = true;
10585        }
10586    }
10587
10588    public final void showSafeModeOverlay() {
10589        View v = LayoutInflater.from(mContext).inflate(
10590                com.android.internal.R.layout.safe_mode, null);
10591        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10592        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10593        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10594        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10595        lp.gravity = Gravity.BOTTOM | Gravity.START;
10596        lp.format = v.getBackground().getOpacity();
10597        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10598                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10599        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10600        ((WindowManager)mContext.getSystemService(
10601                Context.WINDOW_SERVICE)).addView(v, lp);
10602    }
10603
10604    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10605        if (!(sender instanceof PendingIntentRecord)) {
10606            return;
10607        }
10608        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10609        synchronized (stats) {
10610            if (mBatteryStatsService.isOnBattery()) {
10611                mBatteryStatsService.enforceCallingPermission();
10612                PendingIntentRecord rec = (PendingIntentRecord)sender;
10613                int MY_UID = Binder.getCallingUid();
10614                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10615                BatteryStatsImpl.Uid.Pkg pkg =
10616                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10617                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10618                pkg.incWakeupsLocked();
10619            }
10620        }
10621    }
10622
10623    public boolean killPids(int[] pids, String pReason, boolean secure) {
10624        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10625            throw new SecurityException("killPids only available to the system");
10626        }
10627        String reason = (pReason == null) ? "Unknown" : pReason;
10628        // XXX Note: don't acquire main activity lock here, because the window
10629        // manager calls in with its locks held.
10630
10631        boolean killed = false;
10632        synchronized (mPidsSelfLocked) {
10633            int[] types = new int[pids.length];
10634            int worstType = 0;
10635            for (int i=0; i<pids.length; i++) {
10636                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10637                if (proc != null) {
10638                    int type = proc.setAdj;
10639                    types[i] = type;
10640                    if (type > worstType) {
10641                        worstType = type;
10642                    }
10643                }
10644            }
10645
10646            // If the worst oom_adj is somewhere in the cached proc LRU range,
10647            // then constrain it so we will kill all cached procs.
10648            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10649                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10650                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10651            }
10652
10653            // If this is not a secure call, don't let it kill processes that
10654            // are important.
10655            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10656                worstType = ProcessList.SERVICE_ADJ;
10657            }
10658
10659            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10660            for (int i=0; i<pids.length; i++) {
10661                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10662                if (proc == null) {
10663                    continue;
10664                }
10665                int adj = proc.setAdj;
10666                if (adj >= worstType && !proc.killedByAm) {
10667                    proc.kill(reason, true);
10668                    killed = true;
10669                }
10670            }
10671        }
10672        return killed;
10673    }
10674
10675    @Override
10676    public void killUid(int uid, String reason) {
10677        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10678            throw new SecurityException("killUid only available to the system");
10679        }
10680        synchronized (this) {
10681            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10682                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10683                    reason != null ? reason : "kill uid");
10684        }
10685    }
10686
10687    @Override
10688    public boolean killProcessesBelowForeground(String reason) {
10689        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10690            throw new SecurityException("killProcessesBelowForeground() only available to system");
10691        }
10692
10693        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10694    }
10695
10696    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10697        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10698            throw new SecurityException("killProcessesBelowAdj() only available to system");
10699        }
10700
10701        boolean killed = false;
10702        synchronized (mPidsSelfLocked) {
10703            final int size = mPidsSelfLocked.size();
10704            for (int i = 0; i < size; i++) {
10705                final int pid = mPidsSelfLocked.keyAt(i);
10706                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10707                if (proc == null) continue;
10708
10709                final int adj = proc.setAdj;
10710                if (adj > belowAdj && !proc.killedByAm) {
10711                    proc.kill(reason, true);
10712                    killed = true;
10713                }
10714            }
10715        }
10716        return killed;
10717    }
10718
10719    @Override
10720    public void hang(final IBinder who, boolean allowRestart) {
10721        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10722                != PackageManager.PERMISSION_GRANTED) {
10723            throw new SecurityException("Requires permission "
10724                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10725        }
10726
10727        final IBinder.DeathRecipient death = new DeathRecipient() {
10728            @Override
10729            public void binderDied() {
10730                synchronized (this) {
10731                    notifyAll();
10732                }
10733            }
10734        };
10735
10736        try {
10737            who.linkToDeath(death, 0);
10738        } catch (RemoteException e) {
10739            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10740            return;
10741        }
10742
10743        synchronized (this) {
10744            Watchdog.getInstance().setAllowRestart(allowRestart);
10745            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10746            synchronized (death) {
10747                while (who.isBinderAlive()) {
10748                    try {
10749                        death.wait();
10750                    } catch (InterruptedException e) {
10751                    }
10752                }
10753            }
10754            Watchdog.getInstance().setAllowRestart(true);
10755        }
10756    }
10757
10758    @Override
10759    public void restart() {
10760        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10761                != PackageManager.PERMISSION_GRANTED) {
10762            throw new SecurityException("Requires permission "
10763                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10764        }
10765
10766        Log.i(TAG, "Sending shutdown broadcast...");
10767
10768        BroadcastReceiver br = new BroadcastReceiver() {
10769            @Override public void onReceive(Context context, Intent intent) {
10770                // Now the broadcast is done, finish up the low-level shutdown.
10771                Log.i(TAG, "Shutting down activity manager...");
10772                shutdown(10000);
10773                Log.i(TAG, "Shutdown complete, restarting!");
10774                Process.killProcess(Process.myPid());
10775                System.exit(10);
10776            }
10777        };
10778
10779        // First send the high-level shut down broadcast.
10780        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10781        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10782        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10783        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10784        mContext.sendOrderedBroadcastAsUser(intent,
10785                UserHandle.ALL, null, br, mHandler, 0, null, null);
10786        */
10787        br.onReceive(mContext, intent);
10788    }
10789
10790    private long getLowRamTimeSinceIdle(long now) {
10791        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10792    }
10793
10794    @Override
10795    public void performIdleMaintenance() {
10796        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10797                != PackageManager.PERMISSION_GRANTED) {
10798            throw new SecurityException("Requires permission "
10799                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10800        }
10801
10802        synchronized (this) {
10803            final long now = SystemClock.uptimeMillis();
10804            final long timeSinceLastIdle = now - mLastIdleTime;
10805            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10806            mLastIdleTime = now;
10807            mLowRamTimeSinceLastIdle = 0;
10808            if (mLowRamStartTime != 0) {
10809                mLowRamStartTime = now;
10810            }
10811
10812            StringBuilder sb = new StringBuilder(128);
10813            sb.append("Idle maintenance over ");
10814            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10815            sb.append(" low RAM for ");
10816            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10817            Slog.i(TAG, sb.toString());
10818
10819            // If at least 1/3 of our time since the last idle period has been spent
10820            // with RAM low, then we want to kill processes.
10821            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10822
10823            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10824                ProcessRecord proc = mLruProcesses.get(i);
10825                if (proc.notCachedSinceIdle) {
10826                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10827                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10828                        if (doKilling && proc.initialIdlePss != 0
10829                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10830                            proc.kill("idle maint (pss " + proc.lastPss
10831                                    + " from " + proc.initialIdlePss + ")", true);
10832                        }
10833                    }
10834                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10835                    proc.notCachedSinceIdle = true;
10836                    proc.initialIdlePss = 0;
10837                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10838                            isSleeping(), now);
10839                }
10840            }
10841
10842            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10843            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10844        }
10845    }
10846
10847    private void retrieveSettings() {
10848        final ContentResolver resolver = mContext.getContentResolver();
10849        String debugApp = Settings.Global.getString(
10850            resolver, Settings.Global.DEBUG_APP);
10851        boolean waitForDebugger = Settings.Global.getInt(
10852            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10853        boolean alwaysFinishActivities = Settings.Global.getInt(
10854            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10855        boolean forceRtl = Settings.Global.getInt(
10856                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10857        // Transfer any global setting for forcing RTL layout, into a System Property
10858        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10859
10860        Configuration configuration = new Configuration();
10861        Settings.System.getConfiguration(resolver, configuration);
10862        if (forceRtl) {
10863            // This will take care of setting the correct layout direction flags
10864            configuration.setLayoutDirection(configuration.locale);
10865        }
10866
10867        synchronized (this) {
10868            mDebugApp = mOrigDebugApp = debugApp;
10869            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10870            mAlwaysFinishActivities = alwaysFinishActivities;
10871            // This happens before any activities are started, so we can
10872            // change mConfiguration in-place.
10873            updateConfigurationLocked(configuration, null, false, true);
10874            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10875        }
10876    }
10877
10878    /** Loads resources after the current configuration has been set. */
10879    private void loadResourcesOnSystemReady() {
10880        final Resources res = mContext.getResources();
10881        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10882        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10883        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10884    }
10885
10886    public boolean testIsSystemReady() {
10887        // no need to synchronize(this) just to read & return the value
10888        return mSystemReady;
10889    }
10890
10891    private static File getCalledPreBootReceiversFile() {
10892        File dataDir = Environment.getDataDirectory();
10893        File systemDir = new File(dataDir, "system");
10894        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10895        return fname;
10896    }
10897
10898    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10899        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10900        File file = getCalledPreBootReceiversFile();
10901        FileInputStream fis = null;
10902        try {
10903            fis = new FileInputStream(file);
10904            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10905            int fvers = dis.readInt();
10906            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10907                String vers = dis.readUTF();
10908                String codename = dis.readUTF();
10909                String build = dis.readUTF();
10910                if (android.os.Build.VERSION.RELEASE.equals(vers)
10911                        && android.os.Build.VERSION.CODENAME.equals(codename)
10912                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10913                    int num = dis.readInt();
10914                    while (num > 0) {
10915                        num--;
10916                        String pkg = dis.readUTF();
10917                        String cls = dis.readUTF();
10918                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10919                    }
10920                }
10921            }
10922        } catch (FileNotFoundException e) {
10923        } catch (IOException e) {
10924            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10925        } finally {
10926            if (fis != null) {
10927                try {
10928                    fis.close();
10929                } catch (IOException e) {
10930                }
10931            }
10932        }
10933        return lastDoneReceivers;
10934    }
10935
10936    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10937        File file = getCalledPreBootReceiversFile();
10938        FileOutputStream fos = null;
10939        DataOutputStream dos = null;
10940        try {
10941            fos = new FileOutputStream(file);
10942            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10943            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10944            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10945            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10946            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10947            dos.writeInt(list.size());
10948            for (int i=0; i<list.size(); i++) {
10949                dos.writeUTF(list.get(i).getPackageName());
10950                dos.writeUTF(list.get(i).getClassName());
10951            }
10952        } catch (IOException e) {
10953            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10954            file.delete();
10955        } finally {
10956            FileUtils.sync(fos);
10957            if (dos != null) {
10958                try {
10959                    dos.close();
10960                } catch (IOException e) {
10961                    // TODO Auto-generated catch block
10962                    e.printStackTrace();
10963                }
10964            }
10965        }
10966    }
10967
10968    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10969            ArrayList<ComponentName> doneReceivers, int userId) {
10970        boolean waitingUpdate = false;
10971        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10972        List<ResolveInfo> ris = null;
10973        try {
10974            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10975                    intent, null, 0, userId);
10976        } catch (RemoteException e) {
10977        }
10978        if (ris != null) {
10979            for (int i=ris.size()-1; i>=0; i--) {
10980                if ((ris.get(i).activityInfo.applicationInfo.flags
10981                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10982                    ris.remove(i);
10983                }
10984            }
10985            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10986
10987            // For User 0, load the version number. When delivering to a new user, deliver
10988            // to all receivers.
10989            if (userId == UserHandle.USER_OWNER) {
10990                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10991                for (int i=0; i<ris.size(); i++) {
10992                    ActivityInfo ai = ris.get(i).activityInfo;
10993                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10994                    if (lastDoneReceivers.contains(comp)) {
10995                        // We already did the pre boot receiver for this app with the current
10996                        // platform version, so don't do it again...
10997                        ris.remove(i);
10998                        i--;
10999                        // ...however, do keep it as one that has been done, so we don't
11000                        // forget about it when rewriting the file of last done receivers.
11001                        doneReceivers.add(comp);
11002                    }
11003                }
11004            }
11005
11006            // If primary user, send broadcast to all available users, else just to userId
11007            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11008                    : new int[] { userId };
11009            for (int i = 0; i < ris.size(); i++) {
11010                ActivityInfo ai = ris.get(i).activityInfo;
11011                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11012                doneReceivers.add(comp);
11013                intent.setComponent(comp);
11014                for (int j=0; j<users.length; j++) {
11015                    IIntentReceiver finisher = null;
11016                    // On last receiver and user, set up a completion callback
11017                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11018                        finisher = new IIntentReceiver.Stub() {
11019                            public void performReceive(Intent intent, int resultCode,
11020                                    String data, Bundle extras, boolean ordered,
11021                                    boolean sticky, int sendingUser) {
11022                                // The raw IIntentReceiver interface is called
11023                                // with the AM lock held, so redispatch to
11024                                // execute our code without the lock.
11025                                mHandler.post(onFinishCallback);
11026                            }
11027                        };
11028                    }
11029                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11030                            + " for user " + users[j]);
11031                    broadcastIntentLocked(null, null, intent, null, finisher,
11032                            0, null, null, null, AppOpsManager.OP_NONE,
11033                            true, false, MY_PID, Process.SYSTEM_UID,
11034                            users[j]);
11035                    if (finisher != null) {
11036                        waitingUpdate = true;
11037                    }
11038                }
11039            }
11040        }
11041
11042        return waitingUpdate;
11043    }
11044
11045    public void systemReady(final Runnable goingCallback) {
11046        synchronized(this) {
11047            if (mSystemReady) {
11048                // If we're done calling all the receivers, run the next "boot phase" passed in
11049                // by the SystemServer
11050                if (goingCallback != null) {
11051                    goingCallback.run();
11052                }
11053                return;
11054            }
11055
11056            // Make sure we have the current profile info, since it is needed for
11057            // security checks.
11058            updateCurrentProfileIdsLocked();
11059
11060            if (mRecentTasks == null) {
11061                mRecentTasks = mTaskPersister.restoreTasksLocked();
11062                if (!mRecentTasks.isEmpty()) {
11063                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11064                }
11065                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11066                mTaskPersister.startPersisting();
11067            }
11068
11069            // Check to see if there are any update receivers to run.
11070            if (!mDidUpdate) {
11071                if (mWaitingUpdate) {
11072                    return;
11073                }
11074                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11075                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11076                    public void run() {
11077                        synchronized (ActivityManagerService.this) {
11078                            mDidUpdate = true;
11079                        }
11080                        writeLastDonePreBootReceivers(doneReceivers);
11081                        showBootMessage(mContext.getText(
11082                                R.string.android_upgrading_complete),
11083                                false);
11084                        systemReady(goingCallback);
11085                    }
11086                }, doneReceivers, UserHandle.USER_OWNER);
11087
11088                if (mWaitingUpdate) {
11089                    return;
11090                }
11091                mDidUpdate = true;
11092            }
11093
11094            mAppOpsService.systemReady();
11095            mSystemReady = true;
11096        }
11097
11098        ArrayList<ProcessRecord> procsToKill = null;
11099        synchronized(mPidsSelfLocked) {
11100            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11101                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11102                if (!isAllowedWhileBooting(proc.info)){
11103                    if (procsToKill == null) {
11104                        procsToKill = new ArrayList<ProcessRecord>();
11105                    }
11106                    procsToKill.add(proc);
11107                }
11108            }
11109        }
11110
11111        synchronized(this) {
11112            if (procsToKill != null) {
11113                for (int i=procsToKill.size()-1; i>=0; i--) {
11114                    ProcessRecord proc = procsToKill.get(i);
11115                    Slog.i(TAG, "Removing system update proc: " + proc);
11116                    removeProcessLocked(proc, true, false, "system update done");
11117                }
11118            }
11119
11120            // Now that we have cleaned up any update processes, we
11121            // are ready to start launching real processes and know that
11122            // we won't trample on them any more.
11123            mProcessesReady = true;
11124        }
11125
11126        Slog.i(TAG, "System now ready");
11127        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11128            SystemClock.uptimeMillis());
11129
11130        synchronized(this) {
11131            // Make sure we have no pre-ready processes sitting around.
11132
11133            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11134                ResolveInfo ri = mContext.getPackageManager()
11135                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11136                                STOCK_PM_FLAGS);
11137                CharSequence errorMsg = null;
11138                if (ri != null) {
11139                    ActivityInfo ai = ri.activityInfo;
11140                    ApplicationInfo app = ai.applicationInfo;
11141                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11142                        mTopAction = Intent.ACTION_FACTORY_TEST;
11143                        mTopData = null;
11144                        mTopComponent = new ComponentName(app.packageName,
11145                                ai.name);
11146                    } else {
11147                        errorMsg = mContext.getResources().getText(
11148                                com.android.internal.R.string.factorytest_not_system);
11149                    }
11150                } else {
11151                    errorMsg = mContext.getResources().getText(
11152                            com.android.internal.R.string.factorytest_no_action);
11153                }
11154                if (errorMsg != null) {
11155                    mTopAction = null;
11156                    mTopData = null;
11157                    mTopComponent = null;
11158                    Message msg = Message.obtain();
11159                    msg.what = SHOW_FACTORY_ERROR_MSG;
11160                    msg.getData().putCharSequence("msg", errorMsg);
11161                    mHandler.sendMessage(msg);
11162                }
11163            }
11164        }
11165
11166        retrieveSettings();
11167        loadResourcesOnSystemReady();
11168
11169        synchronized (this) {
11170            readGrantedUriPermissionsLocked();
11171        }
11172
11173        if (goingCallback != null) goingCallback.run();
11174
11175        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11176                Integer.toString(mCurrentUserId), mCurrentUserId);
11177        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11178                Integer.toString(mCurrentUserId), mCurrentUserId);
11179        mSystemServiceManager.startUser(mCurrentUserId);
11180
11181        synchronized (this) {
11182            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11183                try {
11184                    List apps = AppGlobals.getPackageManager().
11185                        getPersistentApplications(STOCK_PM_FLAGS);
11186                    if (apps != null) {
11187                        int N = apps.size();
11188                        int i;
11189                        for (i=0; i<N; i++) {
11190                            ApplicationInfo info
11191                                = (ApplicationInfo)apps.get(i);
11192                            if (info != null &&
11193                                    !info.packageName.equals("android")) {
11194                                addAppLocked(info, false, null /* ABI override */);
11195                            }
11196                        }
11197                    }
11198                } catch (RemoteException ex) {
11199                    // pm is in same process, this will never happen.
11200                }
11201            }
11202
11203            // Start up initial activity.
11204            mBooting = true;
11205            startHomeActivityLocked(mCurrentUserId);
11206
11207            try {
11208                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11209                    Message msg = Message.obtain();
11210                    msg.what = SHOW_UID_ERROR_MSG;
11211                    mHandler.sendMessage(msg);
11212                }
11213            } catch (RemoteException e) {
11214            }
11215
11216            long ident = Binder.clearCallingIdentity();
11217            try {
11218                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11219                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11220                        | Intent.FLAG_RECEIVER_FOREGROUND);
11221                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11222                broadcastIntentLocked(null, null, intent,
11223                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11224                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11225                intent = new Intent(Intent.ACTION_USER_STARTING);
11226                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11227                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11228                broadcastIntentLocked(null, null, intent,
11229                        null, new IIntentReceiver.Stub() {
11230                            @Override
11231                            public void performReceive(Intent intent, int resultCode, String data,
11232                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11233                                    throws RemoteException {
11234                            }
11235                        }, 0, null, null,
11236                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11237                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11238            } catch (Throwable t) {
11239                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11240            } finally {
11241                Binder.restoreCallingIdentity(ident);
11242            }
11243            mStackSupervisor.resumeTopActivitiesLocked();
11244            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11245        }
11246    }
11247
11248    private boolean makeAppCrashingLocked(ProcessRecord app,
11249            String shortMsg, String longMsg, String stackTrace) {
11250        app.crashing = true;
11251        app.crashingReport = generateProcessError(app,
11252                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11253        startAppProblemLocked(app);
11254        app.stopFreezingAllLocked();
11255        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11256    }
11257
11258    private void makeAppNotRespondingLocked(ProcessRecord app,
11259            String activity, String shortMsg, String longMsg) {
11260        app.notResponding = true;
11261        app.notRespondingReport = generateProcessError(app,
11262                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11263                activity, shortMsg, longMsg, null);
11264        startAppProblemLocked(app);
11265        app.stopFreezingAllLocked();
11266    }
11267
11268    /**
11269     * Generate a process error record, suitable for attachment to a ProcessRecord.
11270     *
11271     * @param app The ProcessRecord in which the error occurred.
11272     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11273     *                      ActivityManager.AppErrorStateInfo
11274     * @param activity The activity associated with the crash, if known.
11275     * @param shortMsg Short message describing the crash.
11276     * @param longMsg Long message describing the crash.
11277     * @param stackTrace Full crash stack trace, may be null.
11278     *
11279     * @return Returns a fully-formed AppErrorStateInfo record.
11280     */
11281    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11282            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11283        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11284
11285        report.condition = condition;
11286        report.processName = app.processName;
11287        report.pid = app.pid;
11288        report.uid = app.info.uid;
11289        report.tag = activity;
11290        report.shortMsg = shortMsg;
11291        report.longMsg = longMsg;
11292        report.stackTrace = stackTrace;
11293
11294        return report;
11295    }
11296
11297    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11298        synchronized (this) {
11299            app.crashing = false;
11300            app.crashingReport = null;
11301            app.notResponding = false;
11302            app.notRespondingReport = null;
11303            if (app.anrDialog == fromDialog) {
11304                app.anrDialog = null;
11305            }
11306            if (app.waitDialog == fromDialog) {
11307                app.waitDialog = null;
11308            }
11309            if (app.pid > 0 && app.pid != MY_PID) {
11310                handleAppCrashLocked(app, null, null, null);
11311                app.kill("user request after error", true);
11312            }
11313        }
11314    }
11315
11316    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11317            String stackTrace) {
11318        long now = SystemClock.uptimeMillis();
11319
11320        Long crashTime;
11321        if (!app.isolated) {
11322            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11323        } else {
11324            crashTime = null;
11325        }
11326        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11327            // This process loses!
11328            Slog.w(TAG, "Process " + app.info.processName
11329                    + " has crashed too many times: killing!");
11330            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11331                    app.userId, app.info.processName, app.uid);
11332            mStackSupervisor.handleAppCrashLocked(app);
11333            if (!app.persistent) {
11334                // We don't want to start this process again until the user
11335                // explicitly does so...  but for persistent process, we really
11336                // need to keep it running.  If a persistent process is actually
11337                // repeatedly crashing, then badness for everyone.
11338                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11339                        app.info.processName);
11340                if (!app.isolated) {
11341                    // XXX We don't have a way to mark isolated processes
11342                    // as bad, since they don't have a peristent identity.
11343                    mBadProcesses.put(app.info.processName, app.uid,
11344                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11345                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11346                }
11347                app.bad = true;
11348                app.removed = true;
11349                // Don't let services in this process be restarted and potentially
11350                // annoy the user repeatedly.  Unless it is persistent, since those
11351                // processes run critical code.
11352                removeProcessLocked(app, false, false, "crash");
11353                mStackSupervisor.resumeTopActivitiesLocked();
11354                return false;
11355            }
11356            mStackSupervisor.resumeTopActivitiesLocked();
11357        } else {
11358            mStackSupervisor.finishTopRunningActivityLocked(app);
11359        }
11360
11361        // Bump up the crash count of any services currently running in the proc.
11362        for (int i=app.services.size()-1; i>=0; i--) {
11363            // Any services running in the application need to be placed
11364            // back in the pending list.
11365            ServiceRecord sr = app.services.valueAt(i);
11366            sr.crashCount++;
11367        }
11368
11369        // If the crashing process is what we consider to be the "home process" and it has been
11370        // replaced by a third-party app, clear the package preferred activities from packages
11371        // with a home activity running in the process to prevent a repeatedly crashing app
11372        // from blocking the user to manually clear the list.
11373        final ArrayList<ActivityRecord> activities = app.activities;
11374        if (app == mHomeProcess && activities.size() > 0
11375                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11376            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11377                final ActivityRecord r = activities.get(activityNdx);
11378                if (r.isHomeActivity()) {
11379                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11380                    try {
11381                        ActivityThread.getPackageManager()
11382                                .clearPackagePreferredActivities(r.packageName);
11383                    } catch (RemoteException c) {
11384                        // pm is in same process, this will never happen.
11385                    }
11386                }
11387            }
11388        }
11389
11390        if (!app.isolated) {
11391            // XXX Can't keep track of crash times for isolated processes,
11392            // because they don't have a perisistent identity.
11393            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11394        }
11395
11396        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11397        return true;
11398    }
11399
11400    void startAppProblemLocked(ProcessRecord app) {
11401        // If this app is not running under the current user, then we
11402        // can't give it a report button because that would require
11403        // launching the report UI under a different user.
11404        app.errorReportReceiver = null;
11405
11406        for (int userId : mCurrentProfileIds) {
11407            if (app.userId == userId) {
11408                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11409                        mContext, app.info.packageName, app.info.flags);
11410            }
11411        }
11412        skipCurrentReceiverLocked(app);
11413    }
11414
11415    void skipCurrentReceiverLocked(ProcessRecord app) {
11416        for (BroadcastQueue queue : mBroadcastQueues) {
11417            queue.skipCurrentReceiverLocked(app);
11418        }
11419    }
11420
11421    /**
11422     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11423     * The application process will exit immediately after this call returns.
11424     * @param app object of the crashing app, null for the system server
11425     * @param crashInfo describing the exception
11426     */
11427    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11428        ProcessRecord r = findAppProcess(app, "Crash");
11429        final String processName = app == null ? "system_server"
11430                : (r == null ? "unknown" : r.processName);
11431
11432        handleApplicationCrashInner("crash", r, processName, crashInfo);
11433    }
11434
11435    /* Native crash reporting uses this inner version because it needs to be somewhat
11436     * decoupled from the AM-managed cleanup lifecycle
11437     */
11438    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11439            ApplicationErrorReport.CrashInfo crashInfo) {
11440        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11441                UserHandle.getUserId(Binder.getCallingUid()), processName,
11442                r == null ? -1 : r.info.flags,
11443                crashInfo.exceptionClassName,
11444                crashInfo.exceptionMessage,
11445                crashInfo.throwFileName,
11446                crashInfo.throwLineNumber);
11447
11448        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11449
11450        crashApplication(r, crashInfo);
11451    }
11452
11453    public void handleApplicationStrictModeViolation(
11454            IBinder app,
11455            int violationMask,
11456            StrictMode.ViolationInfo info) {
11457        ProcessRecord r = findAppProcess(app, "StrictMode");
11458        if (r == null) {
11459            return;
11460        }
11461
11462        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11463            Integer stackFingerprint = info.hashCode();
11464            boolean logIt = true;
11465            synchronized (mAlreadyLoggedViolatedStacks) {
11466                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11467                    logIt = false;
11468                    // TODO: sub-sample into EventLog for these, with
11469                    // the info.durationMillis?  Then we'd get
11470                    // the relative pain numbers, without logging all
11471                    // the stack traces repeatedly.  We'd want to do
11472                    // likewise in the client code, which also does
11473                    // dup suppression, before the Binder call.
11474                } else {
11475                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11476                        mAlreadyLoggedViolatedStacks.clear();
11477                    }
11478                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11479                }
11480            }
11481            if (logIt) {
11482                logStrictModeViolationToDropBox(r, info);
11483            }
11484        }
11485
11486        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11487            AppErrorResult result = new AppErrorResult();
11488            synchronized (this) {
11489                final long origId = Binder.clearCallingIdentity();
11490
11491                Message msg = Message.obtain();
11492                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11493                HashMap<String, Object> data = new HashMap<String, Object>();
11494                data.put("result", result);
11495                data.put("app", r);
11496                data.put("violationMask", violationMask);
11497                data.put("info", info);
11498                msg.obj = data;
11499                mHandler.sendMessage(msg);
11500
11501                Binder.restoreCallingIdentity(origId);
11502            }
11503            int res = result.get();
11504            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11505        }
11506    }
11507
11508    // Depending on the policy in effect, there could be a bunch of
11509    // these in quick succession so we try to batch these together to
11510    // minimize disk writes, number of dropbox entries, and maximize
11511    // compression, by having more fewer, larger records.
11512    private void logStrictModeViolationToDropBox(
11513            ProcessRecord process,
11514            StrictMode.ViolationInfo info) {
11515        if (info == null) {
11516            return;
11517        }
11518        final boolean isSystemApp = process == null ||
11519                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11520                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11521        final String processName = process == null ? "unknown" : process.processName;
11522        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11523        final DropBoxManager dbox = (DropBoxManager)
11524                mContext.getSystemService(Context.DROPBOX_SERVICE);
11525
11526        // Exit early if the dropbox isn't configured to accept this report type.
11527        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11528
11529        boolean bufferWasEmpty;
11530        boolean needsFlush;
11531        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11532        synchronized (sb) {
11533            bufferWasEmpty = sb.length() == 0;
11534            appendDropBoxProcessHeaders(process, processName, sb);
11535            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11536            sb.append("System-App: ").append(isSystemApp).append("\n");
11537            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11538            if (info.violationNumThisLoop != 0) {
11539                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11540            }
11541            if (info.numAnimationsRunning != 0) {
11542                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11543            }
11544            if (info.broadcastIntentAction != null) {
11545                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11546            }
11547            if (info.durationMillis != -1) {
11548                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11549            }
11550            if (info.numInstances != -1) {
11551                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11552            }
11553            if (info.tags != null) {
11554                for (String tag : info.tags) {
11555                    sb.append("Span-Tag: ").append(tag).append("\n");
11556                }
11557            }
11558            sb.append("\n");
11559            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11560                sb.append(info.crashInfo.stackTrace);
11561            }
11562            sb.append("\n");
11563
11564            // Only buffer up to ~64k.  Various logging bits truncate
11565            // things at 128k.
11566            needsFlush = (sb.length() > 64 * 1024);
11567        }
11568
11569        // Flush immediately if the buffer's grown too large, or this
11570        // is a non-system app.  Non-system apps are isolated with a
11571        // different tag & policy and not batched.
11572        //
11573        // Batching is useful during internal testing with
11574        // StrictMode settings turned up high.  Without batching,
11575        // thousands of separate files could be created on boot.
11576        if (!isSystemApp || needsFlush) {
11577            new Thread("Error dump: " + dropboxTag) {
11578                @Override
11579                public void run() {
11580                    String report;
11581                    synchronized (sb) {
11582                        report = sb.toString();
11583                        sb.delete(0, sb.length());
11584                        sb.trimToSize();
11585                    }
11586                    if (report.length() != 0) {
11587                        dbox.addText(dropboxTag, report);
11588                    }
11589                }
11590            }.start();
11591            return;
11592        }
11593
11594        // System app batching:
11595        if (!bufferWasEmpty) {
11596            // An existing dropbox-writing thread is outstanding, so
11597            // we don't need to start it up.  The existing thread will
11598            // catch the buffer appends we just did.
11599            return;
11600        }
11601
11602        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11603        // (After this point, we shouldn't access AMS internal data structures.)
11604        new Thread("Error dump: " + dropboxTag) {
11605            @Override
11606            public void run() {
11607                // 5 second sleep to let stacks arrive and be batched together
11608                try {
11609                    Thread.sleep(5000);  // 5 seconds
11610                } catch (InterruptedException e) {}
11611
11612                String errorReport;
11613                synchronized (mStrictModeBuffer) {
11614                    errorReport = mStrictModeBuffer.toString();
11615                    if (errorReport.length() == 0) {
11616                        return;
11617                    }
11618                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11619                    mStrictModeBuffer.trimToSize();
11620                }
11621                dbox.addText(dropboxTag, errorReport);
11622            }
11623        }.start();
11624    }
11625
11626    /**
11627     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11628     * @param app object of the crashing app, null for the system server
11629     * @param tag reported by the caller
11630     * @param system whether this wtf is coming from the system
11631     * @param crashInfo describing the context of the error
11632     * @return true if the process should exit immediately (WTF is fatal)
11633     */
11634    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11635            final ApplicationErrorReport.CrashInfo crashInfo) {
11636        final int callingUid = Binder.getCallingUid();
11637        final int callingPid = Binder.getCallingPid();
11638
11639        if (system) {
11640            // If this is coming from the system, we could very well have low-level
11641            // system locks held, so we want to do this all asynchronously.  And we
11642            // never want this to become fatal, so there is that too.
11643            mHandler.post(new Runnable() {
11644                @Override public void run() {
11645                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11646                }
11647            });
11648            return false;
11649        }
11650
11651        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11652                crashInfo);
11653
11654        if (r != null && r.pid != Process.myPid() &&
11655                Settings.Global.getInt(mContext.getContentResolver(),
11656                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11657            crashApplication(r, crashInfo);
11658            return true;
11659        } else {
11660            return false;
11661        }
11662    }
11663
11664    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11665            final ApplicationErrorReport.CrashInfo crashInfo) {
11666        final ProcessRecord r = findAppProcess(app, "WTF");
11667        final String processName = app == null ? "system_server"
11668                : (r == null ? "unknown" : r.processName);
11669
11670        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11671                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11672
11673        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11674
11675        return r;
11676    }
11677
11678    /**
11679     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11680     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11681     */
11682    private ProcessRecord findAppProcess(IBinder app, String reason) {
11683        if (app == null) {
11684            return null;
11685        }
11686
11687        synchronized (this) {
11688            final int NP = mProcessNames.getMap().size();
11689            for (int ip=0; ip<NP; ip++) {
11690                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11691                final int NA = apps.size();
11692                for (int ia=0; ia<NA; ia++) {
11693                    ProcessRecord p = apps.valueAt(ia);
11694                    if (p.thread != null && p.thread.asBinder() == app) {
11695                        return p;
11696                    }
11697                }
11698            }
11699
11700            Slog.w(TAG, "Can't find mystery application for " + reason
11701                    + " from pid=" + Binder.getCallingPid()
11702                    + " uid=" + Binder.getCallingUid() + ": " + app);
11703            return null;
11704        }
11705    }
11706
11707    /**
11708     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11709     * to append various headers to the dropbox log text.
11710     */
11711    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11712            StringBuilder sb) {
11713        // Watchdog thread ends up invoking this function (with
11714        // a null ProcessRecord) to add the stack file to dropbox.
11715        // Do not acquire a lock on this (am) in such cases, as it
11716        // could cause a potential deadlock, if and when watchdog
11717        // is invoked due to unavailability of lock on am and it
11718        // would prevent watchdog from killing system_server.
11719        if (process == null) {
11720            sb.append("Process: ").append(processName).append("\n");
11721            return;
11722        }
11723        // Note: ProcessRecord 'process' is guarded by the service
11724        // instance.  (notably process.pkgList, which could otherwise change
11725        // concurrently during execution of this method)
11726        synchronized (this) {
11727            sb.append("Process: ").append(processName).append("\n");
11728            int flags = process.info.flags;
11729            IPackageManager pm = AppGlobals.getPackageManager();
11730            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11731            for (int ip=0; ip<process.pkgList.size(); ip++) {
11732                String pkg = process.pkgList.keyAt(ip);
11733                sb.append("Package: ").append(pkg);
11734                try {
11735                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11736                    if (pi != null) {
11737                        sb.append(" v").append(pi.versionCode);
11738                        if (pi.versionName != null) {
11739                            sb.append(" (").append(pi.versionName).append(")");
11740                        }
11741                    }
11742                } catch (RemoteException e) {
11743                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11744                }
11745                sb.append("\n");
11746            }
11747        }
11748    }
11749
11750    private static String processClass(ProcessRecord process) {
11751        if (process == null || process.pid == MY_PID) {
11752            return "system_server";
11753        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11754            return "system_app";
11755        } else {
11756            return "data_app";
11757        }
11758    }
11759
11760    /**
11761     * Write a description of an error (crash, WTF, ANR) to the drop box.
11762     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11763     * @param process which caused the error, null means the system server
11764     * @param activity which triggered the error, null if unknown
11765     * @param parent activity related to the error, null if unknown
11766     * @param subject line related to the error, null if absent
11767     * @param report in long form describing the error, null if absent
11768     * @param logFile to include in the report, null if none
11769     * @param crashInfo giving an application stack trace, null if absent
11770     */
11771    public void addErrorToDropBox(String eventType,
11772            ProcessRecord process, String processName, ActivityRecord activity,
11773            ActivityRecord parent, String subject,
11774            final String report, final File logFile,
11775            final ApplicationErrorReport.CrashInfo crashInfo) {
11776        // NOTE -- this must never acquire the ActivityManagerService lock,
11777        // otherwise the watchdog may be prevented from resetting the system.
11778
11779        final String dropboxTag = processClass(process) + "_" + eventType;
11780        final DropBoxManager dbox = (DropBoxManager)
11781                mContext.getSystemService(Context.DROPBOX_SERVICE);
11782
11783        // Exit early if the dropbox isn't configured to accept this report type.
11784        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11785
11786        final StringBuilder sb = new StringBuilder(1024);
11787        appendDropBoxProcessHeaders(process, processName, sb);
11788        if (activity != null) {
11789            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11790        }
11791        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11792            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11793        }
11794        if (parent != null && parent != activity) {
11795            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11796        }
11797        if (subject != null) {
11798            sb.append("Subject: ").append(subject).append("\n");
11799        }
11800        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11801        if (Debug.isDebuggerConnected()) {
11802            sb.append("Debugger: Connected\n");
11803        }
11804        sb.append("\n");
11805
11806        // Do the rest in a worker thread to avoid blocking the caller on I/O
11807        // (After this point, we shouldn't access AMS internal data structures.)
11808        Thread worker = new Thread("Error dump: " + dropboxTag) {
11809            @Override
11810            public void run() {
11811                if (report != null) {
11812                    sb.append(report);
11813                }
11814                if (logFile != null) {
11815                    try {
11816                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11817                                    "\n\n[[TRUNCATED]]"));
11818                    } catch (IOException e) {
11819                        Slog.e(TAG, "Error reading " + logFile, e);
11820                    }
11821                }
11822                if (crashInfo != null && crashInfo.stackTrace != null) {
11823                    sb.append(crashInfo.stackTrace);
11824                }
11825
11826                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11827                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11828                if (lines > 0) {
11829                    sb.append("\n");
11830
11831                    // Merge several logcat streams, and take the last N lines
11832                    InputStreamReader input = null;
11833                    try {
11834                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11835                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11836                                "-b", "crash",
11837                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11838
11839                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11840                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11841                        input = new InputStreamReader(logcat.getInputStream());
11842
11843                        int num;
11844                        char[] buf = new char[8192];
11845                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11846                    } catch (IOException e) {
11847                        Slog.e(TAG, "Error running logcat", e);
11848                    } finally {
11849                        if (input != null) try { input.close(); } catch (IOException e) {}
11850                    }
11851                }
11852
11853                dbox.addText(dropboxTag, sb.toString());
11854            }
11855        };
11856
11857        if (process == null) {
11858            // If process is null, we are being called from some internal code
11859            // and may be about to die -- run this synchronously.
11860            worker.run();
11861        } else {
11862            worker.start();
11863        }
11864    }
11865
11866    /**
11867     * Bring up the "unexpected error" dialog box for a crashing app.
11868     * Deal with edge cases (intercepts from instrumented applications,
11869     * ActivityController, error intent receivers, that sort of thing).
11870     * @param r the application crashing
11871     * @param crashInfo describing the failure
11872     */
11873    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11874        long timeMillis = System.currentTimeMillis();
11875        String shortMsg = crashInfo.exceptionClassName;
11876        String longMsg = crashInfo.exceptionMessage;
11877        String stackTrace = crashInfo.stackTrace;
11878        if (shortMsg != null && longMsg != null) {
11879            longMsg = shortMsg + ": " + longMsg;
11880        } else if (shortMsg != null) {
11881            longMsg = shortMsg;
11882        }
11883
11884        AppErrorResult result = new AppErrorResult();
11885        synchronized (this) {
11886            if (mController != null) {
11887                try {
11888                    String name = r != null ? r.processName : null;
11889                    int pid = r != null ? r.pid : Binder.getCallingPid();
11890                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11891                    if (!mController.appCrashed(name, pid,
11892                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11893                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11894                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11895                            Slog.w(TAG, "Skip killing native crashed app " + name
11896                                    + "(" + pid + ") during testing");
11897                        } else {
11898                            Slog.w(TAG, "Force-killing crashed app " + name
11899                                    + " at watcher's request");
11900                            if (r != null) {
11901                                r.kill("crash", true);
11902                            } else {
11903                                // Huh.
11904                                Process.killProcess(pid);
11905                                Process.killProcessGroup(uid, pid);
11906                            }
11907                        }
11908                        return;
11909                    }
11910                } catch (RemoteException e) {
11911                    mController = null;
11912                    Watchdog.getInstance().setActivityController(null);
11913                }
11914            }
11915
11916            final long origId = Binder.clearCallingIdentity();
11917
11918            // If this process is running instrumentation, finish it.
11919            if (r != null && r.instrumentationClass != null) {
11920                Slog.w(TAG, "Error in app " + r.processName
11921                      + " running instrumentation " + r.instrumentationClass + ":");
11922                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11923                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11924                Bundle info = new Bundle();
11925                info.putString("shortMsg", shortMsg);
11926                info.putString("longMsg", longMsg);
11927                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11928                Binder.restoreCallingIdentity(origId);
11929                return;
11930            }
11931
11932            // If we can't identify the process or it's already exceeded its crash quota,
11933            // quit right away without showing a crash dialog.
11934            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11935                Binder.restoreCallingIdentity(origId);
11936                return;
11937            }
11938
11939            Message msg = Message.obtain();
11940            msg.what = SHOW_ERROR_MSG;
11941            HashMap data = new HashMap();
11942            data.put("result", result);
11943            data.put("app", r);
11944            msg.obj = data;
11945            mHandler.sendMessage(msg);
11946
11947            Binder.restoreCallingIdentity(origId);
11948        }
11949
11950        int res = result.get();
11951
11952        Intent appErrorIntent = null;
11953        synchronized (this) {
11954            if (r != null && !r.isolated) {
11955                // XXX Can't keep track of crash time for isolated processes,
11956                // since they don't have a persistent identity.
11957                mProcessCrashTimes.put(r.info.processName, r.uid,
11958                        SystemClock.uptimeMillis());
11959            }
11960            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11961                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11962            }
11963        }
11964
11965        if (appErrorIntent != null) {
11966            try {
11967                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11968            } catch (ActivityNotFoundException e) {
11969                Slog.w(TAG, "bug report receiver dissappeared", e);
11970            }
11971        }
11972    }
11973
11974    Intent createAppErrorIntentLocked(ProcessRecord r,
11975            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11976        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11977        if (report == null) {
11978            return null;
11979        }
11980        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11981        result.setComponent(r.errorReportReceiver);
11982        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11983        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11984        return result;
11985    }
11986
11987    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11988            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11989        if (r.errorReportReceiver == null) {
11990            return null;
11991        }
11992
11993        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11994            return null;
11995        }
11996
11997        ApplicationErrorReport report = new ApplicationErrorReport();
11998        report.packageName = r.info.packageName;
11999        report.installerPackageName = r.errorReportReceiver.getPackageName();
12000        report.processName = r.processName;
12001        report.time = timeMillis;
12002        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12003
12004        if (r.crashing || r.forceCrashReport) {
12005            report.type = ApplicationErrorReport.TYPE_CRASH;
12006            report.crashInfo = crashInfo;
12007        } else if (r.notResponding) {
12008            report.type = ApplicationErrorReport.TYPE_ANR;
12009            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12010
12011            report.anrInfo.activity = r.notRespondingReport.tag;
12012            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12013            report.anrInfo.info = r.notRespondingReport.longMsg;
12014        }
12015
12016        return report;
12017    }
12018
12019    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12020        enforceNotIsolatedCaller("getProcessesInErrorState");
12021        // assume our apps are happy - lazy create the list
12022        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12023
12024        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12025                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12026        int userId = UserHandle.getUserId(Binder.getCallingUid());
12027
12028        synchronized (this) {
12029
12030            // iterate across all processes
12031            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12032                ProcessRecord app = mLruProcesses.get(i);
12033                if (!allUsers && app.userId != userId) {
12034                    continue;
12035                }
12036                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12037                    // This one's in trouble, so we'll generate a report for it
12038                    // crashes are higher priority (in case there's a crash *and* an anr)
12039                    ActivityManager.ProcessErrorStateInfo report = null;
12040                    if (app.crashing) {
12041                        report = app.crashingReport;
12042                    } else if (app.notResponding) {
12043                        report = app.notRespondingReport;
12044                    }
12045
12046                    if (report != null) {
12047                        if (errList == null) {
12048                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12049                        }
12050                        errList.add(report);
12051                    } else {
12052                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12053                                " crashing = " + app.crashing +
12054                                " notResponding = " + app.notResponding);
12055                    }
12056                }
12057            }
12058        }
12059
12060        return errList;
12061    }
12062
12063    static int procStateToImportance(int procState, int memAdj,
12064            ActivityManager.RunningAppProcessInfo currApp) {
12065        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12066        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12067            currApp.lru = memAdj;
12068        } else {
12069            currApp.lru = 0;
12070        }
12071        return imp;
12072    }
12073
12074    private void fillInProcMemInfo(ProcessRecord app,
12075            ActivityManager.RunningAppProcessInfo outInfo) {
12076        outInfo.pid = app.pid;
12077        outInfo.uid = app.info.uid;
12078        if (mHeavyWeightProcess == app) {
12079            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12080        }
12081        if (app.persistent) {
12082            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12083        }
12084        if (app.activities.size() > 0) {
12085            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12086        }
12087        outInfo.lastTrimLevel = app.trimMemoryLevel;
12088        int adj = app.curAdj;
12089        int procState = app.curProcState;
12090        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12091        outInfo.importanceReasonCode = app.adjTypeCode;
12092        outInfo.processState = app.curProcState;
12093    }
12094
12095    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12096        enforceNotIsolatedCaller("getRunningAppProcesses");
12097        // Lazy instantiation of list
12098        List<ActivityManager.RunningAppProcessInfo> runList = null;
12099        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12100                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12101        int userId = UserHandle.getUserId(Binder.getCallingUid());
12102        synchronized (this) {
12103            // Iterate across all processes
12104            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12105                ProcessRecord app = mLruProcesses.get(i);
12106                if (!allUsers && app.userId != userId) {
12107                    continue;
12108                }
12109                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12110                    // Generate process state info for running application
12111                    ActivityManager.RunningAppProcessInfo currApp =
12112                        new ActivityManager.RunningAppProcessInfo(app.processName,
12113                                app.pid, app.getPackageList());
12114                    fillInProcMemInfo(app, currApp);
12115                    if (app.adjSource instanceof ProcessRecord) {
12116                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12117                        currApp.importanceReasonImportance =
12118                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12119                                        app.adjSourceProcState);
12120                    } else if (app.adjSource instanceof ActivityRecord) {
12121                        ActivityRecord r = (ActivityRecord)app.adjSource;
12122                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12123                    }
12124                    if (app.adjTarget instanceof ComponentName) {
12125                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12126                    }
12127                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12128                    //        + " lru=" + currApp.lru);
12129                    if (runList == null) {
12130                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12131                    }
12132                    runList.add(currApp);
12133                }
12134            }
12135        }
12136        return runList;
12137    }
12138
12139    public List<ApplicationInfo> getRunningExternalApplications() {
12140        enforceNotIsolatedCaller("getRunningExternalApplications");
12141        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12142        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12143        if (runningApps != null && runningApps.size() > 0) {
12144            Set<String> extList = new HashSet<String>();
12145            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12146                if (app.pkgList != null) {
12147                    for (String pkg : app.pkgList) {
12148                        extList.add(pkg);
12149                    }
12150                }
12151            }
12152            IPackageManager pm = AppGlobals.getPackageManager();
12153            for (String pkg : extList) {
12154                try {
12155                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12156                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12157                        retList.add(info);
12158                    }
12159                } catch (RemoteException e) {
12160                }
12161            }
12162        }
12163        return retList;
12164    }
12165
12166    @Override
12167    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12168        enforceNotIsolatedCaller("getMyMemoryState");
12169        synchronized (this) {
12170            ProcessRecord proc;
12171            synchronized (mPidsSelfLocked) {
12172                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12173            }
12174            fillInProcMemInfo(proc, outInfo);
12175        }
12176    }
12177
12178    @Override
12179    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12180        if (checkCallingPermission(android.Manifest.permission.DUMP)
12181                != PackageManager.PERMISSION_GRANTED) {
12182            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12183                    + Binder.getCallingPid()
12184                    + ", uid=" + Binder.getCallingUid()
12185                    + " without permission "
12186                    + android.Manifest.permission.DUMP);
12187            return;
12188        }
12189
12190        boolean dumpAll = false;
12191        boolean dumpClient = false;
12192        String dumpPackage = null;
12193
12194        int opti = 0;
12195        while (opti < args.length) {
12196            String opt = args[opti];
12197            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12198                break;
12199            }
12200            opti++;
12201            if ("-a".equals(opt)) {
12202                dumpAll = true;
12203            } else if ("-c".equals(opt)) {
12204                dumpClient = true;
12205            } else if ("-h".equals(opt)) {
12206                pw.println("Activity manager dump options:");
12207                pw.println("  [-a] [-c] [-h] [cmd] ...");
12208                pw.println("  cmd may be one of:");
12209                pw.println("    a[ctivities]: activity stack state");
12210                pw.println("    r[recents]: recent activities state");
12211                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12212                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12213                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12214                pw.println("    o[om]: out of memory management");
12215                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12216                pw.println("    provider [COMP_SPEC]: provider client-side state");
12217                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12218                pw.println("    service [COMP_SPEC]: service client-side state");
12219                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12220                pw.println("    all: dump all activities");
12221                pw.println("    top: dump the top activity");
12222                pw.println("    write: write all pending state to storage");
12223                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12224                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12225                pw.println("    a partial substring in a component name, a");
12226                pw.println("    hex object identifier.");
12227                pw.println("  -a: include all available server state.");
12228                pw.println("  -c: include client state.");
12229                return;
12230            } else {
12231                pw.println("Unknown argument: " + opt + "; use -h for help");
12232            }
12233        }
12234
12235        long origId = Binder.clearCallingIdentity();
12236        boolean more = false;
12237        // Is the caller requesting to dump a particular piece of data?
12238        if (opti < args.length) {
12239            String cmd = args[opti];
12240            opti++;
12241            if ("activities".equals(cmd) || "a".equals(cmd)) {
12242                synchronized (this) {
12243                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12244                }
12245            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12246                synchronized (this) {
12247                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12248                }
12249            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12250                String[] newArgs;
12251                String name;
12252                if (opti >= args.length) {
12253                    name = null;
12254                    newArgs = EMPTY_STRING_ARRAY;
12255                } else {
12256                    name = args[opti];
12257                    opti++;
12258                    newArgs = new String[args.length - opti];
12259                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12260                            args.length - opti);
12261                }
12262                synchronized (this) {
12263                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12264                }
12265            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12266                String[] newArgs;
12267                String name;
12268                if (opti >= args.length) {
12269                    name = null;
12270                    newArgs = EMPTY_STRING_ARRAY;
12271                } else {
12272                    name = args[opti];
12273                    opti++;
12274                    newArgs = new String[args.length - opti];
12275                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12276                            args.length - opti);
12277                }
12278                synchronized (this) {
12279                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12280                }
12281            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12282                String[] newArgs;
12283                String name;
12284                if (opti >= args.length) {
12285                    name = null;
12286                    newArgs = EMPTY_STRING_ARRAY;
12287                } else {
12288                    name = args[opti];
12289                    opti++;
12290                    newArgs = new String[args.length - opti];
12291                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12292                            args.length - opti);
12293                }
12294                synchronized (this) {
12295                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12296                }
12297            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12298                synchronized (this) {
12299                    dumpOomLocked(fd, pw, args, opti, true);
12300                }
12301            } else if ("provider".equals(cmd)) {
12302                String[] newArgs;
12303                String name;
12304                if (opti >= args.length) {
12305                    name = null;
12306                    newArgs = EMPTY_STRING_ARRAY;
12307                } else {
12308                    name = args[opti];
12309                    opti++;
12310                    newArgs = new String[args.length - opti];
12311                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12312                }
12313                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12314                    pw.println("No providers match: " + name);
12315                    pw.println("Use -h for help.");
12316                }
12317            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12318                synchronized (this) {
12319                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12320                }
12321            } else if ("service".equals(cmd)) {
12322                String[] newArgs;
12323                String name;
12324                if (opti >= args.length) {
12325                    name = null;
12326                    newArgs = EMPTY_STRING_ARRAY;
12327                } else {
12328                    name = args[opti];
12329                    opti++;
12330                    newArgs = new String[args.length - opti];
12331                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12332                            args.length - opti);
12333                }
12334                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12335                    pw.println("No services match: " + name);
12336                    pw.println("Use -h for help.");
12337                }
12338            } else if ("package".equals(cmd)) {
12339                String[] newArgs;
12340                if (opti >= args.length) {
12341                    pw.println("package: no package name specified");
12342                    pw.println("Use -h for help.");
12343                } else {
12344                    dumpPackage = args[opti];
12345                    opti++;
12346                    newArgs = new String[args.length - opti];
12347                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12348                            args.length - opti);
12349                    args = newArgs;
12350                    opti = 0;
12351                    more = true;
12352                }
12353            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12354                synchronized (this) {
12355                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12356                }
12357            } else if ("write".equals(cmd)) {
12358                mTaskPersister.flush();
12359                pw.println("All tasks persisted.");
12360                return;
12361            } else {
12362                // Dumping a single activity?
12363                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12364                    pw.println("Bad activity command, or no activities match: " + cmd);
12365                    pw.println("Use -h for help.");
12366                }
12367            }
12368            if (!more) {
12369                Binder.restoreCallingIdentity(origId);
12370                return;
12371            }
12372        }
12373
12374        // No piece of data specified, dump everything.
12375        synchronized (this) {
12376            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12377            pw.println();
12378            if (dumpAll) {
12379                pw.println("-------------------------------------------------------------------------------");
12380            }
12381            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12382            pw.println();
12383            if (dumpAll) {
12384                pw.println("-------------------------------------------------------------------------------");
12385            }
12386            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12387            pw.println();
12388            if (dumpAll) {
12389                pw.println("-------------------------------------------------------------------------------");
12390            }
12391            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12392            pw.println();
12393            if (dumpAll) {
12394                pw.println("-------------------------------------------------------------------------------");
12395            }
12396            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12397            pw.println();
12398            if (dumpAll) {
12399                pw.println("-------------------------------------------------------------------------------");
12400            }
12401            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12402            pw.println();
12403            if (dumpAll) {
12404                pw.println("-------------------------------------------------------------------------------");
12405            }
12406            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12407        }
12408        Binder.restoreCallingIdentity(origId);
12409    }
12410
12411    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12412            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12413        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12414
12415        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12416                dumpPackage);
12417        boolean needSep = printedAnything;
12418
12419        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12420                dumpPackage, needSep, "  mFocusedActivity: ");
12421        if (printed) {
12422            printedAnything = true;
12423            needSep = false;
12424        }
12425
12426        if (dumpPackage == null) {
12427            if (needSep) {
12428                pw.println();
12429            }
12430            needSep = true;
12431            printedAnything = true;
12432            mStackSupervisor.dump(pw, "  ");
12433        }
12434
12435        if (!printedAnything) {
12436            pw.println("  (nothing)");
12437        }
12438    }
12439
12440    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12441            int opti, boolean dumpAll, String dumpPackage) {
12442        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12443
12444        boolean printedAnything = false;
12445
12446        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12447            boolean printedHeader = false;
12448
12449            final int N = mRecentTasks.size();
12450            for (int i=0; i<N; i++) {
12451                TaskRecord tr = mRecentTasks.get(i);
12452                if (dumpPackage != null) {
12453                    if (tr.realActivity == null ||
12454                            !dumpPackage.equals(tr.realActivity)) {
12455                        continue;
12456                    }
12457                }
12458                if (!printedHeader) {
12459                    pw.println("  Recent tasks:");
12460                    printedHeader = true;
12461                    printedAnything = true;
12462                }
12463                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12464                        pw.println(tr);
12465                if (dumpAll) {
12466                    mRecentTasks.get(i).dump(pw, "    ");
12467                }
12468            }
12469        }
12470
12471        if (!printedAnything) {
12472            pw.println("  (nothing)");
12473        }
12474    }
12475
12476    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12477            int opti, boolean dumpAll, String dumpPackage) {
12478        boolean needSep = false;
12479        boolean printedAnything = false;
12480        int numPers = 0;
12481
12482        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12483
12484        if (dumpAll) {
12485            final int NP = mProcessNames.getMap().size();
12486            for (int ip=0; ip<NP; ip++) {
12487                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12488                final int NA = procs.size();
12489                for (int ia=0; ia<NA; ia++) {
12490                    ProcessRecord r = procs.valueAt(ia);
12491                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12492                        continue;
12493                    }
12494                    if (!needSep) {
12495                        pw.println("  All known processes:");
12496                        needSep = true;
12497                        printedAnything = true;
12498                    }
12499                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12500                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12501                        pw.print(" "); pw.println(r);
12502                    r.dump(pw, "    ");
12503                    if (r.persistent) {
12504                        numPers++;
12505                    }
12506                }
12507            }
12508        }
12509
12510        if (mIsolatedProcesses.size() > 0) {
12511            boolean printed = false;
12512            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12513                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12514                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12515                    continue;
12516                }
12517                if (!printed) {
12518                    if (needSep) {
12519                        pw.println();
12520                    }
12521                    pw.println("  Isolated process list (sorted by uid):");
12522                    printedAnything = true;
12523                    printed = true;
12524                    needSep = true;
12525                }
12526                pw.println(String.format("%sIsolated #%2d: %s",
12527                        "    ", i, r.toString()));
12528            }
12529        }
12530
12531        if (mLruProcesses.size() > 0) {
12532            if (needSep) {
12533                pw.println();
12534            }
12535            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12536                    pw.print(" total, non-act at ");
12537                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12538                    pw.print(", non-svc at ");
12539                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12540                    pw.println("):");
12541            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12542            needSep = true;
12543            printedAnything = true;
12544        }
12545
12546        if (dumpAll || dumpPackage != null) {
12547            synchronized (mPidsSelfLocked) {
12548                boolean printed = false;
12549                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12550                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12551                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12552                        continue;
12553                    }
12554                    if (!printed) {
12555                        if (needSep) pw.println();
12556                        needSep = true;
12557                        pw.println("  PID mappings:");
12558                        printed = true;
12559                        printedAnything = true;
12560                    }
12561                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12562                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12563                }
12564            }
12565        }
12566
12567        if (mForegroundProcesses.size() > 0) {
12568            synchronized (mPidsSelfLocked) {
12569                boolean printed = false;
12570                for (int i=0; i<mForegroundProcesses.size(); i++) {
12571                    ProcessRecord r = mPidsSelfLocked.get(
12572                            mForegroundProcesses.valueAt(i).pid);
12573                    if (dumpPackage != null && (r == null
12574                            || !r.pkgList.containsKey(dumpPackage))) {
12575                        continue;
12576                    }
12577                    if (!printed) {
12578                        if (needSep) pw.println();
12579                        needSep = true;
12580                        pw.println("  Foreground Processes:");
12581                        printed = true;
12582                        printedAnything = true;
12583                    }
12584                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12585                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12586                }
12587            }
12588        }
12589
12590        if (mPersistentStartingProcesses.size() > 0) {
12591            if (needSep) pw.println();
12592            needSep = true;
12593            printedAnything = true;
12594            pw.println("  Persisent processes that are starting:");
12595            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12596                    "Starting Norm", "Restarting PERS", dumpPackage);
12597        }
12598
12599        if (mRemovedProcesses.size() > 0) {
12600            if (needSep) pw.println();
12601            needSep = true;
12602            printedAnything = true;
12603            pw.println("  Processes that are being removed:");
12604            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12605                    "Removed Norm", "Removed PERS", dumpPackage);
12606        }
12607
12608        if (mProcessesOnHold.size() > 0) {
12609            if (needSep) pw.println();
12610            needSep = true;
12611            printedAnything = true;
12612            pw.println("  Processes that are on old until the system is ready:");
12613            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12614                    "OnHold Norm", "OnHold PERS", dumpPackage);
12615        }
12616
12617        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12618
12619        if (mProcessCrashTimes.getMap().size() > 0) {
12620            boolean printed = false;
12621            long now = SystemClock.uptimeMillis();
12622            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12623            final int NP = pmap.size();
12624            for (int ip=0; ip<NP; ip++) {
12625                String pname = pmap.keyAt(ip);
12626                SparseArray<Long> uids = pmap.valueAt(ip);
12627                final int N = uids.size();
12628                for (int i=0; i<N; i++) {
12629                    int puid = uids.keyAt(i);
12630                    ProcessRecord r = mProcessNames.get(pname, puid);
12631                    if (dumpPackage != null && (r == null
12632                            || !r.pkgList.containsKey(dumpPackage))) {
12633                        continue;
12634                    }
12635                    if (!printed) {
12636                        if (needSep) pw.println();
12637                        needSep = true;
12638                        pw.println("  Time since processes crashed:");
12639                        printed = true;
12640                        printedAnything = true;
12641                    }
12642                    pw.print("    Process "); pw.print(pname);
12643                            pw.print(" uid "); pw.print(puid);
12644                            pw.print(": last crashed ");
12645                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12646                            pw.println(" ago");
12647                }
12648            }
12649        }
12650
12651        if (mBadProcesses.getMap().size() > 0) {
12652            boolean printed = false;
12653            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12654            final int NP = pmap.size();
12655            for (int ip=0; ip<NP; ip++) {
12656                String pname = pmap.keyAt(ip);
12657                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12658                final int N = uids.size();
12659                for (int i=0; i<N; i++) {
12660                    int puid = uids.keyAt(i);
12661                    ProcessRecord r = mProcessNames.get(pname, puid);
12662                    if (dumpPackage != null && (r == null
12663                            || !r.pkgList.containsKey(dumpPackage))) {
12664                        continue;
12665                    }
12666                    if (!printed) {
12667                        if (needSep) pw.println();
12668                        needSep = true;
12669                        pw.println("  Bad processes:");
12670                        printedAnything = true;
12671                    }
12672                    BadProcessInfo info = uids.valueAt(i);
12673                    pw.print("    Bad process "); pw.print(pname);
12674                            pw.print(" uid "); pw.print(puid);
12675                            pw.print(": crashed at time "); pw.println(info.time);
12676                    if (info.shortMsg != null) {
12677                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12678                    }
12679                    if (info.longMsg != null) {
12680                        pw.print("      Long msg: "); pw.println(info.longMsg);
12681                    }
12682                    if (info.stack != null) {
12683                        pw.println("      Stack:");
12684                        int lastPos = 0;
12685                        for (int pos=0; pos<info.stack.length(); pos++) {
12686                            if (info.stack.charAt(pos) == '\n') {
12687                                pw.print("        ");
12688                                pw.write(info.stack, lastPos, pos-lastPos);
12689                                pw.println();
12690                                lastPos = pos+1;
12691                            }
12692                        }
12693                        if (lastPos < info.stack.length()) {
12694                            pw.print("        ");
12695                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12696                            pw.println();
12697                        }
12698                    }
12699                }
12700            }
12701        }
12702
12703        if (dumpPackage == null) {
12704            pw.println();
12705            needSep = false;
12706            pw.println("  mStartedUsers:");
12707            for (int i=0; i<mStartedUsers.size(); i++) {
12708                UserStartedState uss = mStartedUsers.valueAt(i);
12709                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12710                        pw.print(": "); uss.dump("", pw);
12711            }
12712            pw.print("  mStartedUserArray: [");
12713            for (int i=0; i<mStartedUserArray.length; i++) {
12714                if (i > 0) pw.print(", ");
12715                pw.print(mStartedUserArray[i]);
12716            }
12717            pw.println("]");
12718            pw.print("  mUserLru: [");
12719            for (int i=0; i<mUserLru.size(); i++) {
12720                if (i > 0) pw.print(", ");
12721                pw.print(mUserLru.get(i));
12722            }
12723            pw.println("]");
12724            if (dumpAll) {
12725                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12726            }
12727            synchronized (mUserProfileGroupIdsSelfLocked) {
12728                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12729                    pw.println("  mUserProfileGroupIds:");
12730                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12731                        pw.print("    User #");
12732                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12733                        pw.print(" -> profile #");
12734                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12735                    }
12736                }
12737            }
12738        }
12739        if (mHomeProcess != null && (dumpPackage == null
12740                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12741            if (needSep) {
12742                pw.println();
12743                needSep = false;
12744            }
12745            pw.println("  mHomeProcess: " + mHomeProcess);
12746        }
12747        if (mPreviousProcess != null && (dumpPackage == null
12748                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12749            if (needSep) {
12750                pw.println();
12751                needSep = false;
12752            }
12753            pw.println("  mPreviousProcess: " + mPreviousProcess);
12754        }
12755        if (dumpAll) {
12756            StringBuilder sb = new StringBuilder(128);
12757            sb.append("  mPreviousProcessVisibleTime: ");
12758            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12759            pw.println(sb);
12760        }
12761        if (mHeavyWeightProcess != null && (dumpPackage == null
12762                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12763            if (needSep) {
12764                pw.println();
12765                needSep = false;
12766            }
12767            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12768        }
12769        if (dumpPackage == null) {
12770            pw.println("  mConfiguration: " + mConfiguration);
12771        }
12772        if (dumpAll) {
12773            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12774            if (mCompatModePackages.getPackages().size() > 0) {
12775                boolean printed = false;
12776                for (Map.Entry<String, Integer> entry
12777                        : mCompatModePackages.getPackages().entrySet()) {
12778                    String pkg = entry.getKey();
12779                    int mode = entry.getValue();
12780                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12781                        continue;
12782                    }
12783                    if (!printed) {
12784                        pw.println("  mScreenCompatPackages:");
12785                        printed = true;
12786                    }
12787                    pw.print("    "); pw.print(pkg); pw.print(": ");
12788                            pw.print(mode); pw.println();
12789                }
12790            }
12791        }
12792        if (dumpPackage == null) {
12793            if (mSleeping || mWentToSleep || mLockScreenShown != LOCK_SCREEN_HIDDEN) {
12794                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12795                        + " mLockScreenShown " + lockScreenShownToString());
12796            }
12797            if (mShuttingDown || mRunningVoice) {
12798                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12799            }
12800        }
12801        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12802                || mOrigWaitForDebugger) {
12803            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12804                    || dumpPackage.equals(mOrigDebugApp)) {
12805                if (needSep) {
12806                    pw.println();
12807                    needSep = false;
12808                }
12809                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12810                        + " mDebugTransient=" + mDebugTransient
12811                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12812            }
12813        }
12814        if (mOpenGlTraceApp != null) {
12815            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12816                if (needSep) {
12817                    pw.println();
12818                    needSep = false;
12819                }
12820                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12821            }
12822        }
12823        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12824                || mProfileFd != null) {
12825            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12826                if (needSep) {
12827                    pw.println();
12828                    needSep = false;
12829                }
12830                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12831                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12832                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12833                        + mAutoStopProfiler);
12834                pw.println("  mProfileType=" + mProfileType);
12835            }
12836        }
12837        if (dumpPackage == null) {
12838            if (mAlwaysFinishActivities || mController != null) {
12839                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12840                        + " mController=" + mController);
12841            }
12842            if (dumpAll) {
12843                pw.println("  Total persistent processes: " + numPers);
12844                pw.println("  mProcessesReady=" + mProcessesReady
12845                        + " mSystemReady=" + mSystemReady
12846                        + " mBooted=" + mBooted
12847                        + " mFactoryTest=" + mFactoryTest);
12848                pw.println("  mBooting=" + mBooting
12849                        + " mCallFinishBooting=" + mCallFinishBooting
12850                        + " mBootAnimationComplete=" + mBootAnimationComplete);
12851                pw.print("  mLastPowerCheckRealtime=");
12852                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12853                        pw.println("");
12854                pw.print("  mLastPowerCheckUptime=");
12855                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12856                        pw.println("");
12857                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12858                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12859                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12860                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12861                        + " (" + mLruProcesses.size() + " total)"
12862                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12863                        + " mNumServiceProcs=" + mNumServiceProcs
12864                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12865                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12866                        + " mLastMemoryLevel" + mLastMemoryLevel
12867                        + " mLastNumProcesses" + mLastNumProcesses);
12868                long now = SystemClock.uptimeMillis();
12869                pw.print("  mLastIdleTime=");
12870                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12871                        pw.print(" mLowRamSinceLastIdle=");
12872                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12873                        pw.println();
12874            }
12875        }
12876
12877        if (!printedAnything) {
12878            pw.println("  (nothing)");
12879        }
12880    }
12881
12882    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12883            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12884        if (mProcessesToGc.size() > 0) {
12885            boolean printed = false;
12886            long now = SystemClock.uptimeMillis();
12887            for (int i=0; i<mProcessesToGc.size(); i++) {
12888                ProcessRecord proc = mProcessesToGc.get(i);
12889                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12890                    continue;
12891                }
12892                if (!printed) {
12893                    if (needSep) pw.println();
12894                    needSep = true;
12895                    pw.println("  Processes that are waiting to GC:");
12896                    printed = true;
12897                }
12898                pw.print("    Process "); pw.println(proc);
12899                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12900                        pw.print(", last gced=");
12901                        pw.print(now-proc.lastRequestedGc);
12902                        pw.print(" ms ago, last lowMem=");
12903                        pw.print(now-proc.lastLowMemory);
12904                        pw.println(" ms ago");
12905
12906            }
12907        }
12908        return needSep;
12909    }
12910
12911    void printOomLevel(PrintWriter pw, String name, int adj) {
12912        pw.print("    ");
12913        if (adj >= 0) {
12914            pw.print(' ');
12915            if (adj < 10) pw.print(' ');
12916        } else {
12917            if (adj > -10) pw.print(' ');
12918        }
12919        pw.print(adj);
12920        pw.print(": ");
12921        pw.print(name);
12922        pw.print(" (");
12923        pw.print(mProcessList.getMemLevel(adj)/1024);
12924        pw.println(" kB)");
12925    }
12926
12927    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12928            int opti, boolean dumpAll) {
12929        boolean needSep = false;
12930
12931        if (mLruProcesses.size() > 0) {
12932            if (needSep) pw.println();
12933            needSep = true;
12934            pw.println("  OOM levels:");
12935            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12936            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12937            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
12938            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12939            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12940            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12941            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12942            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12943            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12944            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12945            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12946            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12947            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12948            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12949
12950            if (needSep) pw.println();
12951            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12952                    pw.print(" total, non-act at ");
12953                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12954                    pw.print(", non-svc at ");
12955                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12956                    pw.println("):");
12957            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12958            needSep = true;
12959        }
12960
12961        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12962
12963        pw.println();
12964        pw.println("  mHomeProcess: " + mHomeProcess);
12965        pw.println("  mPreviousProcess: " + mPreviousProcess);
12966        if (mHeavyWeightProcess != null) {
12967            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12968        }
12969
12970        return true;
12971    }
12972
12973    /**
12974     * There are three ways to call this:
12975     *  - no provider specified: dump all the providers
12976     *  - a flattened component name that matched an existing provider was specified as the
12977     *    first arg: dump that one provider
12978     *  - the first arg isn't the flattened component name of an existing provider:
12979     *    dump all providers whose component contains the first arg as a substring
12980     */
12981    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12982            int opti, boolean dumpAll) {
12983        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12984    }
12985
12986    static class ItemMatcher {
12987        ArrayList<ComponentName> components;
12988        ArrayList<String> strings;
12989        ArrayList<Integer> objects;
12990        boolean all;
12991
12992        ItemMatcher() {
12993            all = true;
12994        }
12995
12996        void build(String name) {
12997            ComponentName componentName = ComponentName.unflattenFromString(name);
12998            if (componentName != null) {
12999                if (components == null) {
13000                    components = new ArrayList<ComponentName>();
13001                }
13002                components.add(componentName);
13003                all = false;
13004            } else {
13005                int objectId = 0;
13006                // Not a '/' separated full component name; maybe an object ID?
13007                try {
13008                    objectId = Integer.parseInt(name, 16);
13009                    if (objects == null) {
13010                        objects = new ArrayList<Integer>();
13011                    }
13012                    objects.add(objectId);
13013                    all = false;
13014                } catch (RuntimeException e) {
13015                    // Not an integer; just do string match.
13016                    if (strings == null) {
13017                        strings = new ArrayList<String>();
13018                    }
13019                    strings.add(name);
13020                    all = false;
13021                }
13022            }
13023        }
13024
13025        int build(String[] args, int opti) {
13026            for (; opti<args.length; opti++) {
13027                String name = args[opti];
13028                if ("--".equals(name)) {
13029                    return opti+1;
13030                }
13031                build(name);
13032            }
13033            return opti;
13034        }
13035
13036        boolean match(Object object, ComponentName comp) {
13037            if (all) {
13038                return true;
13039            }
13040            if (components != null) {
13041                for (int i=0; i<components.size(); i++) {
13042                    if (components.get(i).equals(comp)) {
13043                        return true;
13044                    }
13045                }
13046            }
13047            if (objects != null) {
13048                for (int i=0; i<objects.size(); i++) {
13049                    if (System.identityHashCode(object) == objects.get(i)) {
13050                        return true;
13051                    }
13052                }
13053            }
13054            if (strings != null) {
13055                String flat = comp.flattenToString();
13056                for (int i=0; i<strings.size(); i++) {
13057                    if (flat.contains(strings.get(i))) {
13058                        return true;
13059                    }
13060                }
13061            }
13062            return false;
13063        }
13064    }
13065
13066    /**
13067     * There are three things that cmd can be:
13068     *  - a flattened component name that matches an existing activity
13069     *  - the cmd arg isn't the flattened component name of an existing activity:
13070     *    dump all activity whose component contains the cmd as a substring
13071     *  - A hex number of the ActivityRecord object instance.
13072     */
13073    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13074            int opti, boolean dumpAll) {
13075        ArrayList<ActivityRecord> activities;
13076
13077        synchronized (this) {
13078            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13079        }
13080
13081        if (activities.size() <= 0) {
13082            return false;
13083        }
13084
13085        String[] newArgs = new String[args.length - opti];
13086        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13087
13088        TaskRecord lastTask = null;
13089        boolean needSep = false;
13090        for (int i=activities.size()-1; i>=0; i--) {
13091            ActivityRecord r = activities.get(i);
13092            if (needSep) {
13093                pw.println();
13094            }
13095            needSep = true;
13096            synchronized (this) {
13097                if (lastTask != r.task) {
13098                    lastTask = r.task;
13099                    pw.print("TASK "); pw.print(lastTask.affinity);
13100                            pw.print(" id="); pw.println(lastTask.taskId);
13101                    if (dumpAll) {
13102                        lastTask.dump(pw, "  ");
13103                    }
13104                }
13105            }
13106            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13107        }
13108        return true;
13109    }
13110
13111    /**
13112     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13113     * there is a thread associated with the activity.
13114     */
13115    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13116            final ActivityRecord r, String[] args, boolean dumpAll) {
13117        String innerPrefix = prefix + "  ";
13118        synchronized (this) {
13119            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13120                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13121                    pw.print(" pid=");
13122                    if (r.app != null) pw.println(r.app.pid);
13123                    else pw.println("(not running)");
13124            if (dumpAll) {
13125                r.dump(pw, innerPrefix);
13126            }
13127        }
13128        if (r.app != null && r.app.thread != null) {
13129            // flush anything that is already in the PrintWriter since the thread is going
13130            // to write to the file descriptor directly
13131            pw.flush();
13132            try {
13133                TransferPipe tp = new TransferPipe();
13134                try {
13135                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13136                            r.appToken, innerPrefix, args);
13137                    tp.go(fd);
13138                } finally {
13139                    tp.kill();
13140                }
13141            } catch (IOException e) {
13142                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13143            } catch (RemoteException e) {
13144                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13145            }
13146        }
13147    }
13148
13149    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13150            int opti, boolean dumpAll, String dumpPackage) {
13151        boolean needSep = false;
13152        boolean onlyHistory = false;
13153        boolean printedAnything = false;
13154
13155        if ("history".equals(dumpPackage)) {
13156            if (opti < args.length && "-s".equals(args[opti])) {
13157                dumpAll = false;
13158            }
13159            onlyHistory = true;
13160            dumpPackage = null;
13161        }
13162
13163        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13164        if (!onlyHistory && dumpAll) {
13165            if (mRegisteredReceivers.size() > 0) {
13166                boolean printed = false;
13167                Iterator it = mRegisteredReceivers.values().iterator();
13168                while (it.hasNext()) {
13169                    ReceiverList r = (ReceiverList)it.next();
13170                    if (dumpPackage != null && (r.app == null ||
13171                            !dumpPackage.equals(r.app.info.packageName))) {
13172                        continue;
13173                    }
13174                    if (!printed) {
13175                        pw.println("  Registered Receivers:");
13176                        needSep = true;
13177                        printed = true;
13178                        printedAnything = true;
13179                    }
13180                    pw.print("  * "); pw.println(r);
13181                    r.dump(pw, "    ");
13182                }
13183            }
13184
13185            if (mReceiverResolver.dump(pw, needSep ?
13186                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13187                    "    ", dumpPackage, false)) {
13188                needSep = true;
13189                printedAnything = true;
13190            }
13191        }
13192
13193        for (BroadcastQueue q : mBroadcastQueues) {
13194            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13195            printedAnything |= needSep;
13196        }
13197
13198        needSep = true;
13199
13200        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13201            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13202                if (needSep) {
13203                    pw.println();
13204                }
13205                needSep = true;
13206                printedAnything = true;
13207                pw.print("  Sticky broadcasts for user ");
13208                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13209                StringBuilder sb = new StringBuilder(128);
13210                for (Map.Entry<String, ArrayList<Intent>> ent
13211                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13212                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13213                    if (dumpAll) {
13214                        pw.println(":");
13215                        ArrayList<Intent> intents = ent.getValue();
13216                        final int N = intents.size();
13217                        for (int i=0; i<N; i++) {
13218                            sb.setLength(0);
13219                            sb.append("    Intent: ");
13220                            intents.get(i).toShortString(sb, false, true, false, false);
13221                            pw.println(sb.toString());
13222                            Bundle bundle = intents.get(i).getExtras();
13223                            if (bundle != null) {
13224                                pw.print("      ");
13225                                pw.println(bundle.toString());
13226                            }
13227                        }
13228                    } else {
13229                        pw.println("");
13230                    }
13231                }
13232            }
13233        }
13234
13235        if (!onlyHistory && dumpAll) {
13236            pw.println();
13237            for (BroadcastQueue queue : mBroadcastQueues) {
13238                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13239                        + queue.mBroadcastsScheduled);
13240            }
13241            pw.println("  mHandler:");
13242            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13243            needSep = true;
13244            printedAnything = true;
13245        }
13246
13247        if (!printedAnything) {
13248            pw.println("  (nothing)");
13249        }
13250    }
13251
13252    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13253            int opti, boolean dumpAll, String dumpPackage) {
13254        boolean needSep;
13255        boolean printedAnything = false;
13256
13257        ItemMatcher matcher = new ItemMatcher();
13258        matcher.build(args, opti);
13259
13260        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13261
13262        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13263        printedAnything |= needSep;
13264
13265        if (mLaunchingProviders.size() > 0) {
13266            boolean printed = false;
13267            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13268                ContentProviderRecord r = mLaunchingProviders.get(i);
13269                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13270                    continue;
13271                }
13272                if (!printed) {
13273                    if (needSep) pw.println();
13274                    needSep = true;
13275                    pw.println("  Launching content providers:");
13276                    printed = true;
13277                    printedAnything = true;
13278                }
13279                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13280                        pw.println(r);
13281            }
13282        }
13283
13284        if (mGrantedUriPermissions.size() > 0) {
13285            boolean printed = false;
13286            int dumpUid = -2;
13287            if (dumpPackage != null) {
13288                try {
13289                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13290                } catch (NameNotFoundException e) {
13291                    dumpUid = -1;
13292                }
13293            }
13294            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13295                int uid = mGrantedUriPermissions.keyAt(i);
13296                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13297                    continue;
13298                }
13299                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13300                if (!printed) {
13301                    if (needSep) pw.println();
13302                    needSep = true;
13303                    pw.println("  Granted Uri Permissions:");
13304                    printed = true;
13305                    printedAnything = true;
13306                }
13307                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13308                for (UriPermission perm : perms.values()) {
13309                    pw.print("    "); pw.println(perm);
13310                    if (dumpAll) {
13311                        perm.dump(pw, "      ");
13312                    }
13313                }
13314            }
13315        }
13316
13317        if (!printedAnything) {
13318            pw.println("  (nothing)");
13319        }
13320    }
13321
13322    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13323            int opti, boolean dumpAll, String dumpPackage) {
13324        boolean printed = false;
13325
13326        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13327
13328        if (mIntentSenderRecords.size() > 0) {
13329            Iterator<WeakReference<PendingIntentRecord>> it
13330                    = mIntentSenderRecords.values().iterator();
13331            while (it.hasNext()) {
13332                WeakReference<PendingIntentRecord> ref = it.next();
13333                PendingIntentRecord rec = ref != null ? ref.get(): null;
13334                if (dumpPackage != null && (rec == null
13335                        || !dumpPackage.equals(rec.key.packageName))) {
13336                    continue;
13337                }
13338                printed = true;
13339                if (rec != null) {
13340                    pw.print("  * "); pw.println(rec);
13341                    if (dumpAll) {
13342                        rec.dump(pw, "    ");
13343                    }
13344                } else {
13345                    pw.print("  * "); pw.println(ref);
13346                }
13347            }
13348        }
13349
13350        if (!printed) {
13351            pw.println("  (nothing)");
13352        }
13353    }
13354
13355    private static final int dumpProcessList(PrintWriter pw,
13356            ActivityManagerService service, List list,
13357            String prefix, String normalLabel, String persistentLabel,
13358            String dumpPackage) {
13359        int numPers = 0;
13360        final int N = list.size()-1;
13361        for (int i=N; i>=0; i--) {
13362            ProcessRecord r = (ProcessRecord)list.get(i);
13363            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13364                continue;
13365            }
13366            pw.println(String.format("%s%s #%2d: %s",
13367                    prefix, (r.persistent ? persistentLabel : normalLabel),
13368                    i, r.toString()));
13369            if (r.persistent) {
13370                numPers++;
13371            }
13372        }
13373        return numPers;
13374    }
13375
13376    private static final boolean dumpProcessOomList(PrintWriter pw,
13377            ActivityManagerService service, List<ProcessRecord> origList,
13378            String prefix, String normalLabel, String persistentLabel,
13379            boolean inclDetails, String dumpPackage) {
13380
13381        ArrayList<Pair<ProcessRecord, Integer>> list
13382                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13383        for (int i=0; i<origList.size(); i++) {
13384            ProcessRecord r = origList.get(i);
13385            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13386                continue;
13387            }
13388            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13389        }
13390
13391        if (list.size() <= 0) {
13392            return false;
13393        }
13394
13395        Comparator<Pair<ProcessRecord, Integer>> comparator
13396                = new Comparator<Pair<ProcessRecord, Integer>>() {
13397            @Override
13398            public int compare(Pair<ProcessRecord, Integer> object1,
13399                    Pair<ProcessRecord, Integer> object2) {
13400                if (object1.first.setAdj != object2.first.setAdj) {
13401                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13402                }
13403                if (object1.second.intValue() != object2.second.intValue()) {
13404                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13405                }
13406                return 0;
13407            }
13408        };
13409
13410        Collections.sort(list, comparator);
13411
13412        final long curRealtime = SystemClock.elapsedRealtime();
13413        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13414        final long curUptime = SystemClock.uptimeMillis();
13415        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13416
13417        for (int i=list.size()-1; i>=0; i--) {
13418            ProcessRecord r = list.get(i).first;
13419            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13420            char schedGroup;
13421            switch (r.setSchedGroup) {
13422                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13423                    schedGroup = 'B';
13424                    break;
13425                case Process.THREAD_GROUP_DEFAULT:
13426                    schedGroup = 'F';
13427                    break;
13428                default:
13429                    schedGroup = '?';
13430                    break;
13431            }
13432            char foreground;
13433            if (r.foregroundActivities) {
13434                foreground = 'A';
13435            } else if (r.foregroundServices) {
13436                foreground = 'S';
13437            } else {
13438                foreground = ' ';
13439            }
13440            String procState = ProcessList.makeProcStateString(r.curProcState);
13441            pw.print(prefix);
13442            pw.print(r.persistent ? persistentLabel : normalLabel);
13443            pw.print(" #");
13444            int num = (origList.size()-1)-list.get(i).second;
13445            if (num < 10) pw.print(' ');
13446            pw.print(num);
13447            pw.print(": ");
13448            pw.print(oomAdj);
13449            pw.print(' ');
13450            pw.print(schedGroup);
13451            pw.print('/');
13452            pw.print(foreground);
13453            pw.print('/');
13454            pw.print(procState);
13455            pw.print(" trm:");
13456            if (r.trimMemoryLevel < 10) pw.print(' ');
13457            pw.print(r.trimMemoryLevel);
13458            pw.print(' ');
13459            pw.print(r.toShortString());
13460            pw.print(" (");
13461            pw.print(r.adjType);
13462            pw.println(')');
13463            if (r.adjSource != null || r.adjTarget != null) {
13464                pw.print(prefix);
13465                pw.print("    ");
13466                if (r.adjTarget instanceof ComponentName) {
13467                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13468                } else if (r.adjTarget != null) {
13469                    pw.print(r.adjTarget.toString());
13470                } else {
13471                    pw.print("{null}");
13472                }
13473                pw.print("<=");
13474                if (r.adjSource instanceof ProcessRecord) {
13475                    pw.print("Proc{");
13476                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13477                    pw.println("}");
13478                } else if (r.adjSource != null) {
13479                    pw.println(r.adjSource.toString());
13480                } else {
13481                    pw.println("{null}");
13482                }
13483            }
13484            if (inclDetails) {
13485                pw.print(prefix);
13486                pw.print("    ");
13487                pw.print("oom: max="); pw.print(r.maxAdj);
13488                pw.print(" curRaw="); pw.print(r.curRawAdj);
13489                pw.print(" setRaw="); pw.print(r.setRawAdj);
13490                pw.print(" cur="); pw.print(r.curAdj);
13491                pw.print(" set="); pw.println(r.setAdj);
13492                pw.print(prefix);
13493                pw.print("    ");
13494                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13495                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13496                pw.print(" lastPss="); pw.print(r.lastPss);
13497                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13498                pw.print(prefix);
13499                pw.print("    ");
13500                pw.print("cached="); pw.print(r.cached);
13501                pw.print(" empty="); pw.print(r.empty);
13502                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13503
13504                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13505                    if (r.lastWakeTime != 0) {
13506                        long wtime;
13507                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13508                        synchronized (stats) {
13509                            wtime = stats.getProcessWakeTime(r.info.uid,
13510                                    r.pid, curRealtime);
13511                        }
13512                        long timeUsed = wtime - r.lastWakeTime;
13513                        pw.print(prefix);
13514                        pw.print("    ");
13515                        pw.print("keep awake over ");
13516                        TimeUtils.formatDuration(realtimeSince, pw);
13517                        pw.print(" used ");
13518                        TimeUtils.formatDuration(timeUsed, pw);
13519                        pw.print(" (");
13520                        pw.print((timeUsed*100)/realtimeSince);
13521                        pw.println("%)");
13522                    }
13523                    if (r.lastCpuTime != 0) {
13524                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13525                        pw.print(prefix);
13526                        pw.print("    ");
13527                        pw.print("run cpu over ");
13528                        TimeUtils.formatDuration(uptimeSince, pw);
13529                        pw.print(" used ");
13530                        TimeUtils.formatDuration(timeUsed, pw);
13531                        pw.print(" (");
13532                        pw.print((timeUsed*100)/uptimeSince);
13533                        pw.println("%)");
13534                    }
13535                }
13536            }
13537        }
13538        return true;
13539    }
13540
13541    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13542            String[] args) {
13543        ArrayList<ProcessRecord> procs;
13544        synchronized (this) {
13545            if (args != null && args.length > start
13546                    && args[start].charAt(0) != '-') {
13547                procs = new ArrayList<ProcessRecord>();
13548                int pid = -1;
13549                try {
13550                    pid = Integer.parseInt(args[start]);
13551                } catch (NumberFormatException e) {
13552                }
13553                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13554                    ProcessRecord proc = mLruProcesses.get(i);
13555                    if (proc.pid == pid) {
13556                        procs.add(proc);
13557                    } else if (allPkgs && proc.pkgList != null
13558                            && proc.pkgList.containsKey(args[start])) {
13559                        procs.add(proc);
13560                    } else if (proc.processName.equals(args[start])) {
13561                        procs.add(proc);
13562                    }
13563                }
13564                if (procs.size() <= 0) {
13565                    return null;
13566                }
13567            } else {
13568                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13569            }
13570        }
13571        return procs;
13572    }
13573
13574    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13575            PrintWriter pw, String[] args) {
13576        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13577        if (procs == null) {
13578            pw.println("No process found for: " + args[0]);
13579            return;
13580        }
13581
13582        long uptime = SystemClock.uptimeMillis();
13583        long realtime = SystemClock.elapsedRealtime();
13584        pw.println("Applications Graphics Acceleration Info:");
13585        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13586
13587        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13588            ProcessRecord r = procs.get(i);
13589            if (r.thread != null) {
13590                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13591                pw.flush();
13592                try {
13593                    TransferPipe tp = new TransferPipe();
13594                    try {
13595                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13596                        tp.go(fd);
13597                    } finally {
13598                        tp.kill();
13599                    }
13600                } catch (IOException e) {
13601                    pw.println("Failure while dumping the app: " + r);
13602                    pw.flush();
13603                } catch (RemoteException e) {
13604                    pw.println("Got a RemoteException while dumping the app " + r);
13605                    pw.flush();
13606                }
13607            }
13608        }
13609    }
13610
13611    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13612        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13613        if (procs == null) {
13614            pw.println("No process found for: " + args[0]);
13615            return;
13616        }
13617
13618        pw.println("Applications Database Info:");
13619
13620        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13621            ProcessRecord r = procs.get(i);
13622            if (r.thread != null) {
13623                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13624                pw.flush();
13625                try {
13626                    TransferPipe tp = new TransferPipe();
13627                    try {
13628                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13629                        tp.go(fd);
13630                    } finally {
13631                        tp.kill();
13632                    }
13633                } catch (IOException e) {
13634                    pw.println("Failure while dumping the app: " + r);
13635                    pw.flush();
13636                } catch (RemoteException e) {
13637                    pw.println("Got a RemoteException while dumping the app " + r);
13638                    pw.flush();
13639                }
13640            }
13641        }
13642    }
13643
13644    final static class MemItem {
13645        final boolean isProc;
13646        final String label;
13647        final String shortLabel;
13648        final long pss;
13649        final int id;
13650        final boolean hasActivities;
13651        ArrayList<MemItem> subitems;
13652
13653        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13654                boolean _hasActivities) {
13655            isProc = true;
13656            label = _label;
13657            shortLabel = _shortLabel;
13658            pss = _pss;
13659            id = _id;
13660            hasActivities = _hasActivities;
13661        }
13662
13663        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13664            isProc = false;
13665            label = _label;
13666            shortLabel = _shortLabel;
13667            pss = _pss;
13668            id = _id;
13669            hasActivities = false;
13670        }
13671    }
13672
13673    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13674            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13675        if (sort && !isCompact) {
13676            Collections.sort(items, new Comparator<MemItem>() {
13677                @Override
13678                public int compare(MemItem lhs, MemItem rhs) {
13679                    if (lhs.pss < rhs.pss) {
13680                        return 1;
13681                    } else if (lhs.pss > rhs.pss) {
13682                        return -1;
13683                    }
13684                    return 0;
13685                }
13686            });
13687        }
13688
13689        for (int i=0; i<items.size(); i++) {
13690            MemItem mi = items.get(i);
13691            if (!isCompact) {
13692                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13693            } else if (mi.isProc) {
13694                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13695                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13696                pw.println(mi.hasActivities ? ",a" : ",e");
13697            } else {
13698                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13699                pw.println(mi.pss);
13700            }
13701            if (mi.subitems != null) {
13702                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13703                        true, isCompact);
13704            }
13705        }
13706    }
13707
13708    // These are in KB.
13709    static final long[] DUMP_MEM_BUCKETS = new long[] {
13710        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13711        120*1024, 160*1024, 200*1024,
13712        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13713        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13714    };
13715
13716    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13717            boolean stackLike) {
13718        int start = label.lastIndexOf('.');
13719        if (start >= 0) start++;
13720        else start = 0;
13721        int end = label.length();
13722        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13723            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13724                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13725                out.append(bucket);
13726                out.append(stackLike ? "MB." : "MB ");
13727                out.append(label, start, end);
13728                return;
13729            }
13730        }
13731        out.append(memKB/1024);
13732        out.append(stackLike ? "MB." : "MB ");
13733        out.append(label, start, end);
13734    }
13735
13736    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13737            ProcessList.NATIVE_ADJ,
13738            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13739            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13740            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13741            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13742            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13743            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13744    };
13745    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13746            "Native",
13747            "System", "Persistent", "Persistent Service", "Foreground",
13748            "Visible", "Perceptible",
13749            "Heavy Weight", "Backup",
13750            "A Services", "Home",
13751            "Previous", "B Services", "Cached"
13752    };
13753    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13754            "native",
13755            "sys", "pers", "persvc", "fore",
13756            "vis", "percept",
13757            "heavy", "backup",
13758            "servicea", "home",
13759            "prev", "serviceb", "cached"
13760    };
13761
13762    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13763            long realtime, boolean isCheckinRequest, boolean isCompact) {
13764        if (isCheckinRequest || isCompact) {
13765            // short checkin version
13766            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13767        } else {
13768            pw.println("Applications Memory Usage (kB):");
13769            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13770        }
13771    }
13772
13773    private static final int KSM_SHARED = 0;
13774    private static final int KSM_SHARING = 1;
13775    private static final int KSM_UNSHARED = 2;
13776    private static final int KSM_VOLATILE = 3;
13777
13778    private final long[] getKsmInfo() {
13779        long[] longOut = new long[4];
13780        final int[] SINGLE_LONG_FORMAT = new int[] {
13781            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13782        };
13783        long[] longTmp = new long[1];
13784        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13785                SINGLE_LONG_FORMAT, null, longTmp, null);
13786        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13787        longTmp[0] = 0;
13788        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13789                SINGLE_LONG_FORMAT, null, longTmp, null);
13790        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13791        longTmp[0] = 0;
13792        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13793                SINGLE_LONG_FORMAT, null, longTmp, null);
13794        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13795        longTmp[0] = 0;
13796        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13797                SINGLE_LONG_FORMAT, null, longTmp, null);
13798        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13799        return longOut;
13800    }
13801
13802    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13803            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13804        boolean dumpDetails = false;
13805        boolean dumpFullDetails = false;
13806        boolean dumpDalvik = false;
13807        boolean oomOnly = false;
13808        boolean isCompact = false;
13809        boolean localOnly = false;
13810        boolean packages = false;
13811
13812        int opti = 0;
13813        while (opti < args.length) {
13814            String opt = args[opti];
13815            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13816                break;
13817            }
13818            opti++;
13819            if ("-a".equals(opt)) {
13820                dumpDetails = true;
13821                dumpFullDetails = true;
13822                dumpDalvik = true;
13823            } else if ("-d".equals(opt)) {
13824                dumpDalvik = true;
13825            } else if ("-c".equals(opt)) {
13826                isCompact = true;
13827            } else if ("--oom".equals(opt)) {
13828                oomOnly = true;
13829            } else if ("--local".equals(opt)) {
13830                localOnly = true;
13831            } else if ("--package".equals(opt)) {
13832                packages = true;
13833            } else if ("-h".equals(opt)) {
13834                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13835                pw.println("  -a: include all available information for each process.");
13836                pw.println("  -d: include dalvik details when dumping process details.");
13837                pw.println("  -c: dump in a compact machine-parseable representation.");
13838                pw.println("  --oom: only show processes organized by oom adj.");
13839                pw.println("  --local: only collect details locally, don't call process.");
13840                pw.println("  --package: interpret process arg as package, dumping all");
13841                pw.println("             processes that have loaded that package.");
13842                pw.println("If [process] is specified it can be the name or ");
13843                pw.println("pid of a specific process to dump.");
13844                return;
13845            } else {
13846                pw.println("Unknown argument: " + opt + "; use -h for help");
13847            }
13848        }
13849
13850        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13851        long uptime = SystemClock.uptimeMillis();
13852        long realtime = SystemClock.elapsedRealtime();
13853        final long[] tmpLong = new long[1];
13854
13855        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13856        if (procs == null) {
13857            // No Java processes.  Maybe they want to print a native process.
13858            if (args != null && args.length > opti
13859                    && args[opti].charAt(0) != '-') {
13860                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13861                        = new ArrayList<ProcessCpuTracker.Stats>();
13862                updateCpuStatsNow();
13863                int findPid = -1;
13864                try {
13865                    findPid = Integer.parseInt(args[opti]);
13866                } catch (NumberFormatException e) {
13867                }
13868                synchronized (mProcessCpuTracker) {
13869                    final int N = mProcessCpuTracker.countStats();
13870                    for (int i=0; i<N; i++) {
13871                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13872                        if (st.pid == findPid || (st.baseName != null
13873                                && st.baseName.equals(args[opti]))) {
13874                            nativeProcs.add(st);
13875                        }
13876                    }
13877                }
13878                if (nativeProcs.size() > 0) {
13879                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13880                            isCompact);
13881                    Debug.MemoryInfo mi = null;
13882                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13883                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13884                        final int pid = r.pid;
13885                        if (!isCheckinRequest && dumpDetails) {
13886                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13887                        }
13888                        if (mi == null) {
13889                            mi = new Debug.MemoryInfo();
13890                        }
13891                        if (dumpDetails || (!brief && !oomOnly)) {
13892                            Debug.getMemoryInfo(pid, mi);
13893                        } else {
13894                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13895                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13896                        }
13897                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13898                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13899                        if (isCheckinRequest) {
13900                            pw.println();
13901                        }
13902                    }
13903                    return;
13904                }
13905            }
13906            pw.println("No process found for: " + args[opti]);
13907            return;
13908        }
13909
13910        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
13911            dumpDetails = true;
13912        }
13913
13914        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13915
13916        String[] innerArgs = new String[args.length-opti];
13917        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13918
13919        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13920        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13921        long nativePss=0, dalvikPss=0, otherPss=0;
13922        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13923
13924        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13925        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13926                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13927
13928        long totalPss = 0;
13929        long cachedPss = 0;
13930
13931        Debug.MemoryInfo mi = null;
13932        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13933            final ProcessRecord r = procs.get(i);
13934            final IApplicationThread thread;
13935            final int pid;
13936            final int oomAdj;
13937            final boolean hasActivities;
13938            synchronized (this) {
13939                thread = r.thread;
13940                pid = r.pid;
13941                oomAdj = r.getSetAdjWithServices();
13942                hasActivities = r.activities.size() > 0;
13943            }
13944            if (thread != null) {
13945                if (!isCheckinRequest && dumpDetails) {
13946                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13947                }
13948                if (mi == null) {
13949                    mi = new Debug.MemoryInfo();
13950                }
13951                if (dumpDetails || (!brief && !oomOnly)) {
13952                    Debug.getMemoryInfo(pid, mi);
13953                } else {
13954                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13955                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13956                }
13957                if (dumpDetails) {
13958                    if (localOnly) {
13959                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13960                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13961                        if (isCheckinRequest) {
13962                            pw.println();
13963                        }
13964                    } else {
13965                        try {
13966                            pw.flush();
13967                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13968                                    dumpDalvik, innerArgs);
13969                        } catch (RemoteException e) {
13970                            if (!isCheckinRequest) {
13971                                pw.println("Got RemoteException!");
13972                                pw.flush();
13973                            }
13974                        }
13975                    }
13976                }
13977
13978                final long myTotalPss = mi.getTotalPss();
13979                final long myTotalUss = mi.getTotalUss();
13980
13981                synchronized (this) {
13982                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13983                        // Record this for posterity if the process has been stable.
13984                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13985                    }
13986                }
13987
13988                if (!isCheckinRequest && mi != null) {
13989                    totalPss += myTotalPss;
13990                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13991                            (hasActivities ? " / activities)" : ")"),
13992                            r.processName, myTotalPss, pid, hasActivities);
13993                    procMems.add(pssItem);
13994                    procMemsMap.put(pid, pssItem);
13995
13996                    nativePss += mi.nativePss;
13997                    dalvikPss += mi.dalvikPss;
13998                    otherPss += mi.otherPss;
13999                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14000                        long mem = mi.getOtherPss(j);
14001                        miscPss[j] += mem;
14002                        otherPss -= mem;
14003                    }
14004
14005                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14006                        cachedPss += myTotalPss;
14007                    }
14008
14009                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14010                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14011                                || oomIndex == (oomPss.length-1)) {
14012                            oomPss[oomIndex] += myTotalPss;
14013                            if (oomProcs[oomIndex] == null) {
14014                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14015                            }
14016                            oomProcs[oomIndex].add(pssItem);
14017                            break;
14018                        }
14019                    }
14020                }
14021            }
14022        }
14023
14024        long nativeProcTotalPss = 0;
14025
14026        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14027            // If we are showing aggregations, also look for native processes to
14028            // include so that our aggregations are more accurate.
14029            updateCpuStatsNow();
14030            synchronized (mProcessCpuTracker) {
14031                final int N = mProcessCpuTracker.countStats();
14032                for (int i=0; i<N; i++) {
14033                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14034                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14035                        if (mi == null) {
14036                            mi = new Debug.MemoryInfo();
14037                        }
14038                        if (!brief && !oomOnly) {
14039                            Debug.getMemoryInfo(st.pid, mi);
14040                        } else {
14041                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14042                            mi.nativePrivateDirty = (int)tmpLong[0];
14043                        }
14044
14045                        final long myTotalPss = mi.getTotalPss();
14046                        totalPss += myTotalPss;
14047                        nativeProcTotalPss += myTotalPss;
14048
14049                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14050                                st.name, myTotalPss, st.pid, false);
14051                        procMems.add(pssItem);
14052
14053                        nativePss += mi.nativePss;
14054                        dalvikPss += mi.dalvikPss;
14055                        otherPss += mi.otherPss;
14056                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14057                            long mem = mi.getOtherPss(j);
14058                            miscPss[j] += mem;
14059                            otherPss -= mem;
14060                        }
14061                        oomPss[0] += myTotalPss;
14062                        if (oomProcs[0] == null) {
14063                            oomProcs[0] = new ArrayList<MemItem>();
14064                        }
14065                        oomProcs[0].add(pssItem);
14066                    }
14067                }
14068            }
14069
14070            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14071
14072            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14073            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14074            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14075            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14076                String label = Debug.MemoryInfo.getOtherLabel(j);
14077                catMems.add(new MemItem(label, label, miscPss[j], j));
14078            }
14079
14080            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14081            for (int j=0; j<oomPss.length; j++) {
14082                if (oomPss[j] != 0) {
14083                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14084                            : DUMP_MEM_OOM_LABEL[j];
14085                    MemItem item = new MemItem(label, label, oomPss[j],
14086                            DUMP_MEM_OOM_ADJ[j]);
14087                    item.subitems = oomProcs[j];
14088                    oomMems.add(item);
14089                }
14090            }
14091
14092            if (!brief && !oomOnly && !isCompact) {
14093                pw.println();
14094                pw.println("Total PSS by process:");
14095                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14096                pw.println();
14097            }
14098            if (!isCompact) {
14099                pw.println("Total PSS by OOM adjustment:");
14100            }
14101            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14102            if (!brief && !oomOnly) {
14103                PrintWriter out = categoryPw != null ? categoryPw : pw;
14104                if (!isCompact) {
14105                    out.println();
14106                    out.println("Total PSS by category:");
14107                }
14108                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14109            }
14110            if (!isCompact) {
14111                pw.println();
14112            }
14113            MemInfoReader memInfo = new MemInfoReader();
14114            memInfo.readMemInfo();
14115            if (nativeProcTotalPss > 0) {
14116                synchronized (this) {
14117                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14118                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14119                            memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
14120                }
14121            }
14122            if (!brief) {
14123                if (!isCompact) {
14124                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14125                    pw.print(" kB (status ");
14126                    switch (mLastMemoryLevel) {
14127                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14128                            pw.println("normal)");
14129                            break;
14130                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14131                            pw.println("moderate)");
14132                            break;
14133                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14134                            pw.println("low)");
14135                            break;
14136                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14137                            pw.println("critical)");
14138                            break;
14139                        default:
14140                            pw.print(mLastMemoryLevel);
14141                            pw.println(")");
14142                            break;
14143                    }
14144                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14145                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14146                            pw.print(cachedPss); pw.print(" cached pss + ");
14147                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14148                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14149                } else {
14150                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14151                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14152                            + memInfo.getFreeSizeKb()); pw.print(",");
14153                    pw.println(totalPss - cachedPss);
14154                }
14155            }
14156            if (!isCompact) {
14157                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14158                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14159                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14160                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14161                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14162                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14163                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14164            }
14165            if (!brief) {
14166                if (memInfo.getZramTotalSizeKb() != 0) {
14167                    if (!isCompact) {
14168                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14169                                pw.print(" kB physical used for ");
14170                                pw.print(memInfo.getSwapTotalSizeKb()
14171                                        - memInfo.getSwapFreeSizeKb());
14172                                pw.print(" kB in swap (");
14173                                pw.print(memInfo.getSwapTotalSizeKb());
14174                                pw.println(" kB total swap)");
14175                    } else {
14176                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14177                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14178                                pw.println(memInfo.getSwapFreeSizeKb());
14179                    }
14180                }
14181                final long[] ksm = getKsmInfo();
14182                if (!isCompact) {
14183                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14184                            || ksm[KSM_VOLATILE] != 0) {
14185                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14186                                pw.print(" kB saved from shared ");
14187                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14188                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14189                                pw.print(" kB unshared; ");
14190                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14191                    }
14192                    pw.print("   Tuning: ");
14193                    pw.print(ActivityManager.staticGetMemoryClass());
14194                    pw.print(" (large ");
14195                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14196                    pw.print("), oom ");
14197                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14198                    pw.print(" kB");
14199                    pw.print(", restore limit ");
14200                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14201                    pw.print(" kB");
14202                    if (ActivityManager.isLowRamDeviceStatic()) {
14203                        pw.print(" (low-ram)");
14204                    }
14205                    if (ActivityManager.isHighEndGfx()) {
14206                        pw.print(" (high-end-gfx)");
14207                    }
14208                    pw.println();
14209                } else {
14210                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14211                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14212                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14213                    pw.print("tuning,");
14214                    pw.print(ActivityManager.staticGetMemoryClass());
14215                    pw.print(',');
14216                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14217                    pw.print(',');
14218                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14219                    if (ActivityManager.isLowRamDeviceStatic()) {
14220                        pw.print(",low-ram");
14221                    }
14222                    if (ActivityManager.isHighEndGfx()) {
14223                        pw.print(",high-end-gfx");
14224                    }
14225                    pw.println();
14226                }
14227            }
14228        }
14229    }
14230
14231    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14232            String name) {
14233        sb.append("  ");
14234        sb.append(ProcessList.makeOomAdjString(oomAdj));
14235        sb.append(' ');
14236        sb.append(ProcessList.makeProcStateString(procState));
14237        sb.append(' ');
14238        ProcessList.appendRamKb(sb, pss);
14239        sb.append(" kB: ");
14240        sb.append(name);
14241    }
14242
14243    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14244        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name);
14245        sb.append(" (");
14246        sb.append(mi.pid);
14247        sb.append(") ");
14248        sb.append(mi.adjType);
14249        sb.append('\n');
14250        if (mi.adjReason != null) {
14251            sb.append("                      ");
14252            sb.append(mi.adjReason);
14253            sb.append('\n');
14254        }
14255    }
14256
14257    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14258        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14259        for (int i=0, N=memInfos.size(); i<N; i++) {
14260            ProcessMemInfo mi = memInfos.get(i);
14261            infoMap.put(mi.pid, mi);
14262        }
14263        updateCpuStatsNow();
14264        synchronized (mProcessCpuTracker) {
14265            final int N = mProcessCpuTracker.countStats();
14266            for (int i=0; i<N; i++) {
14267                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14268                if (st.vsize > 0) {
14269                    long pss = Debug.getPss(st.pid, null);
14270                    if (pss > 0) {
14271                        if (infoMap.indexOfKey(st.pid) < 0) {
14272                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14273                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14274                            mi.pss = pss;
14275                            memInfos.add(mi);
14276                        }
14277                    }
14278                }
14279            }
14280        }
14281
14282        long totalPss = 0;
14283        for (int i=0, N=memInfos.size(); i<N; i++) {
14284            ProcessMemInfo mi = memInfos.get(i);
14285            if (mi.pss == 0) {
14286                mi.pss = Debug.getPss(mi.pid, null);
14287            }
14288            totalPss += mi.pss;
14289        }
14290        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14291            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14292                if (lhs.oomAdj != rhs.oomAdj) {
14293                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14294                }
14295                if (lhs.pss != rhs.pss) {
14296                    return lhs.pss < rhs.pss ? 1 : -1;
14297                }
14298                return 0;
14299            }
14300        });
14301
14302        StringBuilder tag = new StringBuilder(128);
14303        StringBuilder stack = new StringBuilder(128);
14304        tag.append("Low on memory -- ");
14305        appendMemBucket(tag, totalPss, "total", false);
14306        appendMemBucket(stack, totalPss, "total", true);
14307
14308        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14309        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14310        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14311
14312        boolean firstLine = true;
14313        int lastOomAdj = Integer.MIN_VALUE;
14314        long extraNativeRam = 0;
14315        long cachedPss = 0;
14316        for (int i=0, N=memInfos.size(); i<N; i++) {
14317            ProcessMemInfo mi = memInfos.get(i);
14318
14319            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14320                cachedPss += mi.pss;
14321            }
14322
14323            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14324                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14325                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14326                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14327                if (lastOomAdj != mi.oomAdj) {
14328                    lastOomAdj = mi.oomAdj;
14329                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14330                        tag.append(" / ");
14331                    }
14332                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14333                        if (firstLine) {
14334                            stack.append(":");
14335                            firstLine = false;
14336                        }
14337                        stack.append("\n\t at ");
14338                    } else {
14339                        stack.append("$");
14340                    }
14341                } else {
14342                    tag.append(" ");
14343                    stack.append("$");
14344                }
14345                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14346                    appendMemBucket(tag, mi.pss, mi.name, false);
14347                }
14348                appendMemBucket(stack, mi.pss, mi.name, true);
14349                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14350                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14351                    stack.append("(");
14352                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14353                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14354                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14355                            stack.append(":");
14356                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14357                        }
14358                    }
14359                    stack.append(")");
14360                }
14361            }
14362
14363            appendMemInfo(fullNativeBuilder, mi);
14364            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14365                // The short form only has native processes that are >= 1MB.
14366                if (mi.pss >= 1000) {
14367                    appendMemInfo(shortNativeBuilder, mi);
14368                } else {
14369                    extraNativeRam += mi.pss;
14370                }
14371            } else {
14372                // Short form has all other details, but if we have collected RAM
14373                // from smaller native processes let's dump a summary of that.
14374                if (extraNativeRam > 0) {
14375                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14376                            -1, extraNativeRam, "(Other native)");
14377                    shortNativeBuilder.append('\n');
14378                    extraNativeRam = 0;
14379                }
14380                appendMemInfo(fullJavaBuilder, mi);
14381            }
14382        }
14383
14384        fullJavaBuilder.append("           ");
14385        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14386        fullJavaBuilder.append(" kB: TOTAL\n");
14387
14388        MemInfoReader memInfo = new MemInfoReader();
14389        memInfo.readMemInfo();
14390        final long[] infos = memInfo.getRawInfo();
14391
14392        StringBuilder memInfoBuilder = new StringBuilder(1024);
14393        Debug.getMemInfo(infos);
14394        memInfoBuilder.append("  MemInfo: ");
14395        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14396        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14397        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14398        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14399        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14400        memInfoBuilder.append("           ");
14401        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14402        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14403        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14404        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14405        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14406            memInfoBuilder.append("  ZRAM: ");
14407            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14408            memInfoBuilder.append(" kB RAM, ");
14409            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14410            memInfoBuilder.append(" kB swap total, ");
14411            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14412            memInfoBuilder.append(" kB swap free\n");
14413        }
14414        final long[] ksm = getKsmInfo();
14415        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14416                || ksm[KSM_VOLATILE] != 0) {
14417            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14418            memInfoBuilder.append(" kB saved from shared ");
14419            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14420            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14421            memInfoBuilder.append(" kB unshared; ");
14422            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14423        }
14424        memInfoBuilder.append("  Free RAM: ");
14425        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14426                + memInfo.getFreeSizeKb());
14427        memInfoBuilder.append(" kB\n");
14428        memInfoBuilder.append("  Used RAM: ");
14429        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14430        memInfoBuilder.append(" kB\n");
14431        memInfoBuilder.append("  Lost RAM: ");
14432        memInfoBuilder.append(memInfo.getTotalSizeKb()
14433                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14434                - memInfo.getKernelUsedSizeKb());
14435        memInfoBuilder.append(" kB\n");
14436        Slog.i(TAG, "Low on memory:");
14437        Slog.i(TAG, shortNativeBuilder.toString());
14438        Slog.i(TAG, fullJavaBuilder.toString());
14439        Slog.i(TAG, memInfoBuilder.toString());
14440
14441        StringBuilder dropBuilder = new StringBuilder(1024);
14442        /*
14443        StringWriter oomSw = new StringWriter();
14444        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14445        StringWriter catSw = new StringWriter();
14446        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14447        String[] emptyArgs = new String[] { };
14448        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14449        oomPw.flush();
14450        String oomString = oomSw.toString();
14451        */
14452        dropBuilder.append("Low on memory:");
14453        dropBuilder.append(stack);
14454        dropBuilder.append('\n');
14455        dropBuilder.append(fullNativeBuilder);
14456        dropBuilder.append(fullJavaBuilder);
14457        dropBuilder.append('\n');
14458        dropBuilder.append(memInfoBuilder);
14459        dropBuilder.append('\n');
14460        /*
14461        dropBuilder.append(oomString);
14462        dropBuilder.append('\n');
14463        */
14464        StringWriter catSw = new StringWriter();
14465        synchronized (ActivityManagerService.this) {
14466            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14467            String[] emptyArgs = new String[] { };
14468            catPw.println();
14469            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14470            catPw.println();
14471            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14472                    false, false, null);
14473            catPw.println();
14474            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14475            catPw.flush();
14476        }
14477        dropBuilder.append(catSw.toString());
14478        addErrorToDropBox("lowmem", null, "system_server", null,
14479                null, tag.toString(), dropBuilder.toString(), null, null);
14480        //Slog.i(TAG, "Sent to dropbox:");
14481        //Slog.i(TAG, dropBuilder.toString());
14482        synchronized (ActivityManagerService.this) {
14483            long now = SystemClock.uptimeMillis();
14484            if (mLastMemUsageReportTime < now) {
14485                mLastMemUsageReportTime = now;
14486            }
14487        }
14488    }
14489
14490    /**
14491     * Searches array of arguments for the specified string
14492     * @param args array of argument strings
14493     * @param value value to search for
14494     * @return true if the value is contained in the array
14495     */
14496    private static boolean scanArgs(String[] args, String value) {
14497        if (args != null) {
14498            for (String arg : args) {
14499                if (value.equals(arg)) {
14500                    return true;
14501                }
14502            }
14503        }
14504        return false;
14505    }
14506
14507    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14508            ContentProviderRecord cpr, boolean always) {
14509        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14510
14511        if (!inLaunching || always) {
14512            synchronized (cpr) {
14513                cpr.launchingApp = null;
14514                cpr.notifyAll();
14515            }
14516            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14517            String names[] = cpr.info.authority.split(";");
14518            for (int j = 0; j < names.length; j++) {
14519                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14520            }
14521        }
14522
14523        for (int i=0; i<cpr.connections.size(); i++) {
14524            ContentProviderConnection conn = cpr.connections.get(i);
14525            if (conn.waiting) {
14526                // If this connection is waiting for the provider, then we don't
14527                // need to mess with its process unless we are always removing
14528                // or for some reason the provider is not currently launching.
14529                if (inLaunching && !always) {
14530                    continue;
14531                }
14532            }
14533            ProcessRecord capp = conn.client;
14534            conn.dead = true;
14535            if (conn.stableCount > 0) {
14536                if (!capp.persistent && capp.thread != null
14537                        && capp.pid != 0
14538                        && capp.pid != MY_PID) {
14539                    capp.kill("depends on provider "
14540                            + cpr.name.flattenToShortString()
14541                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14542                }
14543            } else if (capp.thread != null && conn.provider.provider != null) {
14544                try {
14545                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14546                } catch (RemoteException e) {
14547                }
14548                // In the protocol here, we don't expect the client to correctly
14549                // clean up this connection, we'll just remove it.
14550                cpr.connections.remove(i);
14551                conn.client.conProviders.remove(conn);
14552            }
14553        }
14554
14555        if (inLaunching && always) {
14556            mLaunchingProviders.remove(cpr);
14557        }
14558        return inLaunching;
14559    }
14560
14561    /**
14562     * Main code for cleaning up a process when it has gone away.  This is
14563     * called both as a result of the process dying, or directly when stopping
14564     * a process when running in single process mode.
14565     *
14566     * @return Returns true if the given process has been restarted, so the
14567     * app that was passed in must remain on the process lists.
14568     */
14569    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14570            boolean restarting, boolean allowRestart, int index) {
14571        if (index >= 0) {
14572            removeLruProcessLocked(app);
14573            ProcessList.remove(app.pid);
14574        }
14575
14576        mProcessesToGc.remove(app);
14577        mPendingPssProcesses.remove(app);
14578
14579        // Dismiss any open dialogs.
14580        if (app.crashDialog != null && !app.forceCrashReport) {
14581            app.crashDialog.dismiss();
14582            app.crashDialog = null;
14583        }
14584        if (app.anrDialog != null) {
14585            app.anrDialog.dismiss();
14586            app.anrDialog = null;
14587        }
14588        if (app.waitDialog != null) {
14589            app.waitDialog.dismiss();
14590            app.waitDialog = null;
14591        }
14592
14593        app.crashing = false;
14594        app.notResponding = false;
14595
14596        app.resetPackageList(mProcessStats);
14597        app.unlinkDeathRecipient();
14598        app.makeInactive(mProcessStats);
14599        app.waitingToKill = null;
14600        app.forcingToForeground = null;
14601        updateProcessForegroundLocked(app, false, false);
14602        app.foregroundActivities = false;
14603        app.hasShownUi = false;
14604        app.treatLikeActivity = false;
14605        app.hasAboveClient = false;
14606        app.hasClientActivities = false;
14607
14608        mServices.killServicesLocked(app, allowRestart);
14609
14610        boolean restart = false;
14611
14612        // Remove published content providers.
14613        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14614            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14615            final boolean always = app.bad || !allowRestart;
14616            if (removeDyingProviderLocked(app, cpr, always) || always) {
14617                // We left the provider in the launching list, need to
14618                // restart it.
14619                restart = true;
14620            }
14621
14622            cpr.provider = null;
14623            cpr.proc = null;
14624        }
14625        app.pubProviders.clear();
14626
14627        // Take care of any launching providers waiting for this process.
14628        if (checkAppInLaunchingProvidersLocked(app, false)) {
14629            restart = true;
14630        }
14631
14632        // Unregister from connected content providers.
14633        if (!app.conProviders.isEmpty()) {
14634            for (int i=0; i<app.conProviders.size(); i++) {
14635                ContentProviderConnection conn = app.conProviders.get(i);
14636                conn.provider.connections.remove(conn);
14637            }
14638            app.conProviders.clear();
14639        }
14640
14641        // At this point there may be remaining entries in mLaunchingProviders
14642        // where we were the only one waiting, so they are no longer of use.
14643        // Look for these and clean up if found.
14644        // XXX Commented out for now.  Trying to figure out a way to reproduce
14645        // the actual situation to identify what is actually going on.
14646        if (false) {
14647            for (int i=0; i<mLaunchingProviders.size(); i++) {
14648                ContentProviderRecord cpr = (ContentProviderRecord)
14649                        mLaunchingProviders.get(i);
14650                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14651                    synchronized (cpr) {
14652                        cpr.launchingApp = null;
14653                        cpr.notifyAll();
14654                    }
14655                }
14656            }
14657        }
14658
14659        skipCurrentReceiverLocked(app);
14660
14661        // Unregister any receivers.
14662        for (int i=app.receivers.size()-1; i>=0; i--) {
14663            removeReceiverLocked(app.receivers.valueAt(i));
14664        }
14665        app.receivers.clear();
14666
14667        // If the app is undergoing backup, tell the backup manager about it
14668        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14669            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14670                    + mBackupTarget.appInfo + " died during backup");
14671            try {
14672                IBackupManager bm = IBackupManager.Stub.asInterface(
14673                        ServiceManager.getService(Context.BACKUP_SERVICE));
14674                bm.agentDisconnected(app.info.packageName);
14675            } catch (RemoteException e) {
14676                // can't happen; backup manager is local
14677            }
14678        }
14679
14680        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14681            ProcessChangeItem item = mPendingProcessChanges.get(i);
14682            if (item.pid == app.pid) {
14683                mPendingProcessChanges.remove(i);
14684                mAvailProcessChanges.add(item);
14685            }
14686        }
14687        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14688
14689        // If the caller is restarting this app, then leave it in its
14690        // current lists and let the caller take care of it.
14691        if (restarting) {
14692            return false;
14693        }
14694
14695        if (!app.persistent || app.isolated) {
14696            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14697                    "Removing non-persistent process during cleanup: " + app);
14698            mProcessNames.remove(app.processName, app.uid);
14699            mIsolatedProcesses.remove(app.uid);
14700            if (mHeavyWeightProcess == app) {
14701                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14702                        mHeavyWeightProcess.userId, 0));
14703                mHeavyWeightProcess = null;
14704            }
14705        } else if (!app.removed) {
14706            // This app is persistent, so we need to keep its record around.
14707            // If it is not already on the pending app list, add it there
14708            // and start a new process for it.
14709            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14710                mPersistentStartingProcesses.add(app);
14711                restart = true;
14712            }
14713        }
14714        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14715                "Clean-up removing on hold: " + app);
14716        mProcessesOnHold.remove(app);
14717
14718        if (app == mHomeProcess) {
14719            mHomeProcess = null;
14720        }
14721        if (app == mPreviousProcess) {
14722            mPreviousProcess = null;
14723        }
14724
14725        if (restart && !app.isolated) {
14726            // We have components that still need to be running in the
14727            // process, so re-launch it.
14728            if (index < 0) {
14729                ProcessList.remove(app.pid);
14730            }
14731            mProcessNames.put(app.processName, app.uid, app);
14732            startProcessLocked(app, "restart", app.processName);
14733            return true;
14734        } else if (app.pid > 0 && app.pid != MY_PID) {
14735            // Goodbye!
14736            boolean removed;
14737            synchronized (mPidsSelfLocked) {
14738                mPidsSelfLocked.remove(app.pid);
14739                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14740            }
14741            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14742            if (app.isolated) {
14743                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14744            }
14745            app.setPid(0);
14746        }
14747        return false;
14748    }
14749
14750    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14751        // Look through the content providers we are waiting to have launched,
14752        // and if any run in this process then either schedule a restart of
14753        // the process or kill the client waiting for it if this process has
14754        // gone bad.
14755        int NL = mLaunchingProviders.size();
14756        boolean restart = false;
14757        for (int i=0; i<NL; i++) {
14758            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14759            if (cpr.launchingApp == app) {
14760                if (!alwaysBad && !app.bad) {
14761                    restart = true;
14762                } else {
14763                    removeDyingProviderLocked(app, cpr, true);
14764                    // cpr should have been removed from mLaunchingProviders
14765                    NL = mLaunchingProviders.size();
14766                    i--;
14767                }
14768            }
14769        }
14770        return restart;
14771    }
14772
14773    // =========================================================
14774    // SERVICES
14775    // =========================================================
14776
14777    @Override
14778    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14779            int flags) {
14780        enforceNotIsolatedCaller("getServices");
14781        synchronized (this) {
14782            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14783        }
14784    }
14785
14786    @Override
14787    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14788        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14789        synchronized (this) {
14790            return mServices.getRunningServiceControlPanelLocked(name);
14791        }
14792    }
14793
14794    @Override
14795    public ComponentName startService(IApplicationThread caller, Intent service,
14796            String resolvedType, int userId) {
14797        enforceNotIsolatedCaller("startService");
14798        // Refuse possible leaked file descriptors
14799        if (service != null && service.hasFileDescriptors() == true) {
14800            throw new IllegalArgumentException("File descriptors passed in Intent");
14801        }
14802
14803        if (DEBUG_SERVICE)
14804            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14805        synchronized(this) {
14806            final int callingPid = Binder.getCallingPid();
14807            final int callingUid = Binder.getCallingUid();
14808            final long origId = Binder.clearCallingIdentity();
14809            ComponentName res = mServices.startServiceLocked(caller, service,
14810                    resolvedType, callingPid, callingUid, userId);
14811            Binder.restoreCallingIdentity(origId);
14812            return res;
14813        }
14814    }
14815
14816    ComponentName startServiceInPackage(int uid,
14817            Intent service, String resolvedType, int userId) {
14818        synchronized(this) {
14819            if (DEBUG_SERVICE)
14820                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14821            final long origId = Binder.clearCallingIdentity();
14822            ComponentName res = mServices.startServiceLocked(null, service,
14823                    resolvedType, -1, uid, userId);
14824            Binder.restoreCallingIdentity(origId);
14825            return res;
14826        }
14827    }
14828
14829    @Override
14830    public int stopService(IApplicationThread caller, Intent service,
14831            String resolvedType, int userId) {
14832        enforceNotIsolatedCaller("stopService");
14833        // Refuse possible leaked file descriptors
14834        if (service != null && service.hasFileDescriptors() == true) {
14835            throw new IllegalArgumentException("File descriptors passed in Intent");
14836        }
14837
14838        synchronized(this) {
14839            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14840        }
14841    }
14842
14843    @Override
14844    public IBinder peekService(Intent service, String resolvedType) {
14845        enforceNotIsolatedCaller("peekService");
14846        // Refuse possible leaked file descriptors
14847        if (service != null && service.hasFileDescriptors() == true) {
14848            throw new IllegalArgumentException("File descriptors passed in Intent");
14849        }
14850        synchronized(this) {
14851            return mServices.peekServiceLocked(service, resolvedType);
14852        }
14853    }
14854
14855    @Override
14856    public boolean stopServiceToken(ComponentName className, IBinder token,
14857            int startId) {
14858        synchronized(this) {
14859            return mServices.stopServiceTokenLocked(className, token, startId);
14860        }
14861    }
14862
14863    @Override
14864    public void setServiceForeground(ComponentName className, IBinder token,
14865            int id, Notification notification, boolean removeNotification) {
14866        synchronized(this) {
14867            mServices.setServiceForegroundLocked(className, token, id, notification,
14868                    removeNotification);
14869        }
14870    }
14871
14872    @Override
14873    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14874            boolean requireFull, String name, String callerPackage) {
14875        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14876                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14877    }
14878
14879    int unsafeConvertIncomingUser(int userId) {
14880        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14881                ? mCurrentUserId : userId;
14882    }
14883
14884    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14885            int allowMode, String name, String callerPackage) {
14886        final int callingUserId = UserHandle.getUserId(callingUid);
14887        if (callingUserId == userId) {
14888            return userId;
14889        }
14890
14891        // Note that we may be accessing mCurrentUserId outside of a lock...
14892        // shouldn't be a big deal, if this is being called outside
14893        // of a locked context there is intrinsically a race with
14894        // the value the caller will receive and someone else changing it.
14895        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14896        // we will switch to the calling user if access to the current user fails.
14897        int targetUserId = unsafeConvertIncomingUser(userId);
14898
14899        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14900            final boolean allow;
14901            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14902                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14903                // If the caller has this permission, they always pass go.  And collect $200.
14904                allow = true;
14905            } else if (allowMode == ALLOW_FULL_ONLY) {
14906                // We require full access, sucks to be you.
14907                allow = false;
14908            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14909                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14910                // If the caller does not have either permission, they are always doomed.
14911                allow = false;
14912            } else if (allowMode == ALLOW_NON_FULL) {
14913                // We are blanket allowing non-full access, you lucky caller!
14914                allow = true;
14915            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14916                // We may or may not allow this depending on whether the two users are
14917                // in the same profile.
14918                synchronized (mUserProfileGroupIdsSelfLocked) {
14919                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14920                            UserInfo.NO_PROFILE_GROUP_ID);
14921                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14922                            UserInfo.NO_PROFILE_GROUP_ID);
14923                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14924                            && callingProfile == targetProfile;
14925                }
14926            } else {
14927                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14928            }
14929            if (!allow) {
14930                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14931                    // In this case, they would like to just execute as their
14932                    // owner user instead of failing.
14933                    targetUserId = callingUserId;
14934                } else {
14935                    StringBuilder builder = new StringBuilder(128);
14936                    builder.append("Permission Denial: ");
14937                    builder.append(name);
14938                    if (callerPackage != null) {
14939                        builder.append(" from ");
14940                        builder.append(callerPackage);
14941                    }
14942                    builder.append(" asks to run as user ");
14943                    builder.append(userId);
14944                    builder.append(" but is calling from user ");
14945                    builder.append(UserHandle.getUserId(callingUid));
14946                    builder.append("; this requires ");
14947                    builder.append(INTERACT_ACROSS_USERS_FULL);
14948                    if (allowMode != ALLOW_FULL_ONLY) {
14949                        builder.append(" or ");
14950                        builder.append(INTERACT_ACROSS_USERS);
14951                    }
14952                    String msg = builder.toString();
14953                    Slog.w(TAG, msg);
14954                    throw new SecurityException(msg);
14955                }
14956            }
14957        }
14958        if (!allowAll && targetUserId < 0) {
14959            throw new IllegalArgumentException(
14960                    "Call does not support special user #" + targetUserId);
14961        }
14962        // Check shell permission
14963        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14964            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14965                    targetUserId)) {
14966                throw new SecurityException("Shell does not have permission to access user "
14967                        + targetUserId + "\n " + Debug.getCallers(3));
14968            }
14969        }
14970        return targetUserId;
14971    }
14972
14973    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14974            String className, int flags) {
14975        boolean result = false;
14976        // For apps that don't have pre-defined UIDs, check for permission
14977        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14978            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14979                if (ActivityManager.checkUidPermission(
14980                        INTERACT_ACROSS_USERS,
14981                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14982                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14983                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14984                            + " requests FLAG_SINGLE_USER, but app does not hold "
14985                            + INTERACT_ACROSS_USERS;
14986                    Slog.w(TAG, msg);
14987                    throw new SecurityException(msg);
14988                }
14989                // Permission passed
14990                result = true;
14991            }
14992        } else if ("system".equals(componentProcessName)) {
14993            result = true;
14994        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14995            // Phone app and persistent apps are allowed to export singleuser providers.
14996            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14997                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14998        }
14999        if (DEBUG_MU) {
15000            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
15001                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
15002        }
15003        return result;
15004    }
15005
15006    /**
15007     * Checks to see if the caller is in the same app as the singleton
15008     * component, or the component is in a special app. It allows special apps
15009     * to export singleton components but prevents exporting singleton
15010     * components for regular apps.
15011     */
15012    boolean isValidSingletonCall(int callingUid, int componentUid) {
15013        int componentAppId = UserHandle.getAppId(componentUid);
15014        return UserHandle.isSameApp(callingUid, componentUid)
15015                || componentAppId == Process.SYSTEM_UID
15016                || componentAppId == Process.PHONE_UID
15017                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15018                        == PackageManager.PERMISSION_GRANTED;
15019    }
15020
15021    public int bindService(IApplicationThread caller, IBinder token,
15022            Intent service, String resolvedType,
15023            IServiceConnection connection, int flags, int userId) {
15024        enforceNotIsolatedCaller("bindService");
15025
15026        // Refuse possible leaked file descriptors
15027        if (service != null && service.hasFileDescriptors() == true) {
15028            throw new IllegalArgumentException("File descriptors passed in Intent");
15029        }
15030
15031        synchronized(this) {
15032            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15033                    connection, flags, userId);
15034        }
15035    }
15036
15037    public boolean unbindService(IServiceConnection connection) {
15038        synchronized (this) {
15039            return mServices.unbindServiceLocked(connection);
15040        }
15041    }
15042
15043    public void publishService(IBinder token, Intent intent, IBinder service) {
15044        // Refuse possible leaked file descriptors
15045        if (intent != null && intent.hasFileDescriptors() == true) {
15046            throw new IllegalArgumentException("File descriptors passed in Intent");
15047        }
15048
15049        synchronized(this) {
15050            if (!(token instanceof ServiceRecord)) {
15051                throw new IllegalArgumentException("Invalid service token");
15052            }
15053            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15054        }
15055    }
15056
15057    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15058        // Refuse possible leaked file descriptors
15059        if (intent != null && intent.hasFileDescriptors() == true) {
15060            throw new IllegalArgumentException("File descriptors passed in Intent");
15061        }
15062
15063        synchronized(this) {
15064            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15065        }
15066    }
15067
15068    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15069        synchronized(this) {
15070            if (!(token instanceof ServiceRecord)) {
15071                throw new IllegalArgumentException("Invalid service token");
15072            }
15073            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15074        }
15075    }
15076
15077    // =========================================================
15078    // BACKUP AND RESTORE
15079    // =========================================================
15080
15081    // Cause the target app to be launched if necessary and its backup agent
15082    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15083    // activity manager to announce its creation.
15084    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15085        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
15086        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15087
15088        synchronized(this) {
15089            // !!! TODO: currently no check here that we're already bound
15090            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15091            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15092            synchronized (stats) {
15093                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15094            }
15095
15096            // Backup agent is now in use, its package can't be stopped.
15097            try {
15098                AppGlobals.getPackageManager().setPackageStoppedState(
15099                        app.packageName, false, UserHandle.getUserId(app.uid));
15100            } catch (RemoteException e) {
15101            } catch (IllegalArgumentException e) {
15102                Slog.w(TAG, "Failed trying to unstop package "
15103                        + app.packageName + ": " + e);
15104            }
15105
15106            BackupRecord r = new BackupRecord(ss, app, backupMode);
15107            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15108                    ? new ComponentName(app.packageName, app.backupAgentName)
15109                    : new ComponentName("android", "FullBackupAgent");
15110            // startProcessLocked() returns existing proc's record if it's already running
15111            ProcessRecord proc = startProcessLocked(app.processName, app,
15112                    false, 0, "backup", hostingName, false, false, false);
15113            if (proc == null) {
15114                Slog.e(TAG, "Unable to start backup agent process " + r);
15115                return false;
15116            }
15117
15118            r.app = proc;
15119            mBackupTarget = r;
15120            mBackupAppName = app.packageName;
15121
15122            // Try not to kill the process during backup
15123            updateOomAdjLocked(proc);
15124
15125            // If the process is already attached, schedule the creation of the backup agent now.
15126            // If it is not yet live, this will be done when it attaches to the framework.
15127            if (proc.thread != null) {
15128                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15129                try {
15130                    proc.thread.scheduleCreateBackupAgent(app,
15131                            compatibilityInfoForPackageLocked(app), backupMode);
15132                } catch (RemoteException e) {
15133                    // Will time out on the backup manager side
15134                }
15135            } else {
15136                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15137            }
15138            // Invariants: at this point, the target app process exists and the application
15139            // is either already running or in the process of coming up.  mBackupTarget and
15140            // mBackupAppName describe the app, so that when it binds back to the AM we
15141            // know that it's scheduled for a backup-agent operation.
15142        }
15143
15144        return true;
15145    }
15146
15147    @Override
15148    public void clearPendingBackup() {
15149        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15150        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15151
15152        synchronized (this) {
15153            mBackupTarget = null;
15154            mBackupAppName = null;
15155        }
15156    }
15157
15158    // A backup agent has just come up
15159    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15160        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15161                + " = " + agent);
15162
15163        synchronized(this) {
15164            if (!agentPackageName.equals(mBackupAppName)) {
15165                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15166                return;
15167            }
15168        }
15169
15170        long oldIdent = Binder.clearCallingIdentity();
15171        try {
15172            IBackupManager bm = IBackupManager.Stub.asInterface(
15173                    ServiceManager.getService(Context.BACKUP_SERVICE));
15174            bm.agentConnected(agentPackageName, agent);
15175        } catch (RemoteException e) {
15176            // can't happen; the backup manager service is local
15177        } catch (Exception e) {
15178            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15179            e.printStackTrace();
15180        } finally {
15181            Binder.restoreCallingIdentity(oldIdent);
15182        }
15183    }
15184
15185    // done with this agent
15186    public void unbindBackupAgent(ApplicationInfo appInfo) {
15187        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15188        if (appInfo == null) {
15189            Slog.w(TAG, "unbind backup agent for null app");
15190            return;
15191        }
15192
15193        synchronized(this) {
15194            try {
15195                if (mBackupAppName == null) {
15196                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15197                    return;
15198                }
15199
15200                if (!mBackupAppName.equals(appInfo.packageName)) {
15201                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15202                    return;
15203                }
15204
15205                // Not backing this app up any more; reset its OOM adjustment
15206                final ProcessRecord proc = mBackupTarget.app;
15207                updateOomAdjLocked(proc);
15208
15209                // If the app crashed during backup, 'thread' will be null here
15210                if (proc.thread != null) {
15211                    try {
15212                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15213                                compatibilityInfoForPackageLocked(appInfo));
15214                    } catch (Exception e) {
15215                        Slog.e(TAG, "Exception when unbinding backup agent:");
15216                        e.printStackTrace();
15217                    }
15218                }
15219            } finally {
15220                mBackupTarget = null;
15221                mBackupAppName = null;
15222            }
15223        }
15224    }
15225    // =========================================================
15226    // BROADCASTS
15227    // =========================================================
15228
15229    private final List getStickiesLocked(String action, IntentFilter filter,
15230            List cur, int userId) {
15231        final ContentResolver resolver = mContext.getContentResolver();
15232        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15233        if (stickies == null) {
15234            return cur;
15235        }
15236        final ArrayList<Intent> list = stickies.get(action);
15237        if (list == null) {
15238            return cur;
15239        }
15240        int N = list.size();
15241        for (int i=0; i<N; i++) {
15242            Intent intent = list.get(i);
15243            if (filter.match(resolver, intent, true, TAG) >= 0) {
15244                if (cur == null) {
15245                    cur = new ArrayList<Intent>();
15246                }
15247                cur.add(intent);
15248            }
15249        }
15250        return cur;
15251    }
15252
15253    boolean isPendingBroadcastProcessLocked(int pid) {
15254        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15255                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15256    }
15257
15258    void skipPendingBroadcastLocked(int pid) {
15259            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15260            for (BroadcastQueue queue : mBroadcastQueues) {
15261                queue.skipPendingBroadcastLocked(pid);
15262            }
15263    }
15264
15265    // The app just attached; send any pending broadcasts that it should receive
15266    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15267        boolean didSomething = false;
15268        for (BroadcastQueue queue : mBroadcastQueues) {
15269            didSomething |= queue.sendPendingBroadcastsLocked(app);
15270        }
15271        return didSomething;
15272    }
15273
15274    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15275            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15276        enforceNotIsolatedCaller("registerReceiver");
15277        int callingUid;
15278        int callingPid;
15279        synchronized(this) {
15280            ProcessRecord callerApp = null;
15281            if (caller != null) {
15282                callerApp = getRecordForAppLocked(caller);
15283                if (callerApp == null) {
15284                    throw new SecurityException(
15285                            "Unable to find app for caller " + caller
15286                            + " (pid=" + Binder.getCallingPid()
15287                            + ") when registering receiver " + receiver);
15288                }
15289                if (callerApp.info.uid != Process.SYSTEM_UID &&
15290                        !callerApp.pkgList.containsKey(callerPackage) &&
15291                        !"android".equals(callerPackage)) {
15292                    throw new SecurityException("Given caller package " + callerPackage
15293                            + " is not running in process " + callerApp);
15294                }
15295                callingUid = callerApp.info.uid;
15296                callingPid = callerApp.pid;
15297            } else {
15298                callerPackage = null;
15299                callingUid = Binder.getCallingUid();
15300                callingPid = Binder.getCallingPid();
15301            }
15302
15303            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15304                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15305
15306            List allSticky = null;
15307
15308            // Look for any matching sticky broadcasts...
15309            Iterator actions = filter.actionsIterator();
15310            if (actions != null) {
15311                while (actions.hasNext()) {
15312                    String action = (String)actions.next();
15313                    allSticky = getStickiesLocked(action, filter, allSticky,
15314                            UserHandle.USER_ALL);
15315                    allSticky = getStickiesLocked(action, filter, allSticky,
15316                            UserHandle.getUserId(callingUid));
15317                }
15318            } else {
15319                allSticky = getStickiesLocked(null, filter, allSticky,
15320                        UserHandle.USER_ALL);
15321                allSticky = getStickiesLocked(null, filter, allSticky,
15322                        UserHandle.getUserId(callingUid));
15323            }
15324
15325            // The first sticky in the list is returned directly back to
15326            // the client.
15327            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15328
15329            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15330                    + ": " + sticky);
15331
15332            if (receiver == null) {
15333                return sticky;
15334            }
15335
15336            ReceiverList rl
15337                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15338            if (rl == null) {
15339                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15340                        userId, receiver);
15341                if (rl.app != null) {
15342                    rl.app.receivers.add(rl);
15343                } else {
15344                    try {
15345                        receiver.asBinder().linkToDeath(rl, 0);
15346                    } catch (RemoteException e) {
15347                        return sticky;
15348                    }
15349                    rl.linkedToDeath = true;
15350                }
15351                mRegisteredReceivers.put(receiver.asBinder(), rl);
15352            } else if (rl.uid != callingUid) {
15353                throw new IllegalArgumentException(
15354                        "Receiver requested to register for uid " + callingUid
15355                        + " was previously registered for uid " + rl.uid);
15356            } else if (rl.pid != callingPid) {
15357                throw new IllegalArgumentException(
15358                        "Receiver requested to register for pid " + callingPid
15359                        + " was previously registered for pid " + rl.pid);
15360            } else if (rl.userId != userId) {
15361                throw new IllegalArgumentException(
15362                        "Receiver requested to register for user " + userId
15363                        + " was previously registered for user " + rl.userId);
15364            }
15365            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15366                    permission, callingUid, userId);
15367            rl.add(bf);
15368            if (!bf.debugCheck()) {
15369                Slog.w(TAG, "==> For Dynamic broadast");
15370            }
15371            mReceiverResolver.addFilter(bf);
15372
15373            // Enqueue broadcasts for all existing stickies that match
15374            // this filter.
15375            if (allSticky != null) {
15376                ArrayList receivers = new ArrayList();
15377                receivers.add(bf);
15378
15379                int N = allSticky.size();
15380                for (int i=0; i<N; i++) {
15381                    Intent intent = (Intent)allSticky.get(i);
15382                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15383                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15384                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15385                            null, null, false, true, true, -1);
15386                    queue.enqueueParallelBroadcastLocked(r);
15387                    queue.scheduleBroadcastsLocked();
15388                }
15389            }
15390
15391            return sticky;
15392        }
15393    }
15394
15395    public void unregisterReceiver(IIntentReceiver receiver) {
15396        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15397
15398        final long origId = Binder.clearCallingIdentity();
15399        try {
15400            boolean doTrim = false;
15401
15402            synchronized(this) {
15403                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15404                if (rl != null) {
15405                    if (rl.curBroadcast != null) {
15406                        BroadcastRecord r = rl.curBroadcast;
15407                        final boolean doNext = finishReceiverLocked(
15408                                receiver.asBinder(), r.resultCode, r.resultData,
15409                                r.resultExtras, r.resultAbort);
15410                        if (doNext) {
15411                            doTrim = true;
15412                            r.queue.processNextBroadcast(false);
15413                        }
15414                    }
15415
15416                    if (rl.app != null) {
15417                        rl.app.receivers.remove(rl);
15418                    }
15419                    removeReceiverLocked(rl);
15420                    if (rl.linkedToDeath) {
15421                        rl.linkedToDeath = false;
15422                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15423                    }
15424                }
15425            }
15426
15427            // If we actually concluded any broadcasts, we might now be able
15428            // to trim the recipients' apps from our working set
15429            if (doTrim) {
15430                trimApplications();
15431                return;
15432            }
15433
15434        } finally {
15435            Binder.restoreCallingIdentity(origId);
15436        }
15437    }
15438
15439    void removeReceiverLocked(ReceiverList rl) {
15440        mRegisteredReceivers.remove(rl.receiver.asBinder());
15441        int N = rl.size();
15442        for (int i=0; i<N; i++) {
15443            mReceiverResolver.removeFilter(rl.get(i));
15444        }
15445    }
15446
15447    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15448        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15449            ProcessRecord r = mLruProcesses.get(i);
15450            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15451                try {
15452                    r.thread.dispatchPackageBroadcast(cmd, packages);
15453                } catch (RemoteException ex) {
15454                }
15455            }
15456        }
15457    }
15458
15459    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15460            int callingUid, int[] users) {
15461        List<ResolveInfo> receivers = null;
15462        try {
15463            HashSet<ComponentName> singleUserReceivers = null;
15464            boolean scannedFirstReceivers = false;
15465            for (int user : users) {
15466                // Skip users that have Shell restrictions
15467                if (callingUid == Process.SHELL_UID
15468                        && getUserManagerLocked().hasUserRestriction(
15469                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15470                    continue;
15471                }
15472                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15473                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15474                if (user != 0 && newReceivers != null) {
15475                    // If this is not the primary user, we need to check for
15476                    // any receivers that should be filtered out.
15477                    for (int i=0; i<newReceivers.size(); i++) {
15478                        ResolveInfo ri = newReceivers.get(i);
15479                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15480                            newReceivers.remove(i);
15481                            i--;
15482                        }
15483                    }
15484                }
15485                if (newReceivers != null && newReceivers.size() == 0) {
15486                    newReceivers = null;
15487                }
15488                if (receivers == null) {
15489                    receivers = newReceivers;
15490                } else if (newReceivers != null) {
15491                    // We need to concatenate the additional receivers
15492                    // found with what we have do far.  This would be easy,
15493                    // but we also need to de-dup any receivers that are
15494                    // singleUser.
15495                    if (!scannedFirstReceivers) {
15496                        // Collect any single user receivers we had already retrieved.
15497                        scannedFirstReceivers = true;
15498                        for (int i=0; i<receivers.size(); i++) {
15499                            ResolveInfo ri = receivers.get(i);
15500                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15501                                ComponentName cn = new ComponentName(
15502                                        ri.activityInfo.packageName, ri.activityInfo.name);
15503                                if (singleUserReceivers == null) {
15504                                    singleUserReceivers = new HashSet<ComponentName>();
15505                                }
15506                                singleUserReceivers.add(cn);
15507                            }
15508                        }
15509                    }
15510                    // Add the new results to the existing results, tracking
15511                    // and de-dupping single user receivers.
15512                    for (int i=0; i<newReceivers.size(); i++) {
15513                        ResolveInfo ri = newReceivers.get(i);
15514                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15515                            ComponentName cn = new ComponentName(
15516                                    ri.activityInfo.packageName, ri.activityInfo.name);
15517                            if (singleUserReceivers == null) {
15518                                singleUserReceivers = new HashSet<ComponentName>();
15519                            }
15520                            if (!singleUserReceivers.contains(cn)) {
15521                                singleUserReceivers.add(cn);
15522                                receivers.add(ri);
15523                            }
15524                        } else {
15525                            receivers.add(ri);
15526                        }
15527                    }
15528                }
15529            }
15530        } catch (RemoteException ex) {
15531            // pm is in same process, this will never happen.
15532        }
15533        return receivers;
15534    }
15535
15536    private final int broadcastIntentLocked(ProcessRecord callerApp,
15537            String callerPackage, Intent intent, String resolvedType,
15538            IIntentReceiver resultTo, int resultCode, String resultData,
15539            Bundle map, String requiredPermission, int appOp,
15540            boolean ordered, boolean sticky, int callingPid, int callingUid,
15541            int userId) {
15542        intent = new Intent(intent);
15543
15544        // By default broadcasts do not go to stopped apps.
15545        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15546
15547        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15548            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15549            + " ordered=" + ordered + " userid=" + userId);
15550        if ((resultTo != null) && !ordered) {
15551            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15552        }
15553
15554        userId = handleIncomingUser(callingPid, callingUid, userId,
15555                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15556
15557        // Make sure that the user who is receiving this broadcast is started.
15558        // If not, we will just skip it.
15559
15560        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15561            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15562                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15563                Slog.w(TAG, "Skipping broadcast of " + intent
15564                        + ": user " + userId + " is stopped");
15565                return ActivityManager.BROADCAST_SUCCESS;
15566            }
15567        }
15568
15569        /*
15570         * Prevent non-system code (defined here to be non-persistent
15571         * processes) from sending protected broadcasts.
15572         */
15573        int callingAppId = UserHandle.getAppId(callingUid);
15574        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15575            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15576            || callingAppId == Process.NFC_UID || callingUid == 0) {
15577            // Always okay.
15578        } else if (callerApp == null || !callerApp.persistent) {
15579            try {
15580                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15581                        intent.getAction())) {
15582                    String msg = "Permission Denial: not allowed to send broadcast "
15583                            + intent.getAction() + " from pid="
15584                            + callingPid + ", uid=" + callingUid;
15585                    Slog.w(TAG, msg);
15586                    throw new SecurityException(msg);
15587                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15588                    // Special case for compatibility: we don't want apps to send this,
15589                    // but historically it has not been protected and apps may be using it
15590                    // to poke their own app widget.  So, instead of making it protected,
15591                    // just limit it to the caller.
15592                    if (callerApp == null) {
15593                        String msg = "Permission Denial: not allowed to send broadcast "
15594                                + intent.getAction() + " from unknown caller.";
15595                        Slog.w(TAG, msg);
15596                        throw new SecurityException(msg);
15597                    } else if (intent.getComponent() != null) {
15598                        // They are good enough to send to an explicit component...  verify
15599                        // it is being sent to the calling app.
15600                        if (!intent.getComponent().getPackageName().equals(
15601                                callerApp.info.packageName)) {
15602                            String msg = "Permission Denial: not allowed to send broadcast "
15603                                    + intent.getAction() + " to "
15604                                    + intent.getComponent().getPackageName() + " from "
15605                                    + callerApp.info.packageName;
15606                            Slog.w(TAG, msg);
15607                            throw new SecurityException(msg);
15608                        }
15609                    } else {
15610                        // Limit broadcast to their own package.
15611                        intent.setPackage(callerApp.info.packageName);
15612                    }
15613                }
15614            } catch (RemoteException e) {
15615                Slog.w(TAG, "Remote exception", e);
15616                return ActivityManager.BROADCAST_SUCCESS;
15617            }
15618        }
15619
15620        // Handle special intents: if this broadcast is from the package
15621        // manager about a package being removed, we need to remove all of
15622        // its activities from the history stack.
15623        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15624                intent.getAction());
15625        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15626                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15627                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15628                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15629                || uidRemoved) {
15630            if (checkComponentPermission(
15631                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15632                    callingPid, callingUid, -1, true)
15633                    == PackageManager.PERMISSION_GRANTED) {
15634                if (uidRemoved) {
15635                    final Bundle intentExtras = intent.getExtras();
15636                    final int uid = intentExtras != null
15637                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15638                    if (uid >= 0) {
15639                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15640                        synchronized (bs) {
15641                            bs.removeUidStatsLocked(uid);
15642                        }
15643                        mAppOpsService.uidRemoved(uid);
15644                    }
15645                } else {
15646                    // If resources are unavailable just force stop all
15647                    // those packages and flush the attribute cache as well.
15648                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15649                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15650                        if (list != null && (list.length > 0)) {
15651                            for (String pkg : list) {
15652                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15653                                        "storage unmount");
15654                            }
15655                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15656                            sendPackageBroadcastLocked(
15657                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15658                        }
15659                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15660                            intent.getAction())) {
15661                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15662                    } else {
15663                        Uri data = intent.getData();
15664                        String ssp;
15665                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15666                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15667                                    intent.getAction());
15668                            boolean fullUninstall = removed &&
15669                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15670                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15671                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15672                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15673                                        false, fullUninstall, userId,
15674                                        removed ? "pkg removed" : "pkg changed");
15675                            }
15676                            if (removed) {
15677                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15678                                        new String[] {ssp}, userId);
15679                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15680                                    mAppOpsService.packageRemoved(
15681                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15682
15683                                    // Remove all permissions granted from/to this package
15684                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15685                                }
15686                            }
15687                        }
15688                    }
15689                }
15690            } else {
15691                String msg = "Permission Denial: " + intent.getAction()
15692                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15693                        + ", uid=" + callingUid + ")"
15694                        + " requires "
15695                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15696                Slog.w(TAG, msg);
15697                throw new SecurityException(msg);
15698            }
15699
15700        // Special case for adding a package: by default turn on compatibility
15701        // mode.
15702        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15703            Uri data = intent.getData();
15704            String ssp;
15705            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15706                mCompatModePackages.handlePackageAddedLocked(ssp,
15707                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15708            }
15709        }
15710
15711        /*
15712         * If this is the time zone changed action, queue up a message that will reset the timezone
15713         * of all currently running processes. This message will get queued up before the broadcast
15714         * happens.
15715         */
15716        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15717            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15718        }
15719
15720        /*
15721         * If the user set the time, let all running processes know.
15722         */
15723        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15724            final int is24Hour = intent.getBooleanExtra(
15725                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15726            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15727            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15728            synchronized (stats) {
15729                stats.noteCurrentTimeChangedLocked();
15730            }
15731        }
15732
15733        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15734            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15735        }
15736
15737        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15738            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15739            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15740        }
15741
15742        // Add to the sticky list if requested.
15743        if (sticky) {
15744            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15745                    callingPid, callingUid)
15746                    != PackageManager.PERMISSION_GRANTED) {
15747                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15748                        + callingPid + ", uid=" + callingUid
15749                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15750                Slog.w(TAG, msg);
15751                throw new SecurityException(msg);
15752            }
15753            if (requiredPermission != null) {
15754                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15755                        + " and enforce permission " + requiredPermission);
15756                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15757            }
15758            if (intent.getComponent() != null) {
15759                throw new SecurityException(
15760                        "Sticky broadcasts can't target a specific component");
15761            }
15762            // We use userId directly here, since the "all" target is maintained
15763            // as a separate set of sticky broadcasts.
15764            if (userId != UserHandle.USER_ALL) {
15765                // But first, if this is not a broadcast to all users, then
15766                // make sure it doesn't conflict with an existing broadcast to
15767                // all users.
15768                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15769                        UserHandle.USER_ALL);
15770                if (stickies != null) {
15771                    ArrayList<Intent> list = stickies.get(intent.getAction());
15772                    if (list != null) {
15773                        int N = list.size();
15774                        int i;
15775                        for (i=0; i<N; i++) {
15776                            if (intent.filterEquals(list.get(i))) {
15777                                throw new IllegalArgumentException(
15778                                        "Sticky broadcast " + intent + " for user "
15779                                        + userId + " conflicts with existing global broadcast");
15780                            }
15781                        }
15782                    }
15783                }
15784            }
15785            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15786            if (stickies == null) {
15787                stickies = new ArrayMap<String, ArrayList<Intent>>();
15788                mStickyBroadcasts.put(userId, stickies);
15789            }
15790            ArrayList<Intent> list = stickies.get(intent.getAction());
15791            if (list == null) {
15792                list = new ArrayList<Intent>();
15793                stickies.put(intent.getAction(), list);
15794            }
15795            int N = list.size();
15796            int i;
15797            for (i=0; i<N; i++) {
15798                if (intent.filterEquals(list.get(i))) {
15799                    // This sticky already exists, replace it.
15800                    list.set(i, new Intent(intent));
15801                    break;
15802                }
15803            }
15804            if (i >= N) {
15805                list.add(new Intent(intent));
15806            }
15807        }
15808
15809        int[] users;
15810        if (userId == UserHandle.USER_ALL) {
15811            // Caller wants broadcast to go to all started users.
15812            users = mStartedUserArray;
15813        } else {
15814            // Caller wants broadcast to go to one specific user.
15815            users = new int[] {userId};
15816        }
15817
15818        // Figure out who all will receive this broadcast.
15819        List receivers = null;
15820        List<BroadcastFilter> registeredReceivers = null;
15821        // Need to resolve the intent to interested receivers...
15822        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15823                 == 0) {
15824            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15825        }
15826        if (intent.getComponent() == null) {
15827            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15828                // Query one target user at a time, excluding shell-restricted users
15829                UserManagerService ums = getUserManagerLocked();
15830                for (int i = 0; i < users.length; i++) {
15831                    if (ums.hasUserRestriction(
15832                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15833                        continue;
15834                    }
15835                    List<BroadcastFilter> registeredReceiversForUser =
15836                            mReceiverResolver.queryIntent(intent,
15837                                    resolvedType, false, users[i]);
15838                    if (registeredReceivers == null) {
15839                        registeredReceivers = registeredReceiversForUser;
15840                    } else if (registeredReceiversForUser != null) {
15841                        registeredReceivers.addAll(registeredReceiversForUser);
15842                    }
15843                }
15844            } else {
15845                registeredReceivers = mReceiverResolver.queryIntent(intent,
15846                        resolvedType, false, userId);
15847            }
15848        }
15849
15850        final boolean replacePending =
15851                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15852
15853        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15854                + " replacePending=" + replacePending);
15855
15856        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15857        if (!ordered && NR > 0) {
15858            // If we are not serializing this broadcast, then send the
15859            // registered receivers separately so they don't wait for the
15860            // components to be launched.
15861            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15862            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15863                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15864                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15865                    ordered, sticky, false, userId);
15866            if (DEBUG_BROADCAST) Slog.v(
15867                    TAG, "Enqueueing parallel broadcast " + r);
15868            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15869            if (!replaced) {
15870                queue.enqueueParallelBroadcastLocked(r);
15871                queue.scheduleBroadcastsLocked();
15872            }
15873            registeredReceivers = null;
15874            NR = 0;
15875        }
15876
15877        // Merge into one list.
15878        int ir = 0;
15879        if (receivers != null) {
15880            // A special case for PACKAGE_ADDED: do not allow the package
15881            // being added to see this broadcast.  This prevents them from
15882            // using this as a back door to get run as soon as they are
15883            // installed.  Maybe in the future we want to have a special install
15884            // broadcast or such for apps, but we'd like to deliberately make
15885            // this decision.
15886            String skipPackages[] = null;
15887            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15888                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15889                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15890                Uri data = intent.getData();
15891                if (data != null) {
15892                    String pkgName = data.getSchemeSpecificPart();
15893                    if (pkgName != null) {
15894                        skipPackages = new String[] { pkgName };
15895                    }
15896                }
15897            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15898                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15899            }
15900            if (skipPackages != null && (skipPackages.length > 0)) {
15901                for (String skipPackage : skipPackages) {
15902                    if (skipPackage != null) {
15903                        int NT = receivers.size();
15904                        for (int it=0; it<NT; it++) {
15905                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15906                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15907                                receivers.remove(it);
15908                                it--;
15909                                NT--;
15910                            }
15911                        }
15912                    }
15913                }
15914            }
15915
15916            int NT = receivers != null ? receivers.size() : 0;
15917            int it = 0;
15918            ResolveInfo curt = null;
15919            BroadcastFilter curr = null;
15920            while (it < NT && ir < NR) {
15921                if (curt == null) {
15922                    curt = (ResolveInfo)receivers.get(it);
15923                }
15924                if (curr == null) {
15925                    curr = registeredReceivers.get(ir);
15926                }
15927                if (curr.getPriority() >= curt.priority) {
15928                    // Insert this broadcast record into the final list.
15929                    receivers.add(it, curr);
15930                    ir++;
15931                    curr = null;
15932                    it++;
15933                    NT++;
15934                } else {
15935                    // Skip to the next ResolveInfo in the final list.
15936                    it++;
15937                    curt = null;
15938                }
15939            }
15940        }
15941        while (ir < NR) {
15942            if (receivers == null) {
15943                receivers = new ArrayList();
15944            }
15945            receivers.add(registeredReceivers.get(ir));
15946            ir++;
15947        }
15948
15949        if ((receivers != null && receivers.size() > 0)
15950                || resultTo != null) {
15951            BroadcastQueue queue = broadcastQueueForIntent(intent);
15952            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15953                    callerPackage, callingPid, callingUid, resolvedType,
15954                    requiredPermission, appOp, receivers, resultTo, resultCode,
15955                    resultData, map, ordered, sticky, false, userId);
15956            if (DEBUG_BROADCAST) Slog.v(
15957                    TAG, "Enqueueing ordered broadcast " + r
15958                    + ": prev had " + queue.mOrderedBroadcasts.size());
15959            if (DEBUG_BROADCAST) {
15960                int seq = r.intent.getIntExtra("seq", -1);
15961                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15962            }
15963            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15964            if (!replaced) {
15965                queue.enqueueOrderedBroadcastLocked(r);
15966                queue.scheduleBroadcastsLocked();
15967            }
15968        }
15969
15970        return ActivityManager.BROADCAST_SUCCESS;
15971    }
15972
15973    final Intent verifyBroadcastLocked(Intent intent) {
15974        // Refuse possible leaked file descriptors
15975        if (intent != null && intent.hasFileDescriptors() == true) {
15976            throw new IllegalArgumentException("File descriptors passed in Intent");
15977        }
15978
15979        int flags = intent.getFlags();
15980
15981        if (!mProcessesReady) {
15982            // if the caller really truly claims to know what they're doing, go
15983            // ahead and allow the broadcast without launching any receivers
15984            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15985                intent = new Intent(intent);
15986                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15987            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15988                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15989                        + " before boot completion");
15990                throw new IllegalStateException("Cannot broadcast before boot completed");
15991            }
15992        }
15993
15994        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15995            throw new IllegalArgumentException(
15996                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15997        }
15998
15999        return intent;
16000    }
16001
16002    public final int broadcastIntent(IApplicationThread caller,
16003            Intent intent, String resolvedType, IIntentReceiver resultTo,
16004            int resultCode, String resultData, Bundle map,
16005            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16006        enforceNotIsolatedCaller("broadcastIntent");
16007        synchronized(this) {
16008            intent = verifyBroadcastLocked(intent);
16009
16010            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16011            final int callingPid = Binder.getCallingPid();
16012            final int callingUid = Binder.getCallingUid();
16013            final long origId = Binder.clearCallingIdentity();
16014            int res = broadcastIntentLocked(callerApp,
16015                    callerApp != null ? callerApp.info.packageName : null,
16016                    intent, resolvedType, resultTo,
16017                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16018                    callingPid, callingUid, userId);
16019            Binder.restoreCallingIdentity(origId);
16020            return res;
16021        }
16022    }
16023
16024    int broadcastIntentInPackage(String packageName, int uid,
16025            Intent intent, String resolvedType, IIntentReceiver resultTo,
16026            int resultCode, String resultData, Bundle map,
16027            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16028        synchronized(this) {
16029            intent = verifyBroadcastLocked(intent);
16030
16031            final long origId = Binder.clearCallingIdentity();
16032            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16033                    resultTo, resultCode, resultData, map, requiredPermission,
16034                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16035            Binder.restoreCallingIdentity(origId);
16036            return res;
16037        }
16038    }
16039
16040    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16041        // Refuse possible leaked file descriptors
16042        if (intent != null && intent.hasFileDescriptors() == true) {
16043            throw new IllegalArgumentException("File descriptors passed in Intent");
16044        }
16045
16046        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16047                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16048
16049        synchronized(this) {
16050            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16051                    != PackageManager.PERMISSION_GRANTED) {
16052                String msg = "Permission Denial: unbroadcastIntent() from pid="
16053                        + Binder.getCallingPid()
16054                        + ", uid=" + Binder.getCallingUid()
16055                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16056                Slog.w(TAG, msg);
16057                throw new SecurityException(msg);
16058            }
16059            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16060            if (stickies != null) {
16061                ArrayList<Intent> list = stickies.get(intent.getAction());
16062                if (list != null) {
16063                    int N = list.size();
16064                    int i;
16065                    for (i=0; i<N; i++) {
16066                        if (intent.filterEquals(list.get(i))) {
16067                            list.remove(i);
16068                            break;
16069                        }
16070                    }
16071                    if (list.size() <= 0) {
16072                        stickies.remove(intent.getAction());
16073                    }
16074                }
16075                if (stickies.size() <= 0) {
16076                    mStickyBroadcasts.remove(userId);
16077                }
16078            }
16079        }
16080    }
16081
16082    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
16083            String resultData, Bundle resultExtras, boolean resultAbort) {
16084        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
16085        if (r == null) {
16086            Slog.w(TAG, "finishReceiver called but not found on queue");
16087            return false;
16088        }
16089
16090        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
16091    }
16092
16093    void backgroundServicesFinishedLocked(int userId) {
16094        for (BroadcastQueue queue : mBroadcastQueues) {
16095            queue.backgroundServicesFinishedLocked(userId);
16096        }
16097    }
16098
16099    public void finishReceiver(IBinder who, int resultCode, String resultData,
16100            Bundle resultExtras, boolean resultAbort) {
16101        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16102
16103        // Refuse possible leaked file descriptors
16104        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16105            throw new IllegalArgumentException("File descriptors passed in Bundle");
16106        }
16107
16108        final long origId = Binder.clearCallingIdentity();
16109        try {
16110            boolean doNext = false;
16111            BroadcastRecord r;
16112
16113            synchronized(this) {
16114                r = broadcastRecordForReceiverLocked(who);
16115                if (r != null) {
16116                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16117                        resultData, resultExtras, resultAbort, true);
16118                }
16119            }
16120
16121            if (doNext) {
16122                r.queue.processNextBroadcast(false);
16123            }
16124            trimApplications();
16125        } finally {
16126            Binder.restoreCallingIdentity(origId);
16127        }
16128    }
16129
16130    // =========================================================
16131    // INSTRUMENTATION
16132    // =========================================================
16133
16134    public boolean startInstrumentation(ComponentName className,
16135            String profileFile, int flags, Bundle arguments,
16136            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16137            int userId, String abiOverride) {
16138        enforceNotIsolatedCaller("startInstrumentation");
16139        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16140                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16141        // Refuse possible leaked file descriptors
16142        if (arguments != null && arguments.hasFileDescriptors()) {
16143            throw new IllegalArgumentException("File descriptors passed in Bundle");
16144        }
16145
16146        synchronized(this) {
16147            InstrumentationInfo ii = null;
16148            ApplicationInfo ai = null;
16149            try {
16150                ii = mContext.getPackageManager().getInstrumentationInfo(
16151                    className, STOCK_PM_FLAGS);
16152                ai = AppGlobals.getPackageManager().getApplicationInfo(
16153                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16154            } catch (PackageManager.NameNotFoundException e) {
16155            } catch (RemoteException e) {
16156            }
16157            if (ii == null) {
16158                reportStartInstrumentationFailure(watcher, className,
16159                        "Unable to find instrumentation info for: " + className);
16160                return false;
16161            }
16162            if (ai == null) {
16163                reportStartInstrumentationFailure(watcher, className,
16164                        "Unable to find instrumentation target package: " + ii.targetPackage);
16165                return false;
16166            }
16167
16168            int match = mContext.getPackageManager().checkSignatures(
16169                    ii.targetPackage, ii.packageName);
16170            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16171                String msg = "Permission Denial: starting instrumentation "
16172                        + className + " from pid="
16173                        + Binder.getCallingPid()
16174                        + ", uid=" + Binder.getCallingPid()
16175                        + " not allowed because package " + ii.packageName
16176                        + " does not have a signature matching the target "
16177                        + ii.targetPackage;
16178                reportStartInstrumentationFailure(watcher, className, msg);
16179                throw new SecurityException(msg);
16180            }
16181
16182            final long origId = Binder.clearCallingIdentity();
16183            // Instrumentation can kill and relaunch even persistent processes
16184            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16185                    "start instr");
16186            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16187            app.instrumentationClass = className;
16188            app.instrumentationInfo = ai;
16189            app.instrumentationProfileFile = profileFile;
16190            app.instrumentationArguments = arguments;
16191            app.instrumentationWatcher = watcher;
16192            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16193            app.instrumentationResultClass = className;
16194            Binder.restoreCallingIdentity(origId);
16195        }
16196
16197        return true;
16198    }
16199
16200    /**
16201     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16202     * error to the logs, but if somebody is watching, send the report there too.  This enables
16203     * the "am" command to report errors with more information.
16204     *
16205     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16206     * @param cn The component name of the instrumentation.
16207     * @param report The error report.
16208     */
16209    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16210            ComponentName cn, String report) {
16211        Slog.w(TAG, report);
16212        try {
16213            if (watcher != null) {
16214                Bundle results = new Bundle();
16215                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16216                results.putString("Error", report);
16217                watcher.instrumentationStatus(cn, -1, results);
16218            }
16219        } catch (RemoteException e) {
16220            Slog.w(TAG, e);
16221        }
16222    }
16223
16224    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16225        if (app.instrumentationWatcher != null) {
16226            try {
16227                // NOTE:  IInstrumentationWatcher *must* be oneway here
16228                app.instrumentationWatcher.instrumentationFinished(
16229                    app.instrumentationClass,
16230                    resultCode,
16231                    results);
16232            } catch (RemoteException e) {
16233            }
16234        }
16235        if (app.instrumentationUiAutomationConnection != null) {
16236            try {
16237                app.instrumentationUiAutomationConnection.shutdown();
16238            } catch (RemoteException re) {
16239                /* ignore */
16240            }
16241            // Only a UiAutomation can set this flag and now that
16242            // it is finished we make sure it is reset to its default.
16243            mUserIsMonkey = false;
16244        }
16245        app.instrumentationWatcher = null;
16246        app.instrumentationUiAutomationConnection = null;
16247        app.instrumentationClass = null;
16248        app.instrumentationInfo = null;
16249        app.instrumentationProfileFile = null;
16250        app.instrumentationArguments = null;
16251
16252        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16253                "finished inst");
16254    }
16255
16256    public void finishInstrumentation(IApplicationThread target,
16257            int resultCode, Bundle results) {
16258        int userId = UserHandle.getCallingUserId();
16259        // Refuse possible leaked file descriptors
16260        if (results != null && results.hasFileDescriptors()) {
16261            throw new IllegalArgumentException("File descriptors passed in Intent");
16262        }
16263
16264        synchronized(this) {
16265            ProcessRecord app = getRecordForAppLocked(target);
16266            if (app == null) {
16267                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16268                return;
16269            }
16270            final long origId = Binder.clearCallingIdentity();
16271            finishInstrumentationLocked(app, resultCode, results);
16272            Binder.restoreCallingIdentity(origId);
16273        }
16274    }
16275
16276    // =========================================================
16277    // CONFIGURATION
16278    // =========================================================
16279
16280    public ConfigurationInfo getDeviceConfigurationInfo() {
16281        ConfigurationInfo config = new ConfigurationInfo();
16282        synchronized (this) {
16283            config.reqTouchScreen = mConfiguration.touchscreen;
16284            config.reqKeyboardType = mConfiguration.keyboard;
16285            config.reqNavigation = mConfiguration.navigation;
16286            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16287                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16288                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16289            }
16290            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16291                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16292                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16293            }
16294            config.reqGlEsVersion = GL_ES_VERSION;
16295        }
16296        return config;
16297    }
16298
16299    ActivityStack getFocusedStack() {
16300        return mStackSupervisor.getFocusedStack();
16301    }
16302
16303    public Configuration getConfiguration() {
16304        Configuration ci;
16305        synchronized(this) {
16306            ci = new Configuration(mConfiguration);
16307        }
16308        return ci;
16309    }
16310
16311    public void updatePersistentConfiguration(Configuration values) {
16312        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16313                "updateConfiguration()");
16314        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16315                "updateConfiguration()");
16316        if (values == null) {
16317            throw new NullPointerException("Configuration must not be null");
16318        }
16319
16320        synchronized(this) {
16321            final long origId = Binder.clearCallingIdentity();
16322            updateConfigurationLocked(values, null, true, false);
16323            Binder.restoreCallingIdentity(origId);
16324        }
16325    }
16326
16327    public void updateConfiguration(Configuration values) {
16328        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16329                "updateConfiguration()");
16330
16331        synchronized(this) {
16332            if (values == null && mWindowManager != null) {
16333                // sentinel: fetch the current configuration from the window manager
16334                values = mWindowManager.computeNewConfiguration();
16335            }
16336
16337            if (mWindowManager != null) {
16338                mProcessList.applyDisplaySize(mWindowManager);
16339            }
16340
16341            final long origId = Binder.clearCallingIdentity();
16342            if (values != null) {
16343                Settings.System.clearConfiguration(values);
16344            }
16345            updateConfigurationLocked(values, null, false, false);
16346            Binder.restoreCallingIdentity(origId);
16347        }
16348    }
16349
16350    /**
16351     * Do either or both things: (1) change the current configuration, and (2)
16352     * make sure the given activity is running with the (now) current
16353     * configuration.  Returns true if the activity has been left running, or
16354     * false if <var>starting</var> is being destroyed to match the new
16355     * configuration.
16356     * @param persistent TODO
16357     */
16358    boolean updateConfigurationLocked(Configuration values,
16359            ActivityRecord starting, boolean persistent, boolean initLocale) {
16360        int changes = 0;
16361
16362        if (values != null) {
16363            Configuration newConfig = new Configuration(mConfiguration);
16364            changes = newConfig.updateFrom(values);
16365            if (changes != 0) {
16366                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16367                    Slog.i(TAG, "Updating configuration to: " + values);
16368                }
16369
16370                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16371
16372                if (values.locale != null && !initLocale) {
16373                    saveLocaleLocked(values.locale,
16374                                     !values.locale.equals(mConfiguration.locale),
16375                                     values.userSetLocale);
16376                }
16377
16378                mConfigurationSeq++;
16379                if (mConfigurationSeq <= 0) {
16380                    mConfigurationSeq = 1;
16381                }
16382                newConfig.seq = mConfigurationSeq;
16383                mConfiguration = newConfig;
16384                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16385                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16386                //mUsageStatsService.noteStartConfig(newConfig);
16387
16388                final Configuration configCopy = new Configuration(mConfiguration);
16389
16390                // TODO: If our config changes, should we auto dismiss any currently
16391                // showing dialogs?
16392                mShowDialogs = shouldShowDialogs(newConfig);
16393
16394                AttributeCache ac = AttributeCache.instance();
16395                if (ac != null) {
16396                    ac.updateConfiguration(configCopy);
16397                }
16398
16399                // Make sure all resources in our process are updated
16400                // right now, so that anyone who is going to retrieve
16401                // resource values after we return will be sure to get
16402                // the new ones.  This is especially important during
16403                // boot, where the first config change needs to guarantee
16404                // all resources have that config before following boot
16405                // code is executed.
16406                mSystemThread.applyConfigurationToResources(configCopy);
16407
16408                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16409                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16410                    msg.obj = new Configuration(configCopy);
16411                    mHandler.sendMessage(msg);
16412                }
16413
16414                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16415                    ProcessRecord app = mLruProcesses.get(i);
16416                    try {
16417                        if (app.thread != null) {
16418                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16419                                    + app.processName + " new config " + mConfiguration);
16420                            app.thread.scheduleConfigurationChanged(configCopy);
16421                        }
16422                    } catch (Exception e) {
16423                    }
16424                }
16425                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16426                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16427                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16428                        | Intent.FLAG_RECEIVER_FOREGROUND);
16429                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16430                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16431                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16432                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16433                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16434                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16435                    broadcastIntentLocked(null, null, intent,
16436                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16437                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16438                }
16439            }
16440        }
16441
16442        boolean kept = true;
16443        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16444        // mainStack is null during startup.
16445        if (mainStack != null) {
16446            if (changes != 0 && starting == null) {
16447                // If the configuration changed, and the caller is not already
16448                // in the process of starting an activity, then find the top
16449                // activity to check if its configuration needs to change.
16450                starting = mainStack.topRunningActivityLocked(null);
16451            }
16452
16453            if (starting != null) {
16454                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16455                // And we need to make sure at this point that all other activities
16456                // are made visible with the correct configuration.
16457                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16458            }
16459        }
16460
16461        if (values != null && mWindowManager != null) {
16462            mWindowManager.setNewConfiguration(mConfiguration);
16463        }
16464
16465        return kept;
16466    }
16467
16468    /**
16469     * Decide based on the configuration whether we should shouw the ANR,
16470     * crash, etc dialogs.  The idea is that if there is no affordnace to
16471     * press the on-screen buttons, we shouldn't show the dialog.
16472     *
16473     * A thought: SystemUI might also want to get told about this, the Power
16474     * dialog / global actions also might want different behaviors.
16475     */
16476    private static final boolean shouldShowDialogs(Configuration config) {
16477        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16478                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16479    }
16480
16481    /**
16482     * Save the locale.  You must be inside a synchronized (this) block.
16483     */
16484    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16485        if(isDiff) {
16486            SystemProperties.set("user.language", l.getLanguage());
16487            SystemProperties.set("user.region", l.getCountry());
16488        }
16489
16490        if(isPersist) {
16491            SystemProperties.set("persist.sys.language", l.getLanguage());
16492            SystemProperties.set("persist.sys.country", l.getCountry());
16493            SystemProperties.set("persist.sys.localevar", l.getVariant());
16494
16495            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16496        }
16497    }
16498
16499    @Override
16500    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16501        synchronized (this) {
16502            ActivityRecord srec = ActivityRecord.forToken(token);
16503            if (srec.task != null && srec.task.stack != null) {
16504                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16505            }
16506        }
16507        return false;
16508    }
16509
16510    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16511            Intent resultData) {
16512
16513        synchronized (this) {
16514            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16515            if (stack != null) {
16516                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16517            }
16518            return false;
16519        }
16520    }
16521
16522    public int getLaunchedFromUid(IBinder activityToken) {
16523        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16524        if (srec == null) {
16525            return -1;
16526        }
16527        return srec.launchedFromUid;
16528    }
16529
16530    public String getLaunchedFromPackage(IBinder activityToken) {
16531        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16532        if (srec == null) {
16533            return null;
16534        }
16535        return srec.launchedFromPackage;
16536    }
16537
16538    // =========================================================
16539    // LIFETIME MANAGEMENT
16540    // =========================================================
16541
16542    // Returns which broadcast queue the app is the current [or imminent] receiver
16543    // on, or 'null' if the app is not an active broadcast recipient.
16544    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16545        BroadcastRecord r = app.curReceiver;
16546        if (r != null) {
16547            return r.queue;
16548        }
16549
16550        // It's not the current receiver, but it might be starting up to become one
16551        synchronized (this) {
16552            for (BroadcastQueue queue : mBroadcastQueues) {
16553                r = queue.mPendingBroadcast;
16554                if (r != null && r.curApp == app) {
16555                    // found it; report which queue it's in
16556                    return queue;
16557                }
16558            }
16559        }
16560
16561        return null;
16562    }
16563
16564    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16565            boolean doingAll, long now) {
16566        if (mAdjSeq == app.adjSeq) {
16567            // This adjustment has already been computed.
16568            return app.curRawAdj;
16569        }
16570
16571        if (app.thread == null) {
16572            app.adjSeq = mAdjSeq;
16573            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16574            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16575            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16576        }
16577
16578        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16579        app.adjSource = null;
16580        app.adjTarget = null;
16581        app.empty = false;
16582        app.cached = false;
16583
16584        final int activitiesSize = app.activities.size();
16585
16586        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16587            // The max adjustment doesn't allow this app to be anything
16588            // below foreground, so it is not worth doing work for it.
16589            app.adjType = "fixed";
16590            app.adjSeq = mAdjSeq;
16591            app.curRawAdj = app.maxAdj;
16592            app.foregroundActivities = false;
16593            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16594            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16595            // System processes can do UI, and when they do we want to have
16596            // them trim their memory after the user leaves the UI.  To
16597            // facilitate this, here we need to determine whether or not it
16598            // is currently showing UI.
16599            app.systemNoUi = true;
16600            if (app == TOP_APP) {
16601                app.systemNoUi = false;
16602            } else if (activitiesSize > 0) {
16603                for (int j = 0; j < activitiesSize; j++) {
16604                    final ActivityRecord r = app.activities.get(j);
16605                    if (r.visible) {
16606                        app.systemNoUi = false;
16607                    }
16608                }
16609            }
16610            if (!app.systemNoUi) {
16611                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16612            }
16613            return (app.curAdj=app.maxAdj);
16614        }
16615
16616        app.systemNoUi = false;
16617
16618        // Determine the importance of the process, starting with most
16619        // important to least, and assign an appropriate OOM adjustment.
16620        int adj;
16621        int schedGroup;
16622        int procState;
16623        boolean foregroundActivities = false;
16624        BroadcastQueue queue;
16625        if (app == TOP_APP) {
16626            // The last app on the list is the foreground app.
16627            adj = ProcessList.FOREGROUND_APP_ADJ;
16628            schedGroup = Process.THREAD_GROUP_DEFAULT;
16629            app.adjType = "top-activity";
16630            foregroundActivities = true;
16631            procState = ActivityManager.PROCESS_STATE_TOP;
16632        } else if (app.instrumentationClass != null) {
16633            // Don't want to kill running instrumentation.
16634            adj = ProcessList.FOREGROUND_APP_ADJ;
16635            schedGroup = Process.THREAD_GROUP_DEFAULT;
16636            app.adjType = "instrumentation";
16637            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16638        } else if ((queue = isReceivingBroadcast(app)) != null) {
16639            // An app that is currently receiving a broadcast also
16640            // counts as being in the foreground for OOM killer purposes.
16641            // It's placed in a sched group based on the nature of the
16642            // broadcast as reflected by which queue it's active in.
16643            adj = ProcessList.FOREGROUND_APP_ADJ;
16644            schedGroup = (queue == mFgBroadcastQueue)
16645                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16646            app.adjType = "broadcast";
16647            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16648        } else if (app.executingServices.size() > 0) {
16649            // An app that is currently executing a service callback also
16650            // counts as being in the foreground.
16651            adj = ProcessList.FOREGROUND_APP_ADJ;
16652            schedGroup = app.execServicesFg ?
16653                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16654            app.adjType = "exec-service";
16655            procState = ActivityManager.PROCESS_STATE_SERVICE;
16656            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16657        } else {
16658            // As far as we know the process is empty.  We may change our mind later.
16659            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16660            // At this point we don't actually know the adjustment.  Use the cached adj
16661            // value that the caller wants us to.
16662            adj = cachedAdj;
16663            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16664            app.cached = true;
16665            app.empty = true;
16666            app.adjType = "cch-empty";
16667        }
16668
16669        // Examine all activities if not already foreground.
16670        if (!foregroundActivities && activitiesSize > 0) {
16671            for (int j = 0; j < activitiesSize; j++) {
16672                final ActivityRecord r = app.activities.get(j);
16673                if (r.app != app) {
16674                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16675                            + app + "?!?");
16676                    continue;
16677                }
16678                if (r.visible) {
16679                    // App has a visible activity; only upgrade adjustment.
16680                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16681                        adj = ProcessList.VISIBLE_APP_ADJ;
16682                        app.adjType = "visible";
16683                    }
16684                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16685                        procState = ActivityManager.PROCESS_STATE_TOP;
16686                    }
16687                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16688                    app.cached = false;
16689                    app.empty = false;
16690                    foregroundActivities = true;
16691                    break;
16692                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16693                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16694                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16695                        app.adjType = "pausing";
16696                    }
16697                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16698                        procState = ActivityManager.PROCESS_STATE_TOP;
16699                    }
16700                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16701                    app.cached = false;
16702                    app.empty = false;
16703                    foregroundActivities = true;
16704                } else if (r.state == ActivityState.STOPPING) {
16705                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16706                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16707                        app.adjType = "stopping";
16708                    }
16709                    // For the process state, we will at this point consider the
16710                    // process to be cached.  It will be cached either as an activity
16711                    // or empty depending on whether the activity is finishing.  We do
16712                    // this so that we can treat the process as cached for purposes of
16713                    // memory trimming (determing current memory level, trim command to
16714                    // send to process) since there can be an arbitrary number of stopping
16715                    // processes and they should soon all go into the cached state.
16716                    if (!r.finishing) {
16717                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16718                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16719                        }
16720                    }
16721                    app.cached = false;
16722                    app.empty = false;
16723                    foregroundActivities = true;
16724                } else {
16725                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16726                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16727                        app.adjType = "cch-act";
16728                    }
16729                }
16730            }
16731        }
16732
16733        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16734            if (app.foregroundServices) {
16735                // The user is aware of this app, so make it visible.
16736                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16737                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16738                app.cached = false;
16739                app.adjType = "fg-service";
16740                schedGroup = Process.THREAD_GROUP_DEFAULT;
16741            } else if (app.forcingToForeground != null) {
16742                // The user is aware of this app, so make it visible.
16743                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16744                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16745                app.cached = false;
16746                app.adjType = "force-fg";
16747                app.adjSource = app.forcingToForeground;
16748                schedGroup = Process.THREAD_GROUP_DEFAULT;
16749            }
16750        }
16751
16752        if (app == mHeavyWeightProcess) {
16753            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16754                // We don't want to kill the current heavy-weight process.
16755                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16756                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16757                app.cached = false;
16758                app.adjType = "heavy";
16759            }
16760            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16761                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16762            }
16763        }
16764
16765        if (app == mHomeProcess) {
16766            if (adj > ProcessList.HOME_APP_ADJ) {
16767                // This process is hosting what we currently consider to be the
16768                // home app, so we don't want to let it go into the background.
16769                adj = ProcessList.HOME_APP_ADJ;
16770                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16771                app.cached = false;
16772                app.adjType = "home";
16773            }
16774            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16775                procState = ActivityManager.PROCESS_STATE_HOME;
16776            }
16777        }
16778
16779        if (app == mPreviousProcess && app.activities.size() > 0) {
16780            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16781                // This was the previous process that showed UI to the user.
16782                // We want to try to keep it around more aggressively, to give
16783                // a good experience around switching between two apps.
16784                adj = ProcessList.PREVIOUS_APP_ADJ;
16785                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16786                app.cached = false;
16787                app.adjType = "previous";
16788            }
16789            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16790                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16791            }
16792        }
16793
16794        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16795                + " reason=" + app.adjType);
16796
16797        // By default, we use the computed adjustment.  It may be changed if
16798        // there are applications dependent on our services or providers, but
16799        // this gives us a baseline and makes sure we don't get into an
16800        // infinite recursion.
16801        app.adjSeq = mAdjSeq;
16802        app.curRawAdj = adj;
16803        app.hasStartedServices = false;
16804
16805        if (mBackupTarget != null && app == mBackupTarget.app) {
16806            // If possible we want to avoid killing apps while they're being backed up
16807            if (adj > ProcessList.BACKUP_APP_ADJ) {
16808                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16809                adj = ProcessList.BACKUP_APP_ADJ;
16810                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16811                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16812                }
16813                app.adjType = "backup";
16814                app.cached = false;
16815            }
16816            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16817                procState = ActivityManager.PROCESS_STATE_BACKUP;
16818            }
16819        }
16820
16821        boolean mayBeTop = false;
16822
16823        for (int is = app.services.size()-1;
16824                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16825                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16826                        || procState > ActivityManager.PROCESS_STATE_TOP);
16827                is--) {
16828            ServiceRecord s = app.services.valueAt(is);
16829            if (s.startRequested) {
16830                app.hasStartedServices = true;
16831                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16832                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16833                }
16834                if (app.hasShownUi && app != mHomeProcess) {
16835                    // If this process has shown some UI, let it immediately
16836                    // go to the LRU list because it may be pretty heavy with
16837                    // UI stuff.  We'll tag it with a label just to help
16838                    // debug and understand what is going on.
16839                    if (adj > ProcessList.SERVICE_ADJ) {
16840                        app.adjType = "cch-started-ui-services";
16841                    }
16842                } else {
16843                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16844                        // This service has seen some activity within
16845                        // recent memory, so we will keep its process ahead
16846                        // of the background processes.
16847                        if (adj > ProcessList.SERVICE_ADJ) {
16848                            adj = ProcessList.SERVICE_ADJ;
16849                            app.adjType = "started-services";
16850                            app.cached = false;
16851                        }
16852                    }
16853                    // If we have let the service slide into the background
16854                    // state, still have some text describing what it is doing
16855                    // even though the service no longer has an impact.
16856                    if (adj > ProcessList.SERVICE_ADJ) {
16857                        app.adjType = "cch-started-services";
16858                    }
16859                }
16860            }
16861            for (int conni = s.connections.size()-1;
16862                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16863                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16864                            || procState > ActivityManager.PROCESS_STATE_TOP);
16865                    conni--) {
16866                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16867                for (int i = 0;
16868                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16869                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16870                                || procState > ActivityManager.PROCESS_STATE_TOP);
16871                        i++) {
16872                    // XXX should compute this based on the max of
16873                    // all connected clients.
16874                    ConnectionRecord cr = clist.get(i);
16875                    if (cr.binding.client == app) {
16876                        // Binding to ourself is not interesting.
16877                        continue;
16878                    }
16879                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16880                        ProcessRecord client = cr.binding.client;
16881                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16882                                TOP_APP, doingAll, now);
16883                        int clientProcState = client.curProcState;
16884                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16885                            // If the other app is cached for any reason, for purposes here
16886                            // we are going to consider it empty.  The specific cached state
16887                            // doesn't propagate except under certain conditions.
16888                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16889                        }
16890                        String adjType = null;
16891                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16892                            // Not doing bind OOM management, so treat
16893                            // this guy more like a started service.
16894                            if (app.hasShownUi && app != mHomeProcess) {
16895                                // If this process has shown some UI, let it immediately
16896                                // go to the LRU list because it may be pretty heavy with
16897                                // UI stuff.  We'll tag it with a label just to help
16898                                // debug and understand what is going on.
16899                                if (adj > clientAdj) {
16900                                    adjType = "cch-bound-ui-services";
16901                                }
16902                                app.cached = false;
16903                                clientAdj = adj;
16904                                clientProcState = procState;
16905                            } else {
16906                                if (now >= (s.lastActivity
16907                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16908                                    // This service has not seen activity within
16909                                    // recent memory, so allow it to drop to the
16910                                    // LRU list if there is no other reason to keep
16911                                    // it around.  We'll also tag it with a label just
16912                                    // to help debug and undertand what is going on.
16913                                    if (adj > clientAdj) {
16914                                        adjType = "cch-bound-services";
16915                                    }
16916                                    clientAdj = adj;
16917                                }
16918                            }
16919                        }
16920                        if (adj > clientAdj) {
16921                            // If this process has recently shown UI, and
16922                            // the process that is binding to it is less
16923                            // important than being visible, then we don't
16924                            // care about the binding as much as we care
16925                            // about letting this process get into the LRU
16926                            // list to be killed and restarted if needed for
16927                            // memory.
16928                            if (app.hasShownUi && app != mHomeProcess
16929                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16930                                adjType = "cch-bound-ui-services";
16931                            } else {
16932                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16933                                        |Context.BIND_IMPORTANT)) != 0) {
16934                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
16935                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
16936                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16937                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16938                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16939                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16940                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16941                                    adj = clientAdj;
16942                                } else {
16943                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16944                                        adj = ProcessList.VISIBLE_APP_ADJ;
16945                                    }
16946                                }
16947                                if (!client.cached) {
16948                                    app.cached = false;
16949                                }
16950                                adjType = "service";
16951                            }
16952                        }
16953                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16954                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16955                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16956                            }
16957                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16958                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16959                                    // Special handling of clients who are in the top state.
16960                                    // We *may* want to consider this process to be in the
16961                                    // top state as well, but only if there is not another
16962                                    // reason for it to be running.  Being on the top is a
16963                                    // special state, meaning you are specifically running
16964                                    // for the current top app.  If the process is already
16965                                    // running in the background for some other reason, it
16966                                    // is more important to continue considering it to be
16967                                    // in the background state.
16968                                    mayBeTop = true;
16969                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16970                                } else {
16971                                    // Special handling for above-top states (persistent
16972                                    // processes).  These should not bring the current process
16973                                    // into the top state, since they are not on top.  Instead
16974                                    // give them the best state after that.
16975                                    clientProcState =
16976                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16977                                }
16978                            }
16979                        } else {
16980                            if (clientProcState <
16981                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16982                                clientProcState =
16983                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16984                            }
16985                        }
16986                        if (procState > clientProcState) {
16987                            procState = clientProcState;
16988                        }
16989                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16990                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16991                            app.pendingUiClean = true;
16992                        }
16993                        if (adjType != null) {
16994                            app.adjType = adjType;
16995                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16996                                    .REASON_SERVICE_IN_USE;
16997                            app.adjSource = cr.binding.client;
16998                            app.adjSourceProcState = clientProcState;
16999                            app.adjTarget = s.name;
17000                        }
17001                    }
17002                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17003                        app.treatLikeActivity = true;
17004                    }
17005                    final ActivityRecord a = cr.activity;
17006                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17007                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17008                                (a.visible || a.state == ActivityState.RESUMED
17009                                 || a.state == ActivityState.PAUSING)) {
17010                            adj = ProcessList.FOREGROUND_APP_ADJ;
17011                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17012                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17013                            }
17014                            app.cached = false;
17015                            app.adjType = "service";
17016                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17017                                    .REASON_SERVICE_IN_USE;
17018                            app.adjSource = a;
17019                            app.adjSourceProcState = procState;
17020                            app.adjTarget = s.name;
17021                        }
17022                    }
17023                }
17024            }
17025        }
17026
17027        for (int provi = app.pubProviders.size()-1;
17028                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17029                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17030                        || procState > ActivityManager.PROCESS_STATE_TOP);
17031                provi--) {
17032            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17033            for (int i = cpr.connections.size()-1;
17034                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17035                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17036                            || procState > ActivityManager.PROCESS_STATE_TOP);
17037                    i--) {
17038                ContentProviderConnection conn = cpr.connections.get(i);
17039                ProcessRecord client = conn.client;
17040                if (client == app) {
17041                    // Being our own client is not interesting.
17042                    continue;
17043                }
17044                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17045                int clientProcState = client.curProcState;
17046                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17047                    // If the other app is cached for any reason, for purposes here
17048                    // we are going to consider it empty.
17049                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17050                }
17051                if (adj > clientAdj) {
17052                    if (app.hasShownUi && app != mHomeProcess
17053                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17054                        app.adjType = "cch-ui-provider";
17055                    } else {
17056                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17057                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17058                        app.adjType = "provider";
17059                    }
17060                    app.cached &= client.cached;
17061                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17062                            .REASON_PROVIDER_IN_USE;
17063                    app.adjSource = client;
17064                    app.adjSourceProcState = clientProcState;
17065                    app.adjTarget = cpr.name;
17066                }
17067                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17068                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17069                        // Special handling of clients who are in the top state.
17070                        // We *may* want to consider this process to be in the
17071                        // top state as well, but only if there is not another
17072                        // reason for it to be running.  Being on the top is a
17073                        // special state, meaning you are specifically running
17074                        // for the current top app.  If the process is already
17075                        // running in the background for some other reason, it
17076                        // is more important to continue considering it to be
17077                        // in the background state.
17078                        mayBeTop = true;
17079                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17080                    } else {
17081                        // Special handling for above-top states (persistent
17082                        // processes).  These should not bring the current process
17083                        // into the top state, since they are not on top.  Instead
17084                        // give them the best state after that.
17085                        clientProcState =
17086                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17087                    }
17088                }
17089                if (procState > clientProcState) {
17090                    procState = clientProcState;
17091                }
17092                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17093                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17094                }
17095            }
17096            // If the provider has external (non-framework) process
17097            // dependencies, ensure that its adjustment is at least
17098            // FOREGROUND_APP_ADJ.
17099            if (cpr.hasExternalProcessHandles()) {
17100                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17101                    adj = ProcessList.FOREGROUND_APP_ADJ;
17102                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17103                    app.cached = false;
17104                    app.adjType = "provider";
17105                    app.adjTarget = cpr.name;
17106                }
17107                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17108                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17109                }
17110            }
17111        }
17112
17113        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17114            // A client of one of our services or providers is in the top state.  We
17115            // *may* want to be in the top state, but not if we are already running in
17116            // the background for some other reason.  For the decision here, we are going
17117            // to pick out a few specific states that we want to remain in when a client
17118            // is top (states that tend to be longer-term) and otherwise allow it to go
17119            // to the top state.
17120            switch (procState) {
17121                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17122                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17123                case ActivityManager.PROCESS_STATE_SERVICE:
17124                    // These all are longer-term states, so pull them up to the top
17125                    // of the background states, but not all the way to the top state.
17126                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17127                    break;
17128                default:
17129                    // Otherwise, top is a better choice, so take it.
17130                    procState = ActivityManager.PROCESS_STATE_TOP;
17131                    break;
17132            }
17133        }
17134
17135        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17136            if (app.hasClientActivities) {
17137                // This is a cached process, but with client activities.  Mark it so.
17138                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17139                app.adjType = "cch-client-act";
17140            } else if (app.treatLikeActivity) {
17141                // This is a cached process, but somebody wants us to treat it like it has
17142                // an activity, okay!
17143                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17144                app.adjType = "cch-as-act";
17145            }
17146        }
17147
17148        if (adj == ProcessList.SERVICE_ADJ) {
17149            if (doingAll) {
17150                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17151                mNewNumServiceProcs++;
17152                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17153                if (!app.serviceb) {
17154                    // This service isn't far enough down on the LRU list to
17155                    // normally be a B service, but if we are low on RAM and it
17156                    // is large we want to force it down since we would prefer to
17157                    // keep launcher over it.
17158                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17159                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17160                        app.serviceHighRam = true;
17161                        app.serviceb = true;
17162                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17163                    } else {
17164                        mNewNumAServiceProcs++;
17165                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17166                    }
17167                } else {
17168                    app.serviceHighRam = false;
17169                }
17170            }
17171            if (app.serviceb) {
17172                adj = ProcessList.SERVICE_B_ADJ;
17173            }
17174        }
17175
17176        app.curRawAdj = adj;
17177
17178        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17179        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17180        if (adj > app.maxAdj) {
17181            adj = app.maxAdj;
17182            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17183                schedGroup = Process.THREAD_GROUP_DEFAULT;
17184            }
17185        }
17186
17187        // Do final modification to adj.  Everything we do between here and applying
17188        // the final setAdj must be done in this function, because we will also use
17189        // it when computing the final cached adj later.  Note that we don't need to
17190        // worry about this for max adj above, since max adj will always be used to
17191        // keep it out of the cached vaues.
17192        app.curAdj = app.modifyRawOomAdj(adj);
17193        app.curSchedGroup = schedGroup;
17194        app.curProcState = procState;
17195        app.foregroundActivities = foregroundActivities;
17196
17197        return app.curRawAdj;
17198    }
17199
17200    /**
17201     * Schedule PSS collection of a process.
17202     */
17203    void requestPssLocked(ProcessRecord proc, int procState) {
17204        if (mPendingPssProcesses.contains(proc)) {
17205            return;
17206        }
17207        if (mPendingPssProcesses.size() == 0) {
17208            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17209        }
17210        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17211        proc.pssProcState = procState;
17212        mPendingPssProcesses.add(proc);
17213    }
17214
17215    /**
17216     * Schedule PSS collection of all processes.
17217     */
17218    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17219        if (!always) {
17220            if (now < (mLastFullPssTime +
17221                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17222                return;
17223            }
17224        }
17225        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17226        mLastFullPssTime = now;
17227        mFullPssPending = true;
17228        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17229        mPendingPssProcesses.clear();
17230        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17231            ProcessRecord app = mLruProcesses.get(i);
17232            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17233                app.pssProcState = app.setProcState;
17234                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17235                        isSleeping(), now);
17236                mPendingPssProcesses.add(app);
17237            }
17238        }
17239        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17240    }
17241
17242    /**
17243     * Ask a given process to GC right now.
17244     */
17245    final void performAppGcLocked(ProcessRecord app) {
17246        try {
17247            app.lastRequestedGc = SystemClock.uptimeMillis();
17248            if (app.thread != null) {
17249                if (app.reportLowMemory) {
17250                    app.reportLowMemory = false;
17251                    app.thread.scheduleLowMemory();
17252                } else {
17253                    app.thread.processInBackground();
17254                }
17255            }
17256        } catch (Exception e) {
17257            // whatever.
17258        }
17259    }
17260
17261    /**
17262     * Returns true if things are idle enough to perform GCs.
17263     */
17264    private final boolean canGcNowLocked() {
17265        boolean processingBroadcasts = false;
17266        for (BroadcastQueue q : mBroadcastQueues) {
17267            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17268                processingBroadcasts = true;
17269            }
17270        }
17271        return !processingBroadcasts
17272                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17273    }
17274
17275    /**
17276     * Perform GCs on all processes that are waiting for it, but only
17277     * if things are idle.
17278     */
17279    final void performAppGcsLocked() {
17280        final int N = mProcessesToGc.size();
17281        if (N <= 0) {
17282            return;
17283        }
17284        if (canGcNowLocked()) {
17285            while (mProcessesToGc.size() > 0) {
17286                ProcessRecord proc = mProcessesToGc.remove(0);
17287                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17288                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17289                            <= SystemClock.uptimeMillis()) {
17290                        // To avoid spamming the system, we will GC processes one
17291                        // at a time, waiting a few seconds between each.
17292                        performAppGcLocked(proc);
17293                        scheduleAppGcsLocked();
17294                        return;
17295                    } else {
17296                        // It hasn't been long enough since we last GCed this
17297                        // process...  put it in the list to wait for its time.
17298                        addProcessToGcListLocked(proc);
17299                        break;
17300                    }
17301                }
17302            }
17303
17304            scheduleAppGcsLocked();
17305        }
17306    }
17307
17308    /**
17309     * If all looks good, perform GCs on all processes waiting for them.
17310     */
17311    final void performAppGcsIfAppropriateLocked() {
17312        if (canGcNowLocked()) {
17313            performAppGcsLocked();
17314            return;
17315        }
17316        // Still not idle, wait some more.
17317        scheduleAppGcsLocked();
17318    }
17319
17320    /**
17321     * Schedule the execution of all pending app GCs.
17322     */
17323    final void scheduleAppGcsLocked() {
17324        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17325
17326        if (mProcessesToGc.size() > 0) {
17327            // Schedule a GC for the time to the next process.
17328            ProcessRecord proc = mProcessesToGc.get(0);
17329            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17330
17331            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17332            long now = SystemClock.uptimeMillis();
17333            if (when < (now+GC_TIMEOUT)) {
17334                when = now + GC_TIMEOUT;
17335            }
17336            mHandler.sendMessageAtTime(msg, when);
17337        }
17338    }
17339
17340    /**
17341     * Add a process to the array of processes waiting to be GCed.  Keeps the
17342     * list in sorted order by the last GC time.  The process can't already be
17343     * on the list.
17344     */
17345    final void addProcessToGcListLocked(ProcessRecord proc) {
17346        boolean added = false;
17347        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17348            if (mProcessesToGc.get(i).lastRequestedGc <
17349                    proc.lastRequestedGc) {
17350                added = true;
17351                mProcessesToGc.add(i+1, proc);
17352                break;
17353            }
17354        }
17355        if (!added) {
17356            mProcessesToGc.add(0, proc);
17357        }
17358    }
17359
17360    /**
17361     * Set up to ask a process to GC itself.  This will either do it
17362     * immediately, or put it on the list of processes to gc the next
17363     * time things are idle.
17364     */
17365    final void scheduleAppGcLocked(ProcessRecord app) {
17366        long now = SystemClock.uptimeMillis();
17367        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17368            return;
17369        }
17370        if (!mProcessesToGc.contains(app)) {
17371            addProcessToGcListLocked(app);
17372            scheduleAppGcsLocked();
17373        }
17374    }
17375
17376    final void checkExcessivePowerUsageLocked(boolean doKills) {
17377        updateCpuStatsNow();
17378
17379        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17380        boolean doWakeKills = doKills;
17381        boolean doCpuKills = doKills;
17382        if (mLastPowerCheckRealtime == 0) {
17383            doWakeKills = false;
17384        }
17385        if (mLastPowerCheckUptime == 0) {
17386            doCpuKills = false;
17387        }
17388        if (stats.isScreenOn()) {
17389            doWakeKills = false;
17390        }
17391        final long curRealtime = SystemClock.elapsedRealtime();
17392        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17393        final long curUptime = SystemClock.uptimeMillis();
17394        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17395        mLastPowerCheckRealtime = curRealtime;
17396        mLastPowerCheckUptime = curUptime;
17397        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17398            doWakeKills = false;
17399        }
17400        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17401            doCpuKills = false;
17402        }
17403        int i = mLruProcesses.size();
17404        while (i > 0) {
17405            i--;
17406            ProcessRecord app = mLruProcesses.get(i);
17407            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17408                long wtime;
17409                synchronized (stats) {
17410                    wtime = stats.getProcessWakeTime(app.info.uid,
17411                            app.pid, curRealtime);
17412                }
17413                long wtimeUsed = wtime - app.lastWakeTime;
17414                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17415                if (DEBUG_POWER) {
17416                    StringBuilder sb = new StringBuilder(128);
17417                    sb.append("Wake for ");
17418                    app.toShortString(sb);
17419                    sb.append(": over ");
17420                    TimeUtils.formatDuration(realtimeSince, sb);
17421                    sb.append(" used ");
17422                    TimeUtils.formatDuration(wtimeUsed, sb);
17423                    sb.append(" (");
17424                    sb.append((wtimeUsed*100)/realtimeSince);
17425                    sb.append("%)");
17426                    Slog.i(TAG, sb.toString());
17427                    sb.setLength(0);
17428                    sb.append("CPU for ");
17429                    app.toShortString(sb);
17430                    sb.append(": over ");
17431                    TimeUtils.formatDuration(uptimeSince, sb);
17432                    sb.append(" used ");
17433                    TimeUtils.formatDuration(cputimeUsed, sb);
17434                    sb.append(" (");
17435                    sb.append((cputimeUsed*100)/uptimeSince);
17436                    sb.append("%)");
17437                    Slog.i(TAG, sb.toString());
17438                }
17439                // If a process has held a wake lock for more
17440                // than 50% of the time during this period,
17441                // that sounds bad.  Kill!
17442                if (doWakeKills && realtimeSince > 0
17443                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17444                    synchronized (stats) {
17445                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17446                                realtimeSince, wtimeUsed);
17447                    }
17448                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17449                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17450                } else if (doCpuKills && uptimeSince > 0
17451                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17452                    synchronized (stats) {
17453                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17454                                uptimeSince, cputimeUsed);
17455                    }
17456                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17457                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17458                } else {
17459                    app.lastWakeTime = wtime;
17460                    app.lastCpuTime = app.curCpuTime;
17461                }
17462            }
17463        }
17464    }
17465
17466    private final boolean applyOomAdjLocked(ProcessRecord app,
17467            ProcessRecord TOP_APP, boolean doingAll, long now) {
17468        boolean success = true;
17469
17470        if (app.curRawAdj != app.setRawAdj) {
17471            app.setRawAdj = app.curRawAdj;
17472        }
17473
17474        int changes = 0;
17475
17476        if (app.curAdj != app.setAdj) {
17477            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17478            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17479                TAG, "Set " + app.pid + " " + app.processName +
17480                " adj " + app.curAdj + ": " + app.adjType);
17481            app.setAdj = app.curAdj;
17482        }
17483
17484        if (app.setSchedGroup != app.curSchedGroup) {
17485            app.setSchedGroup = app.curSchedGroup;
17486            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17487                    "Setting process group of " + app.processName
17488                    + " to " + app.curSchedGroup);
17489            if (app.waitingToKill != null &&
17490                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17491                app.kill(app.waitingToKill, true);
17492                success = false;
17493            } else {
17494                if (true) {
17495                    long oldId = Binder.clearCallingIdentity();
17496                    try {
17497                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17498                    } catch (Exception e) {
17499                        Slog.w(TAG, "Failed setting process group of " + app.pid
17500                                + " to " + app.curSchedGroup);
17501                        e.printStackTrace();
17502                    } finally {
17503                        Binder.restoreCallingIdentity(oldId);
17504                    }
17505                } else {
17506                    if (app.thread != null) {
17507                        try {
17508                            app.thread.setSchedulingGroup(app.curSchedGroup);
17509                        } catch (RemoteException e) {
17510                        }
17511                    }
17512                }
17513                Process.setSwappiness(app.pid,
17514                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17515            }
17516        }
17517        if (app.repForegroundActivities != app.foregroundActivities) {
17518            app.repForegroundActivities = app.foregroundActivities;
17519            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17520        }
17521        if (app.repProcState != app.curProcState) {
17522            app.repProcState = app.curProcState;
17523            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17524            if (app.thread != null) {
17525                try {
17526                    if (false) {
17527                        //RuntimeException h = new RuntimeException("here");
17528                        Slog.i(TAG, "Sending new process state " + app.repProcState
17529                                + " to " + app /*, h*/);
17530                    }
17531                    app.thread.setProcessState(app.repProcState);
17532                } catch (RemoteException e) {
17533                }
17534            }
17535        }
17536        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17537                app.setProcState)) {
17538            app.lastStateTime = now;
17539            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17540                    isSleeping(), now);
17541            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17542                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17543                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17544                    + (app.nextPssTime-now) + ": " + app);
17545        } else {
17546            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17547                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17548                requestPssLocked(app, app.setProcState);
17549                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17550                        isSleeping(), now);
17551            } else if (false && DEBUG_PSS) {
17552                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17553            }
17554        }
17555        if (app.setProcState != app.curProcState) {
17556            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17557                    "Proc state change of " + app.processName
17558                    + " to " + app.curProcState);
17559            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17560            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17561            if (setImportant && !curImportant) {
17562                // This app is no longer something we consider important enough to allow to
17563                // use arbitrary amounts of battery power.  Note
17564                // its current wake lock time to later know to kill it if
17565                // it is not behaving well.
17566                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17567                synchronized (stats) {
17568                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17569                            app.pid, SystemClock.elapsedRealtime());
17570                }
17571                app.lastCpuTime = app.curCpuTime;
17572
17573            }
17574            app.setProcState = app.curProcState;
17575            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17576                app.notCachedSinceIdle = false;
17577            }
17578            if (!doingAll) {
17579                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17580            } else {
17581                app.procStateChanged = true;
17582            }
17583        }
17584
17585        if (changes != 0) {
17586            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17587            int i = mPendingProcessChanges.size()-1;
17588            ProcessChangeItem item = null;
17589            while (i >= 0) {
17590                item = mPendingProcessChanges.get(i);
17591                if (item.pid == app.pid) {
17592                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17593                    break;
17594                }
17595                i--;
17596            }
17597            if (i < 0) {
17598                // No existing item in pending changes; need a new one.
17599                final int NA = mAvailProcessChanges.size();
17600                if (NA > 0) {
17601                    item = mAvailProcessChanges.remove(NA-1);
17602                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17603                } else {
17604                    item = new ProcessChangeItem();
17605                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17606                }
17607                item.changes = 0;
17608                item.pid = app.pid;
17609                item.uid = app.info.uid;
17610                if (mPendingProcessChanges.size() == 0) {
17611                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17612                            "*** Enqueueing dispatch processes changed!");
17613                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17614                }
17615                mPendingProcessChanges.add(item);
17616            }
17617            item.changes |= changes;
17618            item.processState = app.repProcState;
17619            item.foregroundActivities = app.repForegroundActivities;
17620            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17621                    + Integer.toHexString(System.identityHashCode(item))
17622                    + " " + app.toShortString() + ": changes=" + item.changes
17623                    + " procState=" + item.processState
17624                    + " foreground=" + item.foregroundActivities
17625                    + " type=" + app.adjType + " source=" + app.adjSource
17626                    + " target=" + app.adjTarget);
17627        }
17628
17629        return success;
17630    }
17631
17632    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17633        if (proc.thread != null) {
17634            if (proc.baseProcessTracker != null) {
17635                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17636            }
17637            if (proc.repProcState >= 0) {
17638                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17639                        proc.repProcState);
17640            }
17641        }
17642    }
17643
17644    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17645            ProcessRecord TOP_APP, boolean doingAll, long now) {
17646        if (app.thread == null) {
17647            return false;
17648        }
17649
17650        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17651
17652        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17653    }
17654
17655    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17656            boolean oomAdj) {
17657        if (isForeground != proc.foregroundServices) {
17658            proc.foregroundServices = isForeground;
17659            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17660                    proc.info.uid);
17661            if (isForeground) {
17662                if (curProcs == null) {
17663                    curProcs = new ArrayList<ProcessRecord>();
17664                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17665                }
17666                if (!curProcs.contains(proc)) {
17667                    curProcs.add(proc);
17668                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17669                            proc.info.packageName, proc.info.uid);
17670                }
17671            } else {
17672                if (curProcs != null) {
17673                    if (curProcs.remove(proc)) {
17674                        mBatteryStatsService.noteEvent(
17675                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17676                                proc.info.packageName, proc.info.uid);
17677                        if (curProcs.size() <= 0) {
17678                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17679                        }
17680                    }
17681                }
17682            }
17683            if (oomAdj) {
17684                updateOomAdjLocked();
17685            }
17686        }
17687    }
17688
17689    private final ActivityRecord resumedAppLocked() {
17690        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17691        String pkg;
17692        int uid;
17693        if (act != null) {
17694            pkg = act.packageName;
17695            uid = act.info.applicationInfo.uid;
17696        } else {
17697            pkg = null;
17698            uid = -1;
17699        }
17700        // Has the UID or resumed package name changed?
17701        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17702                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17703            if (mCurResumedPackage != null) {
17704                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17705                        mCurResumedPackage, mCurResumedUid);
17706            }
17707            mCurResumedPackage = pkg;
17708            mCurResumedUid = uid;
17709            if (mCurResumedPackage != null) {
17710                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17711                        mCurResumedPackage, mCurResumedUid);
17712            }
17713        }
17714        return act;
17715    }
17716
17717    final boolean updateOomAdjLocked(ProcessRecord app) {
17718        final ActivityRecord TOP_ACT = resumedAppLocked();
17719        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17720        final boolean wasCached = app.cached;
17721
17722        mAdjSeq++;
17723
17724        // This is the desired cached adjusment we want to tell it to use.
17725        // If our app is currently cached, we know it, and that is it.  Otherwise,
17726        // we don't know it yet, and it needs to now be cached we will then
17727        // need to do a complete oom adj.
17728        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17729                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17730        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17731                SystemClock.uptimeMillis());
17732        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17733            // Changed to/from cached state, so apps after it in the LRU
17734            // list may also be changed.
17735            updateOomAdjLocked();
17736        }
17737        return success;
17738    }
17739
17740    final void updateOomAdjLocked() {
17741        final ActivityRecord TOP_ACT = resumedAppLocked();
17742        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17743        final long now = SystemClock.uptimeMillis();
17744        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17745        final int N = mLruProcesses.size();
17746
17747        if (false) {
17748            RuntimeException e = new RuntimeException();
17749            e.fillInStackTrace();
17750            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17751        }
17752
17753        mAdjSeq++;
17754        mNewNumServiceProcs = 0;
17755        mNewNumAServiceProcs = 0;
17756
17757        final int emptyProcessLimit;
17758        final int cachedProcessLimit;
17759        if (mProcessLimit <= 0) {
17760            emptyProcessLimit = cachedProcessLimit = 0;
17761        } else if (mProcessLimit == 1) {
17762            emptyProcessLimit = 1;
17763            cachedProcessLimit = 0;
17764        } else {
17765            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17766            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17767        }
17768
17769        // Let's determine how many processes we have running vs.
17770        // how many slots we have for background processes; we may want
17771        // to put multiple processes in a slot of there are enough of
17772        // them.
17773        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17774                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17775        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17776        if (numEmptyProcs > cachedProcessLimit) {
17777            // If there are more empty processes than our limit on cached
17778            // processes, then use the cached process limit for the factor.
17779            // This ensures that the really old empty processes get pushed
17780            // down to the bottom, so if we are running low on memory we will
17781            // have a better chance at keeping around more cached processes
17782            // instead of a gazillion empty processes.
17783            numEmptyProcs = cachedProcessLimit;
17784        }
17785        int emptyFactor = numEmptyProcs/numSlots;
17786        if (emptyFactor < 1) emptyFactor = 1;
17787        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17788        if (cachedFactor < 1) cachedFactor = 1;
17789        int stepCached = 0;
17790        int stepEmpty = 0;
17791        int numCached = 0;
17792        int numEmpty = 0;
17793        int numTrimming = 0;
17794
17795        mNumNonCachedProcs = 0;
17796        mNumCachedHiddenProcs = 0;
17797
17798        // First update the OOM adjustment for each of the
17799        // application processes based on their current state.
17800        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17801        int nextCachedAdj = curCachedAdj+1;
17802        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17803        int nextEmptyAdj = curEmptyAdj+2;
17804        for (int i=N-1; i>=0; i--) {
17805            ProcessRecord app = mLruProcesses.get(i);
17806            if (!app.killedByAm && app.thread != null) {
17807                app.procStateChanged = false;
17808                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17809
17810                // If we haven't yet assigned the final cached adj
17811                // to the process, do that now.
17812                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17813                    switch (app.curProcState) {
17814                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17815                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17816                            // This process is a cached process holding activities...
17817                            // assign it the next cached value for that type, and then
17818                            // step that cached level.
17819                            app.curRawAdj = curCachedAdj;
17820                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17821                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17822                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17823                                    + ")");
17824                            if (curCachedAdj != nextCachedAdj) {
17825                                stepCached++;
17826                                if (stepCached >= cachedFactor) {
17827                                    stepCached = 0;
17828                                    curCachedAdj = nextCachedAdj;
17829                                    nextCachedAdj += 2;
17830                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17831                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17832                                    }
17833                                }
17834                            }
17835                            break;
17836                        default:
17837                            // For everything else, assign next empty cached process
17838                            // level and bump that up.  Note that this means that
17839                            // long-running services that have dropped down to the
17840                            // cached level will be treated as empty (since their process
17841                            // state is still as a service), which is what we want.
17842                            app.curRawAdj = curEmptyAdj;
17843                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17844                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17845                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17846                                    + ")");
17847                            if (curEmptyAdj != nextEmptyAdj) {
17848                                stepEmpty++;
17849                                if (stepEmpty >= emptyFactor) {
17850                                    stepEmpty = 0;
17851                                    curEmptyAdj = nextEmptyAdj;
17852                                    nextEmptyAdj += 2;
17853                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17854                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17855                                    }
17856                                }
17857                            }
17858                            break;
17859                    }
17860                }
17861
17862                applyOomAdjLocked(app, TOP_APP, true, now);
17863
17864                // Count the number of process types.
17865                switch (app.curProcState) {
17866                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17867                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17868                        mNumCachedHiddenProcs++;
17869                        numCached++;
17870                        if (numCached > cachedProcessLimit) {
17871                            app.kill("cached #" + numCached, true);
17872                        }
17873                        break;
17874                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17875                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17876                                && app.lastActivityTime < oldTime) {
17877                            app.kill("empty for "
17878                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17879                                    / 1000) + "s", true);
17880                        } else {
17881                            numEmpty++;
17882                            if (numEmpty > emptyProcessLimit) {
17883                                app.kill("empty #" + numEmpty, true);
17884                            }
17885                        }
17886                        break;
17887                    default:
17888                        mNumNonCachedProcs++;
17889                        break;
17890                }
17891
17892                if (app.isolated && app.services.size() <= 0) {
17893                    // If this is an isolated process, and there are no
17894                    // services running in it, then the process is no longer
17895                    // needed.  We agressively kill these because we can by
17896                    // definition not re-use the same process again, and it is
17897                    // good to avoid having whatever code was running in them
17898                    // left sitting around after no longer needed.
17899                    app.kill("isolated not needed", true);
17900                }
17901
17902                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17903                        && !app.killedByAm) {
17904                    numTrimming++;
17905                }
17906            }
17907        }
17908
17909        mNumServiceProcs = mNewNumServiceProcs;
17910
17911        // Now determine the memory trimming level of background processes.
17912        // Unfortunately we need to start at the back of the list to do this
17913        // properly.  We only do this if the number of background apps we
17914        // are managing to keep around is less than half the maximum we desire;
17915        // if we are keeping a good number around, we'll let them use whatever
17916        // memory they want.
17917        final int numCachedAndEmpty = numCached + numEmpty;
17918        int memFactor;
17919        if (numCached <= ProcessList.TRIM_CACHED_APPS
17920                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17921            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17922                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17923            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17924                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17925            } else {
17926                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17927            }
17928        } else {
17929            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17930        }
17931        // We always allow the memory level to go up (better).  We only allow it to go
17932        // down if we are in a state where that is allowed, *and* the total number of processes
17933        // has gone down since last time.
17934        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17935                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17936                + " last=" + mLastNumProcesses);
17937        if (memFactor > mLastMemoryLevel) {
17938            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17939                memFactor = mLastMemoryLevel;
17940                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17941            }
17942        }
17943        mLastMemoryLevel = memFactor;
17944        mLastNumProcesses = mLruProcesses.size();
17945        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17946        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17947        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17948            if (mLowRamStartTime == 0) {
17949                mLowRamStartTime = now;
17950            }
17951            int step = 0;
17952            int fgTrimLevel;
17953            switch (memFactor) {
17954                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17955                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17956                    break;
17957                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17958                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17959                    break;
17960                default:
17961                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17962                    break;
17963            }
17964            int factor = numTrimming/3;
17965            int minFactor = 2;
17966            if (mHomeProcess != null) minFactor++;
17967            if (mPreviousProcess != null) minFactor++;
17968            if (factor < minFactor) factor = minFactor;
17969            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17970            for (int i=N-1; i>=0; i--) {
17971                ProcessRecord app = mLruProcesses.get(i);
17972                if (allChanged || app.procStateChanged) {
17973                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17974                    app.procStateChanged = false;
17975                }
17976                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17977                        && !app.killedByAm) {
17978                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17979                        try {
17980                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17981                                    "Trimming memory of " + app.processName
17982                                    + " to " + curLevel);
17983                            app.thread.scheduleTrimMemory(curLevel);
17984                        } catch (RemoteException e) {
17985                        }
17986                        if (false) {
17987                            // For now we won't do this; our memory trimming seems
17988                            // to be good enough at this point that destroying
17989                            // activities causes more harm than good.
17990                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17991                                    && app != mHomeProcess && app != mPreviousProcess) {
17992                                // Need to do this on its own message because the stack may not
17993                                // be in a consistent state at this point.
17994                                // For these apps we will also finish their activities
17995                                // to help them free memory.
17996                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17997                            }
17998                        }
17999                    }
18000                    app.trimMemoryLevel = curLevel;
18001                    step++;
18002                    if (step >= factor) {
18003                        step = 0;
18004                        switch (curLevel) {
18005                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18006                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18007                                break;
18008                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18009                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18010                                break;
18011                        }
18012                    }
18013                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18014                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18015                            && app.thread != null) {
18016                        try {
18017                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18018                                    "Trimming memory of heavy-weight " + app.processName
18019                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18020                            app.thread.scheduleTrimMemory(
18021                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18022                        } catch (RemoteException e) {
18023                        }
18024                    }
18025                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18026                } else {
18027                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18028                            || app.systemNoUi) && app.pendingUiClean) {
18029                        // If this application is now in the background and it
18030                        // had done UI, then give it the special trim level to
18031                        // have it free UI resources.
18032                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18033                        if (app.trimMemoryLevel < level && app.thread != null) {
18034                            try {
18035                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18036                                        "Trimming memory of bg-ui " + app.processName
18037                                        + " to " + level);
18038                                app.thread.scheduleTrimMemory(level);
18039                            } catch (RemoteException e) {
18040                            }
18041                        }
18042                        app.pendingUiClean = false;
18043                    }
18044                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18045                        try {
18046                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18047                                    "Trimming memory of fg " + app.processName
18048                                    + " to " + fgTrimLevel);
18049                            app.thread.scheduleTrimMemory(fgTrimLevel);
18050                        } catch (RemoteException e) {
18051                        }
18052                    }
18053                    app.trimMemoryLevel = fgTrimLevel;
18054                }
18055            }
18056        } else {
18057            if (mLowRamStartTime != 0) {
18058                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18059                mLowRamStartTime = 0;
18060            }
18061            for (int i=N-1; i>=0; i--) {
18062                ProcessRecord app = mLruProcesses.get(i);
18063                if (allChanged || app.procStateChanged) {
18064                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18065                    app.procStateChanged = false;
18066                }
18067                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18068                        || app.systemNoUi) && app.pendingUiClean) {
18069                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18070                            && app.thread != null) {
18071                        try {
18072                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18073                                    "Trimming memory of ui hidden " + app.processName
18074                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18075                            app.thread.scheduleTrimMemory(
18076                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18077                        } catch (RemoteException e) {
18078                        }
18079                    }
18080                    app.pendingUiClean = false;
18081                }
18082                app.trimMemoryLevel = 0;
18083            }
18084        }
18085
18086        if (mAlwaysFinishActivities) {
18087            // Need to do this on its own message because the stack may not
18088            // be in a consistent state at this point.
18089            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18090        }
18091
18092        if (allChanged) {
18093            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18094        }
18095
18096        if (mProcessStats.shouldWriteNowLocked(now)) {
18097            mHandler.post(new Runnable() {
18098                @Override public void run() {
18099                    synchronized (ActivityManagerService.this) {
18100                        mProcessStats.writeStateAsyncLocked();
18101                    }
18102                }
18103            });
18104        }
18105
18106        if (DEBUG_OOM_ADJ) {
18107            if (false) {
18108                RuntimeException here = new RuntimeException("here");
18109                here.fillInStackTrace();
18110                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18111            } else {
18112                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18113            }
18114        }
18115    }
18116
18117    final void trimApplications() {
18118        synchronized (this) {
18119            int i;
18120
18121            // First remove any unused application processes whose package
18122            // has been removed.
18123            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18124                final ProcessRecord app = mRemovedProcesses.get(i);
18125                if (app.activities.size() == 0
18126                        && app.curReceiver == null && app.services.size() == 0) {
18127                    Slog.i(
18128                        TAG, "Exiting empty application process "
18129                        + app.processName + " ("
18130                        + (app.thread != null ? app.thread.asBinder() : null)
18131                        + ")\n");
18132                    if (app.pid > 0 && app.pid != MY_PID) {
18133                        app.kill("empty", false);
18134                    } else {
18135                        try {
18136                            app.thread.scheduleExit();
18137                        } catch (Exception e) {
18138                            // Ignore exceptions.
18139                        }
18140                    }
18141                    cleanUpApplicationRecordLocked(app, false, true, -1);
18142                    mRemovedProcesses.remove(i);
18143
18144                    if (app.persistent) {
18145                        addAppLocked(app.info, false, null /* ABI override */);
18146                    }
18147                }
18148            }
18149
18150            // Now update the oom adj for all processes.
18151            updateOomAdjLocked();
18152        }
18153    }
18154
18155    /** This method sends the specified signal to each of the persistent apps */
18156    public void signalPersistentProcesses(int sig) throws RemoteException {
18157        if (sig != Process.SIGNAL_USR1) {
18158            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18159        }
18160
18161        synchronized (this) {
18162            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18163                    != PackageManager.PERMISSION_GRANTED) {
18164                throw new SecurityException("Requires permission "
18165                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18166            }
18167
18168            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18169                ProcessRecord r = mLruProcesses.get(i);
18170                if (r.thread != null && r.persistent) {
18171                    Process.sendSignal(r.pid, sig);
18172                }
18173            }
18174        }
18175    }
18176
18177    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18178        if (proc == null || proc == mProfileProc) {
18179            proc = mProfileProc;
18180            profileType = mProfileType;
18181            clearProfilerLocked();
18182        }
18183        if (proc == null) {
18184            return;
18185        }
18186        try {
18187            proc.thread.profilerControl(false, null, profileType);
18188        } catch (RemoteException e) {
18189            throw new IllegalStateException("Process disappeared");
18190        }
18191    }
18192
18193    private void clearProfilerLocked() {
18194        if (mProfileFd != null) {
18195            try {
18196                mProfileFd.close();
18197            } catch (IOException e) {
18198            }
18199        }
18200        mProfileApp = null;
18201        mProfileProc = null;
18202        mProfileFile = null;
18203        mProfileType = 0;
18204        mAutoStopProfiler = false;
18205        mSamplingInterval = 0;
18206    }
18207
18208    public boolean profileControl(String process, int userId, boolean start,
18209            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18210
18211        try {
18212            synchronized (this) {
18213                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18214                // its own permission.
18215                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18216                        != PackageManager.PERMISSION_GRANTED) {
18217                    throw new SecurityException("Requires permission "
18218                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18219                }
18220
18221                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18222                    throw new IllegalArgumentException("null profile info or fd");
18223                }
18224
18225                ProcessRecord proc = null;
18226                if (process != null) {
18227                    proc = findProcessLocked(process, userId, "profileControl");
18228                }
18229
18230                if (start && (proc == null || proc.thread == null)) {
18231                    throw new IllegalArgumentException("Unknown process: " + process);
18232                }
18233
18234                if (start) {
18235                    stopProfilerLocked(null, 0);
18236                    setProfileApp(proc.info, proc.processName, profilerInfo);
18237                    mProfileProc = proc;
18238                    mProfileType = profileType;
18239                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18240                    try {
18241                        fd = fd.dup();
18242                    } catch (IOException e) {
18243                        fd = null;
18244                    }
18245                    profilerInfo.profileFd = fd;
18246                    proc.thread.profilerControl(start, profilerInfo, profileType);
18247                    fd = null;
18248                    mProfileFd = null;
18249                } else {
18250                    stopProfilerLocked(proc, profileType);
18251                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18252                        try {
18253                            profilerInfo.profileFd.close();
18254                        } catch (IOException e) {
18255                        }
18256                    }
18257                }
18258
18259                return true;
18260            }
18261        } catch (RemoteException e) {
18262            throw new IllegalStateException("Process disappeared");
18263        } finally {
18264            if (profilerInfo != null && profilerInfo.profileFd != null) {
18265                try {
18266                    profilerInfo.profileFd.close();
18267                } catch (IOException e) {
18268                }
18269            }
18270        }
18271    }
18272
18273    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18274        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18275                userId, true, ALLOW_FULL_ONLY, callName, null);
18276        ProcessRecord proc = null;
18277        try {
18278            int pid = Integer.parseInt(process);
18279            synchronized (mPidsSelfLocked) {
18280                proc = mPidsSelfLocked.get(pid);
18281            }
18282        } catch (NumberFormatException e) {
18283        }
18284
18285        if (proc == null) {
18286            ArrayMap<String, SparseArray<ProcessRecord>> all
18287                    = mProcessNames.getMap();
18288            SparseArray<ProcessRecord> procs = all.get(process);
18289            if (procs != null && procs.size() > 0) {
18290                proc = procs.valueAt(0);
18291                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18292                    for (int i=1; i<procs.size(); i++) {
18293                        ProcessRecord thisProc = procs.valueAt(i);
18294                        if (thisProc.userId == userId) {
18295                            proc = thisProc;
18296                            break;
18297                        }
18298                    }
18299                }
18300            }
18301        }
18302
18303        return proc;
18304    }
18305
18306    public boolean dumpHeap(String process, int userId, boolean managed,
18307            String path, ParcelFileDescriptor fd) throws RemoteException {
18308
18309        try {
18310            synchronized (this) {
18311                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18312                // its own permission (same as profileControl).
18313                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18314                        != PackageManager.PERMISSION_GRANTED) {
18315                    throw new SecurityException("Requires permission "
18316                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18317                }
18318
18319                if (fd == null) {
18320                    throw new IllegalArgumentException("null fd");
18321                }
18322
18323                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18324                if (proc == null || proc.thread == null) {
18325                    throw new IllegalArgumentException("Unknown process: " + process);
18326                }
18327
18328                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18329                if (!isDebuggable) {
18330                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18331                        throw new SecurityException("Process not debuggable: " + proc);
18332                    }
18333                }
18334
18335                proc.thread.dumpHeap(managed, path, fd);
18336                fd = null;
18337                return true;
18338            }
18339        } catch (RemoteException e) {
18340            throw new IllegalStateException("Process disappeared");
18341        } finally {
18342            if (fd != null) {
18343                try {
18344                    fd.close();
18345                } catch (IOException e) {
18346                }
18347            }
18348        }
18349    }
18350
18351    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18352    public void monitor() {
18353        synchronized (this) { }
18354    }
18355
18356    void onCoreSettingsChange(Bundle settings) {
18357        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18358            ProcessRecord processRecord = mLruProcesses.get(i);
18359            try {
18360                if (processRecord.thread != null) {
18361                    processRecord.thread.setCoreSettings(settings);
18362                }
18363            } catch (RemoteException re) {
18364                /* ignore */
18365            }
18366        }
18367    }
18368
18369    // Multi-user methods
18370
18371    /**
18372     * Start user, if its not already running, but don't bring it to foreground.
18373     */
18374    @Override
18375    public boolean startUserInBackground(final int userId) {
18376        return startUser(userId, /* foreground */ false);
18377    }
18378
18379    /**
18380     * Start user, if its not already running, and bring it to foreground.
18381     */
18382    boolean startUserInForeground(final int userId, Dialog dlg) {
18383        boolean result = startUser(userId, /* foreground */ true);
18384        dlg.dismiss();
18385        return result;
18386    }
18387
18388    /**
18389     * Refreshes the list of users related to the current user when either a
18390     * user switch happens or when a new related user is started in the
18391     * background.
18392     */
18393    private void updateCurrentProfileIdsLocked() {
18394        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18395                mCurrentUserId, false /* enabledOnly */);
18396        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18397        for (int i = 0; i < currentProfileIds.length; i++) {
18398            currentProfileIds[i] = profiles.get(i).id;
18399        }
18400        mCurrentProfileIds = currentProfileIds;
18401
18402        synchronized (mUserProfileGroupIdsSelfLocked) {
18403            mUserProfileGroupIdsSelfLocked.clear();
18404            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18405            for (int i = 0; i < users.size(); i++) {
18406                UserInfo user = users.get(i);
18407                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18408                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18409                }
18410            }
18411        }
18412    }
18413
18414    private Set getProfileIdsLocked(int userId) {
18415        Set userIds = new HashSet<Integer>();
18416        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18417                userId, false /* enabledOnly */);
18418        for (UserInfo user : profiles) {
18419            userIds.add(Integer.valueOf(user.id));
18420        }
18421        return userIds;
18422    }
18423
18424    @Override
18425    public boolean switchUser(final int userId) {
18426        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18427        String userName;
18428        synchronized (this) {
18429            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18430            if (userInfo == null) {
18431                Slog.w(TAG, "No user info for user #" + userId);
18432                return false;
18433            }
18434            if (userInfo.isManagedProfile()) {
18435                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18436                return false;
18437            }
18438            userName = userInfo.name;
18439            mTargetUserId = userId;
18440        }
18441        mHandler.removeMessages(START_USER_SWITCH_MSG);
18442        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18443        return true;
18444    }
18445
18446    private void showUserSwitchDialog(int userId, String userName) {
18447        // The dialog will show and then initiate the user switch by calling startUserInForeground
18448        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18449                true /* above system */);
18450        d.show();
18451    }
18452
18453    private boolean startUser(final int userId, final boolean foreground) {
18454        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18455                != PackageManager.PERMISSION_GRANTED) {
18456            String msg = "Permission Denial: switchUser() from pid="
18457                    + Binder.getCallingPid()
18458                    + ", uid=" + Binder.getCallingUid()
18459                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18460            Slog.w(TAG, msg);
18461            throw new SecurityException(msg);
18462        }
18463
18464        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18465
18466        final long ident = Binder.clearCallingIdentity();
18467        try {
18468            synchronized (this) {
18469                final int oldUserId = mCurrentUserId;
18470                if (oldUserId == userId) {
18471                    return true;
18472                }
18473
18474                mStackSupervisor.setLockTaskModeLocked(null, false);
18475
18476                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18477                if (userInfo == null) {
18478                    Slog.w(TAG, "No user info for user #" + userId);
18479                    return false;
18480                }
18481                if (foreground && userInfo.isManagedProfile()) {
18482                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18483                    return false;
18484                }
18485
18486                if (foreground) {
18487                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18488                            R.anim.screen_user_enter);
18489                }
18490
18491                boolean needStart = false;
18492
18493                // If the user we are switching to is not currently started, then
18494                // we need to start it now.
18495                if (mStartedUsers.get(userId) == null) {
18496                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18497                    updateStartedUserArrayLocked();
18498                    needStart = true;
18499                }
18500
18501                final Integer userIdInt = Integer.valueOf(userId);
18502                mUserLru.remove(userIdInt);
18503                mUserLru.add(userIdInt);
18504
18505                if (foreground) {
18506                    mCurrentUserId = userId;
18507                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18508                    updateCurrentProfileIdsLocked();
18509                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18510                    // Once the internal notion of the active user has switched, we lock the device
18511                    // with the option to show the user switcher on the keyguard.
18512                    mWindowManager.lockNow(null);
18513                } else {
18514                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18515                    updateCurrentProfileIdsLocked();
18516                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18517                    mUserLru.remove(currentUserIdInt);
18518                    mUserLru.add(currentUserIdInt);
18519                }
18520
18521                final UserStartedState uss = mStartedUsers.get(userId);
18522
18523                // Make sure user is in the started state.  If it is currently
18524                // stopping, we need to knock that off.
18525                if (uss.mState == UserStartedState.STATE_STOPPING) {
18526                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18527                    // so we can just fairly silently bring the user back from
18528                    // the almost-dead.
18529                    uss.mState = UserStartedState.STATE_RUNNING;
18530                    updateStartedUserArrayLocked();
18531                    needStart = true;
18532                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18533                    // This means ACTION_SHUTDOWN has been sent, so we will
18534                    // need to treat this as a new boot of the user.
18535                    uss.mState = UserStartedState.STATE_BOOTING;
18536                    updateStartedUserArrayLocked();
18537                    needStart = true;
18538                }
18539
18540                if (uss.mState == UserStartedState.STATE_BOOTING) {
18541                    // Booting up a new user, need to tell system services about it.
18542                    // Note that this is on the same handler as scheduling of broadcasts,
18543                    // which is important because it needs to go first.
18544                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18545                }
18546
18547                if (foreground) {
18548                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18549                            oldUserId));
18550                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18551                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18552                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18553                            oldUserId, userId, uss));
18554                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18555                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18556                }
18557
18558                if (needStart) {
18559                    // Send USER_STARTED broadcast
18560                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18561                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18562                            | Intent.FLAG_RECEIVER_FOREGROUND);
18563                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18564                    broadcastIntentLocked(null, null, intent,
18565                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18566                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18567                }
18568
18569                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18570                    if (userId != UserHandle.USER_OWNER) {
18571                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18572                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18573                        broadcastIntentLocked(null, null, intent, null,
18574                                new IIntentReceiver.Stub() {
18575                                    public void performReceive(Intent intent, int resultCode,
18576                                            String data, Bundle extras, boolean ordered,
18577                                            boolean sticky, int sendingUser) {
18578                                        onUserInitialized(uss, foreground, oldUserId, userId);
18579                                    }
18580                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18581                                true, false, MY_PID, Process.SYSTEM_UID,
18582                                userId);
18583                        uss.initializing = true;
18584                    } else {
18585                        getUserManagerLocked().makeInitialized(userInfo.id);
18586                    }
18587                }
18588
18589                if (foreground) {
18590                    if (!uss.initializing) {
18591                        moveUserToForeground(uss, oldUserId, userId);
18592                    }
18593                } else {
18594                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18595                }
18596
18597                if (needStart) {
18598                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18599                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18600                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18601                    broadcastIntentLocked(null, null, intent,
18602                            null, new IIntentReceiver.Stub() {
18603                                @Override
18604                                public void performReceive(Intent intent, int resultCode, String data,
18605                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18606                                        throws RemoteException {
18607                                }
18608                            }, 0, null, null,
18609                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18610                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18611                }
18612            }
18613        } finally {
18614            Binder.restoreCallingIdentity(ident);
18615        }
18616
18617        return true;
18618    }
18619
18620    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18621        long ident = Binder.clearCallingIdentity();
18622        try {
18623            Intent intent;
18624            if (oldUserId >= 0) {
18625                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18626                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18627                int count = profiles.size();
18628                for (int i = 0; i < count; i++) {
18629                    int profileUserId = profiles.get(i).id;
18630                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18631                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18632                            | Intent.FLAG_RECEIVER_FOREGROUND);
18633                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18634                    broadcastIntentLocked(null, null, intent,
18635                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18636                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18637                }
18638            }
18639            if (newUserId >= 0) {
18640                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18641                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18642                int count = profiles.size();
18643                for (int i = 0; i < count; i++) {
18644                    int profileUserId = profiles.get(i).id;
18645                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18646                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18647                            | Intent.FLAG_RECEIVER_FOREGROUND);
18648                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18649                    broadcastIntentLocked(null, null, intent,
18650                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18651                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18652                }
18653                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18654                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18655                        | Intent.FLAG_RECEIVER_FOREGROUND);
18656                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18657                broadcastIntentLocked(null, null, intent,
18658                        null, null, 0, null, null,
18659                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18660                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18661            }
18662        } finally {
18663            Binder.restoreCallingIdentity(ident);
18664        }
18665    }
18666
18667    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18668            final int newUserId) {
18669        final int N = mUserSwitchObservers.beginBroadcast();
18670        if (N > 0) {
18671            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18672                int mCount = 0;
18673                @Override
18674                public void sendResult(Bundle data) throws RemoteException {
18675                    synchronized (ActivityManagerService.this) {
18676                        if (mCurUserSwitchCallback == this) {
18677                            mCount++;
18678                            if (mCount == N) {
18679                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18680                            }
18681                        }
18682                    }
18683                }
18684            };
18685            synchronized (this) {
18686                uss.switching = true;
18687                mCurUserSwitchCallback = callback;
18688            }
18689            for (int i=0; i<N; i++) {
18690                try {
18691                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18692                            newUserId, callback);
18693                } catch (RemoteException e) {
18694                }
18695            }
18696        } else {
18697            synchronized (this) {
18698                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18699            }
18700        }
18701        mUserSwitchObservers.finishBroadcast();
18702    }
18703
18704    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18705        synchronized (this) {
18706            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18707            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18708        }
18709    }
18710
18711    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18712        mCurUserSwitchCallback = null;
18713        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18714        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18715                oldUserId, newUserId, uss));
18716    }
18717
18718    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18719        synchronized (this) {
18720            if (foreground) {
18721                moveUserToForeground(uss, oldUserId, newUserId);
18722            }
18723        }
18724
18725        completeSwitchAndInitalize(uss, newUserId, true, false);
18726    }
18727
18728    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18729        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18730        if (homeInFront) {
18731            startHomeActivityLocked(newUserId);
18732        } else {
18733            mStackSupervisor.resumeTopActivitiesLocked();
18734        }
18735        EventLogTags.writeAmSwitchUser(newUserId);
18736        getUserManagerLocked().userForeground(newUserId);
18737        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18738    }
18739
18740    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18741        completeSwitchAndInitalize(uss, newUserId, false, true);
18742    }
18743
18744    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18745            boolean clearInitializing, boolean clearSwitching) {
18746        boolean unfrozen = false;
18747        synchronized (this) {
18748            if (clearInitializing) {
18749                uss.initializing = false;
18750                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18751            }
18752            if (clearSwitching) {
18753                uss.switching = false;
18754            }
18755            if (!uss.switching && !uss.initializing) {
18756                mWindowManager.stopFreezingScreen();
18757                unfrozen = true;
18758            }
18759        }
18760        if (unfrozen) {
18761            final int N = mUserSwitchObservers.beginBroadcast();
18762            for (int i=0; i<N; i++) {
18763                try {
18764                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18765                } catch (RemoteException e) {
18766                }
18767            }
18768            mUserSwitchObservers.finishBroadcast();
18769        }
18770    }
18771
18772    void scheduleStartProfilesLocked() {
18773        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18774            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18775                    DateUtils.SECOND_IN_MILLIS);
18776        }
18777    }
18778
18779    void startProfilesLocked() {
18780        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18781        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18782                mCurrentUserId, false /* enabledOnly */);
18783        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18784        for (UserInfo user : profiles) {
18785            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18786                    && user.id != mCurrentUserId) {
18787                toStart.add(user);
18788            }
18789        }
18790        final int n = toStart.size();
18791        int i = 0;
18792        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18793            startUserInBackground(toStart.get(i).id);
18794        }
18795        if (i < n) {
18796            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18797        }
18798    }
18799
18800    void finishUserBoot(UserStartedState uss) {
18801        synchronized (this) {
18802            if (uss.mState == UserStartedState.STATE_BOOTING
18803                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18804                uss.mState = UserStartedState.STATE_RUNNING;
18805                final int userId = uss.mHandle.getIdentifier();
18806                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18807                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18808                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18809                broadcastIntentLocked(null, null, intent,
18810                        null, null, 0, null, null,
18811                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18812                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18813            }
18814        }
18815    }
18816
18817    void finishUserSwitch(UserStartedState uss) {
18818        synchronized (this) {
18819            finishUserBoot(uss);
18820
18821            startProfilesLocked();
18822
18823            int num = mUserLru.size();
18824            int i = 0;
18825            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18826                Integer oldUserId = mUserLru.get(i);
18827                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18828                if (oldUss == null) {
18829                    // Shouldn't happen, but be sane if it does.
18830                    mUserLru.remove(i);
18831                    num--;
18832                    continue;
18833                }
18834                if (oldUss.mState == UserStartedState.STATE_STOPPING
18835                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18836                    // This user is already stopping, doesn't count.
18837                    num--;
18838                    i++;
18839                    continue;
18840                }
18841                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18842                    // Owner and current can't be stopped, but count as running.
18843                    i++;
18844                    continue;
18845                }
18846                // This is a user to be stopped.
18847                stopUserLocked(oldUserId, null);
18848                num--;
18849                i++;
18850            }
18851        }
18852    }
18853
18854    @Override
18855    public int stopUser(final int userId, final IStopUserCallback callback) {
18856        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18857                != PackageManager.PERMISSION_GRANTED) {
18858            String msg = "Permission Denial: switchUser() from pid="
18859                    + Binder.getCallingPid()
18860                    + ", uid=" + Binder.getCallingUid()
18861                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18862            Slog.w(TAG, msg);
18863            throw new SecurityException(msg);
18864        }
18865        if (userId <= 0) {
18866            throw new IllegalArgumentException("Can't stop primary user " + userId);
18867        }
18868        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18869        synchronized (this) {
18870            return stopUserLocked(userId, callback);
18871        }
18872    }
18873
18874    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18875        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18876        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18877            return ActivityManager.USER_OP_IS_CURRENT;
18878        }
18879
18880        final UserStartedState uss = mStartedUsers.get(userId);
18881        if (uss == null) {
18882            // User is not started, nothing to do...  but we do need to
18883            // callback if requested.
18884            if (callback != null) {
18885                mHandler.post(new Runnable() {
18886                    @Override
18887                    public void run() {
18888                        try {
18889                            callback.userStopped(userId);
18890                        } catch (RemoteException e) {
18891                        }
18892                    }
18893                });
18894            }
18895            return ActivityManager.USER_OP_SUCCESS;
18896        }
18897
18898        if (callback != null) {
18899            uss.mStopCallbacks.add(callback);
18900        }
18901
18902        if (uss.mState != UserStartedState.STATE_STOPPING
18903                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18904            uss.mState = UserStartedState.STATE_STOPPING;
18905            updateStartedUserArrayLocked();
18906
18907            long ident = Binder.clearCallingIdentity();
18908            try {
18909                // We are going to broadcast ACTION_USER_STOPPING and then
18910                // once that is done send a final ACTION_SHUTDOWN and then
18911                // stop the user.
18912                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18913                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18914                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18915                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18916                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18917                // This is the result receiver for the final shutdown broadcast.
18918                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18919                    @Override
18920                    public void performReceive(Intent intent, int resultCode, String data,
18921                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18922                        finishUserStop(uss);
18923                    }
18924                };
18925                // This is the result receiver for the initial stopping broadcast.
18926                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18927                    @Override
18928                    public void performReceive(Intent intent, int resultCode, String data,
18929                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18930                        // On to the next.
18931                        synchronized (ActivityManagerService.this) {
18932                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18933                                // Whoops, we are being started back up.  Abort, abort!
18934                                return;
18935                            }
18936                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18937                        }
18938                        mBatteryStatsService.noteEvent(
18939                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18940                                Integer.toString(userId), userId);
18941                        mSystemServiceManager.stopUser(userId);
18942                        broadcastIntentLocked(null, null, shutdownIntent,
18943                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18944                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18945                    }
18946                };
18947                // Kick things off.
18948                broadcastIntentLocked(null, null, stoppingIntent,
18949                        null, stoppingReceiver, 0, null, null,
18950                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18951                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18952            } finally {
18953                Binder.restoreCallingIdentity(ident);
18954            }
18955        }
18956
18957        return ActivityManager.USER_OP_SUCCESS;
18958    }
18959
18960    void finishUserStop(UserStartedState uss) {
18961        final int userId = uss.mHandle.getIdentifier();
18962        boolean stopped;
18963        ArrayList<IStopUserCallback> callbacks;
18964        synchronized (this) {
18965            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18966            if (mStartedUsers.get(userId) != uss) {
18967                stopped = false;
18968            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18969                stopped = false;
18970            } else {
18971                stopped = true;
18972                // User can no longer run.
18973                mStartedUsers.remove(userId);
18974                mUserLru.remove(Integer.valueOf(userId));
18975                updateStartedUserArrayLocked();
18976
18977                // Clean up all state and processes associated with the user.
18978                // Kill all the processes for the user.
18979                forceStopUserLocked(userId, "finish user");
18980            }
18981
18982            // Explicitly remove the old information in mRecentTasks.
18983            removeRecentTasksForUserLocked(userId);
18984        }
18985
18986        for (int i=0; i<callbacks.size(); i++) {
18987            try {
18988                if (stopped) callbacks.get(i).userStopped(userId);
18989                else callbacks.get(i).userStopAborted(userId);
18990            } catch (RemoteException e) {
18991            }
18992        }
18993
18994        if (stopped) {
18995            mSystemServiceManager.cleanupUser(userId);
18996            synchronized (this) {
18997                mStackSupervisor.removeUserLocked(userId);
18998            }
18999        }
19000    }
19001
19002    @Override
19003    public UserInfo getCurrentUser() {
19004        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
19005                != PackageManager.PERMISSION_GRANTED) && (
19006                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19007                != PackageManager.PERMISSION_GRANTED)) {
19008            String msg = "Permission Denial: getCurrentUser() from pid="
19009                    + Binder.getCallingPid()
19010                    + ", uid=" + Binder.getCallingUid()
19011                    + " requires " + INTERACT_ACROSS_USERS;
19012            Slog.w(TAG, msg);
19013            throw new SecurityException(msg);
19014        }
19015        synchronized (this) {
19016            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19017            return getUserManagerLocked().getUserInfo(userId);
19018        }
19019    }
19020
19021    int getCurrentUserIdLocked() {
19022        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19023    }
19024
19025    @Override
19026    public boolean isUserRunning(int userId, boolean orStopped) {
19027        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19028                != PackageManager.PERMISSION_GRANTED) {
19029            String msg = "Permission Denial: isUserRunning() from pid="
19030                    + Binder.getCallingPid()
19031                    + ", uid=" + Binder.getCallingUid()
19032                    + " requires " + INTERACT_ACROSS_USERS;
19033            Slog.w(TAG, msg);
19034            throw new SecurityException(msg);
19035        }
19036        synchronized (this) {
19037            return isUserRunningLocked(userId, orStopped);
19038        }
19039    }
19040
19041    boolean isUserRunningLocked(int userId, boolean orStopped) {
19042        UserStartedState state = mStartedUsers.get(userId);
19043        if (state == null) {
19044            return false;
19045        }
19046        if (orStopped) {
19047            return true;
19048        }
19049        return state.mState != UserStartedState.STATE_STOPPING
19050                && state.mState != UserStartedState.STATE_SHUTDOWN;
19051    }
19052
19053    @Override
19054    public int[] getRunningUserIds() {
19055        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19056                != PackageManager.PERMISSION_GRANTED) {
19057            String msg = "Permission Denial: isUserRunning() from pid="
19058                    + Binder.getCallingPid()
19059                    + ", uid=" + Binder.getCallingUid()
19060                    + " requires " + INTERACT_ACROSS_USERS;
19061            Slog.w(TAG, msg);
19062            throw new SecurityException(msg);
19063        }
19064        synchronized (this) {
19065            return mStartedUserArray;
19066        }
19067    }
19068
19069    private void updateStartedUserArrayLocked() {
19070        int num = 0;
19071        for (int i=0; i<mStartedUsers.size();  i++) {
19072            UserStartedState uss = mStartedUsers.valueAt(i);
19073            // This list does not include stopping users.
19074            if (uss.mState != UserStartedState.STATE_STOPPING
19075                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19076                num++;
19077            }
19078        }
19079        mStartedUserArray = new int[num];
19080        num = 0;
19081        for (int i=0; i<mStartedUsers.size();  i++) {
19082            UserStartedState uss = mStartedUsers.valueAt(i);
19083            if (uss.mState != UserStartedState.STATE_STOPPING
19084                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19085                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19086                num++;
19087            }
19088        }
19089    }
19090
19091    @Override
19092    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19093        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19094                != PackageManager.PERMISSION_GRANTED) {
19095            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19096                    + Binder.getCallingPid()
19097                    + ", uid=" + Binder.getCallingUid()
19098                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19099            Slog.w(TAG, msg);
19100            throw new SecurityException(msg);
19101        }
19102
19103        mUserSwitchObservers.register(observer);
19104    }
19105
19106    @Override
19107    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19108        mUserSwitchObservers.unregister(observer);
19109    }
19110
19111    private boolean userExists(int userId) {
19112        if (userId == 0) {
19113            return true;
19114        }
19115        UserManagerService ums = getUserManagerLocked();
19116        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19117    }
19118
19119    int[] getUsersLocked() {
19120        UserManagerService ums = getUserManagerLocked();
19121        return ums != null ? ums.getUserIds() : new int[] { 0 };
19122    }
19123
19124    UserManagerService getUserManagerLocked() {
19125        if (mUserManager == null) {
19126            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19127            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19128        }
19129        return mUserManager;
19130    }
19131
19132    private int applyUserId(int uid, int userId) {
19133        return UserHandle.getUid(userId, uid);
19134    }
19135
19136    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19137        if (info == null) return null;
19138        ApplicationInfo newInfo = new ApplicationInfo(info);
19139        newInfo.uid = applyUserId(info.uid, userId);
19140        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19141                + info.packageName;
19142        return newInfo;
19143    }
19144
19145    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19146        if (aInfo == null
19147                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19148            return aInfo;
19149        }
19150
19151        ActivityInfo info = new ActivityInfo(aInfo);
19152        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19153        return info;
19154    }
19155
19156    private final class LocalService extends ActivityManagerInternal {
19157        @Override
19158        public void goingToSleep() {
19159            ActivityManagerService.this.goingToSleep();
19160        }
19161
19162        @Override
19163        public void wakingUp() {
19164            ActivityManagerService.this.wakingUp();
19165        }
19166
19167        @Override
19168        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19169                String processName, String abiOverride, int uid, Runnable crashHandler) {
19170            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19171                    processName, abiOverride, uid, crashHandler);
19172        }
19173    }
19174
19175    /**
19176     * An implementation of IAppTask, that allows an app to manage its own tasks via
19177     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19178     * only the process that calls getAppTasks() can call the AppTask methods.
19179     */
19180    class AppTaskImpl extends IAppTask.Stub {
19181        private int mTaskId;
19182        private int mCallingUid;
19183
19184        public AppTaskImpl(int taskId, int callingUid) {
19185            mTaskId = taskId;
19186            mCallingUid = callingUid;
19187        }
19188
19189        private void checkCaller() {
19190            if (mCallingUid != Binder.getCallingUid()) {
19191                throw new SecurityException("Caller " + mCallingUid
19192                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19193            }
19194        }
19195
19196        @Override
19197        public void finishAndRemoveTask() {
19198            checkCaller();
19199
19200            synchronized (ActivityManagerService.this) {
19201                long origId = Binder.clearCallingIdentity();
19202                try {
19203                    if (!removeTaskByIdLocked(mTaskId, false)) {
19204                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19205                    }
19206                } finally {
19207                    Binder.restoreCallingIdentity(origId);
19208                }
19209            }
19210        }
19211
19212        @Override
19213        public ActivityManager.RecentTaskInfo getTaskInfo() {
19214            checkCaller();
19215
19216            synchronized (ActivityManagerService.this) {
19217                long origId = Binder.clearCallingIdentity();
19218                try {
19219                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19220                    if (tr == null) {
19221                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19222                    }
19223                    return createRecentTaskInfoFromTaskRecord(tr);
19224                } finally {
19225                    Binder.restoreCallingIdentity(origId);
19226                }
19227            }
19228        }
19229
19230        @Override
19231        public void moveToFront() {
19232            checkCaller();
19233
19234            final TaskRecord tr;
19235            synchronized (ActivityManagerService.this) {
19236                tr = recentTaskForIdLocked(mTaskId);
19237                if (tr == null) {
19238                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19239                }
19240                if (tr.getRootActivity() != null) {
19241                    moveTaskToFrontLocked(tr.taskId, 0, null);
19242                    return;
19243                }
19244            }
19245
19246            startActivityFromRecentsInner(tr.taskId, null);
19247        }
19248
19249        @Override
19250        public int startActivity(IBinder whoThread, String callingPackage,
19251                Intent intent, String resolvedType, Bundle options) {
19252            checkCaller();
19253
19254            int callingUser = UserHandle.getCallingUserId();
19255            TaskRecord tr;
19256            IApplicationThread appThread;
19257            synchronized (ActivityManagerService.this) {
19258                tr = recentTaskForIdLocked(mTaskId);
19259                if (tr == null) {
19260                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19261                }
19262                appThread = ApplicationThreadNative.asInterface(whoThread);
19263                if (appThread == null) {
19264                    throw new IllegalArgumentException("Bad app thread " + appThread);
19265                }
19266            }
19267            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19268                    resolvedType, null, null, null, null, 0, 0, null, null,
19269                    null, options, callingUser, null, tr);
19270        }
19271
19272        @Override
19273        public void setExcludeFromRecents(boolean exclude) {
19274            checkCaller();
19275
19276            synchronized (ActivityManagerService.this) {
19277                long origId = Binder.clearCallingIdentity();
19278                try {
19279                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19280                    if (tr == null) {
19281                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19282                    }
19283                    Intent intent = tr.getBaseIntent();
19284                    if (exclude) {
19285                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19286                    } else {
19287                        intent.setFlags(intent.getFlags()
19288                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19289                    }
19290                } finally {
19291                    Binder.restoreCallingIdentity(origId);
19292                }
19293            }
19294        }
19295    }
19296}
19297