ActivityManagerService.java revision ce09f5a53c8408d995c116a4430c000574d9875a
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    /**
956     * State of external call telling us if the lock screen is shown.
957     */
958    private boolean mLockScreenShown = false;
959
960    /**
961     * Set if we are shutting down the system, similar to sleeping.
962     */
963    boolean mShuttingDown = false;
964
965    /**
966     * Current sequence id for oom_adj computation traversal.
967     */
968    int mAdjSeq = 0;
969
970    /**
971     * Current sequence id for process LRU updating.
972     */
973    int mLruSeq = 0;
974
975    /**
976     * Keep track of the non-cached/empty process we last found, to help
977     * determine how to distribute cached/empty processes next time.
978     */
979    int mNumNonCachedProcs = 0;
980
981    /**
982     * Keep track of the number of cached hidden procs, to balance oom adj
983     * distribution between those and empty procs.
984     */
985    int mNumCachedHiddenProcs = 0;
986
987    /**
988     * Keep track of the number of service processes we last found, to
989     * determine on the next iteration which should be B services.
990     */
991    int mNumServiceProcs = 0;
992    int mNewNumAServiceProcs = 0;
993    int mNewNumServiceProcs = 0;
994
995    /**
996     * Allow the current computed overall memory level of the system to go down?
997     * This is set to false when we are killing processes for reasons other than
998     * memory management, so that the now smaller process list will not be taken as
999     * an indication that memory is tighter.
1000     */
1001    boolean mAllowLowerMemLevel = false;
1002
1003    /**
1004     * The last computed memory level, for holding when we are in a state that
1005     * processes are going away for other reasons.
1006     */
1007    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1008
1009    /**
1010     * The last total number of process we have, to determine if changes actually look
1011     * like a shrinking number of process due to lower RAM.
1012     */
1013    int mLastNumProcesses;
1014
1015    /**
1016     * The uptime of the last time we performed idle maintenance.
1017     */
1018    long mLastIdleTime = SystemClock.uptimeMillis();
1019
1020    /**
1021     * Total time spent with RAM that has been added in the past since the last idle time.
1022     */
1023    long mLowRamTimeSinceLastIdle = 0;
1024
1025    /**
1026     * If RAM is currently low, when that horrible situation started.
1027     */
1028    long mLowRamStartTime = 0;
1029
1030    /**
1031     * For reporting to battery stats the current top application.
1032     */
1033    private String mCurResumedPackage = null;
1034    private int mCurResumedUid = -1;
1035
1036    /**
1037     * For reporting to battery stats the apps currently running foreground
1038     * service.  The ProcessMap is package/uid tuples; each of these contain
1039     * an array of the currently foreground processes.
1040     */
1041    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1042            = new ProcessMap<ArrayList<ProcessRecord>>();
1043
1044    /**
1045     * This is set if we had to do a delayed dexopt of an app before launching
1046     * it, to increase the ANR timeouts in that case.
1047     */
1048    boolean mDidDexOpt;
1049
1050    /**
1051     * Set if the systemServer made a call to enterSafeMode.
1052     */
1053    boolean mSafeMode;
1054
1055    String mDebugApp = null;
1056    boolean mWaitForDebugger = false;
1057    boolean mDebugTransient = false;
1058    String mOrigDebugApp = null;
1059    boolean mOrigWaitForDebugger = false;
1060    boolean mAlwaysFinishActivities = false;
1061    IActivityController mController = null;
1062    String mProfileApp = null;
1063    ProcessRecord mProfileProc = null;
1064    String mProfileFile;
1065    ParcelFileDescriptor mProfileFd;
1066    int mSamplingInterval = 0;
1067    boolean mAutoStopProfiler = false;
1068    int mProfileType = 0;
1069    String mOpenGlTraceApp = null;
1070
1071    static class ProcessChangeItem {
1072        static final int CHANGE_ACTIVITIES = 1<<0;
1073        static final int CHANGE_PROCESS_STATE = 1<<1;
1074        int changes;
1075        int uid;
1076        int pid;
1077        int processState;
1078        boolean foregroundActivities;
1079    }
1080
1081    final RemoteCallbackList<IProcessObserver> mProcessObservers
1082            = new RemoteCallbackList<IProcessObserver>();
1083    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1084
1085    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1086            = new ArrayList<ProcessChangeItem>();
1087    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1088            = new ArrayList<ProcessChangeItem>();
1089
1090    /**
1091     * Runtime CPU use collection thread.  This object's lock is used to
1092     * perform synchronization with the thread (notifying it to run).
1093     */
1094    final Thread mProcessCpuThread;
1095
1096    /**
1097     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1098     * Must acquire this object's lock when accessing it.
1099     * NOTE: this lock will be held while doing long operations (trawling
1100     * through all processes in /proc), so it should never be acquired by
1101     * any critical paths such as when holding the main activity manager lock.
1102     */
1103    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1104            MONITOR_THREAD_CPU_USAGE);
1105    final AtomicLong mLastCpuTime = new AtomicLong(0);
1106    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1107
1108    long mLastWriteTime = 0;
1109
1110    /**
1111     * Used to retain an update lock when the foreground activity is in
1112     * immersive mode.
1113     */
1114    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1115
1116    /**
1117     * Set to true after the system has finished booting.
1118     */
1119    boolean mBooted = false;
1120
1121    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1122    int mProcessLimitOverride = -1;
1123
1124    WindowManagerService mWindowManager;
1125
1126    final ActivityThread mSystemThread;
1127
1128    // Holds the current foreground user's id
1129    int mCurrentUserId = 0;
1130    // Holds the target user's id during a user switch
1131    int mTargetUserId = UserHandle.USER_NULL;
1132    // If there are multiple profiles for the current user, their ids are here
1133    // Currently only the primary user can have managed profiles
1134    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1135
1136    /**
1137     * Mapping from each known user ID to the profile group ID it is associated with.
1138     */
1139    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1140
1141    private UserManagerService mUserManager;
1142
1143    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1144        final ProcessRecord mApp;
1145        final int mPid;
1146        final IApplicationThread mAppThread;
1147
1148        AppDeathRecipient(ProcessRecord app, int pid,
1149                IApplicationThread thread) {
1150            if (localLOGV) Slog.v(
1151                TAG, "New death recipient " + this
1152                + " for thread " + thread.asBinder());
1153            mApp = app;
1154            mPid = pid;
1155            mAppThread = thread;
1156        }
1157
1158        @Override
1159        public void binderDied() {
1160            if (localLOGV) Slog.v(
1161                TAG, "Death received in " + this
1162                + " for thread " + mAppThread.asBinder());
1163            synchronized(ActivityManagerService.this) {
1164                appDiedLocked(mApp, mPid, mAppThread);
1165            }
1166        }
1167    }
1168
1169    static final int SHOW_ERROR_MSG = 1;
1170    static final int SHOW_NOT_RESPONDING_MSG = 2;
1171    static final int SHOW_FACTORY_ERROR_MSG = 3;
1172    static final int UPDATE_CONFIGURATION_MSG = 4;
1173    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1174    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1175    static final int SERVICE_TIMEOUT_MSG = 12;
1176    static final int UPDATE_TIME_ZONE = 13;
1177    static final int SHOW_UID_ERROR_MSG = 14;
1178    static final int IM_FEELING_LUCKY_MSG = 15;
1179    static final int PROC_START_TIMEOUT_MSG = 20;
1180    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1181    static final int KILL_APPLICATION_MSG = 22;
1182    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1183    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1184    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1185    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1186    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1187    static final int CLEAR_DNS_CACHE_MSG = 28;
1188    static final int UPDATE_HTTP_PROXY_MSG = 29;
1189    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1190    static final int DISPATCH_PROCESSES_CHANGED = 31;
1191    static final int DISPATCH_PROCESS_DIED = 32;
1192    static final int REPORT_MEM_USAGE_MSG = 33;
1193    static final int REPORT_USER_SWITCH_MSG = 34;
1194    static final int CONTINUE_USER_SWITCH_MSG = 35;
1195    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1196    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1197    static final int PERSIST_URI_GRANTS_MSG = 38;
1198    static final int REQUEST_ALL_PSS_MSG = 39;
1199    static final int START_PROFILES_MSG = 40;
1200    static final int UPDATE_TIME = 41;
1201    static final int SYSTEM_USER_START_MSG = 42;
1202    static final int SYSTEM_USER_CURRENT_MSG = 43;
1203    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1204    static final int FINISH_BOOTING_MSG = 45;
1205    static final int START_USER_SWITCH_MSG = 46;
1206    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1207
1208    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1209    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1210    static final int FIRST_COMPAT_MODE_MSG = 300;
1211    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1212
1213    AlertDialog mUidAlert;
1214    CompatModeDialog mCompatModeDialog;
1215    long mLastMemUsageReportTime = 0;
1216
1217    private LockToAppRequestDialog mLockToAppRequest;
1218
1219    /**
1220     * Flag whether the current user is a "monkey", i.e. whether
1221     * the UI is driven by a UI automation tool.
1222     */
1223    private boolean mUserIsMonkey;
1224
1225    /** Flag whether the device has a Recents UI */
1226    boolean mHasRecents;
1227
1228    /** The dimensions of the thumbnails in the Recents UI. */
1229    int mThumbnailWidth;
1230    int mThumbnailHeight;
1231
1232    final ServiceThread mHandlerThread;
1233    final MainHandler mHandler;
1234
1235    final class MainHandler extends Handler {
1236        public MainHandler(Looper looper) {
1237            super(looper, null, true);
1238        }
1239
1240        @Override
1241        public void handleMessage(Message msg) {
1242            switch (msg.what) {
1243            case SHOW_ERROR_MSG: {
1244                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1245                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1246                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1247                synchronized (ActivityManagerService.this) {
1248                    ProcessRecord proc = (ProcessRecord)data.get("app");
1249                    AppErrorResult res = (AppErrorResult) data.get("result");
1250                    if (proc != null && proc.crashDialog != null) {
1251                        Slog.e(TAG, "App already has crash dialog: " + proc);
1252                        if (res != null) {
1253                            res.set(0);
1254                        }
1255                        return;
1256                    }
1257                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1258                            >= Process.FIRST_APPLICATION_UID
1259                            && proc.pid != MY_PID);
1260                    for (int userId : mCurrentProfileIds) {
1261                        isBackground &= (proc.userId != userId);
1262                    }
1263                    if (isBackground && !showBackground) {
1264                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1265                        if (res != null) {
1266                            res.set(0);
1267                        }
1268                        return;
1269                    }
1270                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1271                        Dialog d = new AppErrorDialog(mContext,
1272                                ActivityManagerService.this, res, proc);
1273                        d.show();
1274                        proc.crashDialog = d;
1275                    } else {
1276                        // The device is asleep, so just pretend that the user
1277                        // saw a crash dialog and hit "force quit".
1278                        if (res != null) {
1279                            res.set(0);
1280                        }
1281                    }
1282                }
1283
1284                ensureBootCompleted();
1285            } break;
1286            case SHOW_NOT_RESPONDING_MSG: {
1287                synchronized (ActivityManagerService.this) {
1288                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1289                    ProcessRecord proc = (ProcessRecord)data.get("app");
1290                    if (proc != null && proc.anrDialog != null) {
1291                        Slog.e(TAG, "App already has anr dialog: " + proc);
1292                        return;
1293                    }
1294
1295                    Intent intent = new Intent("android.intent.action.ANR");
1296                    if (!mProcessesReady) {
1297                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1298                                | Intent.FLAG_RECEIVER_FOREGROUND);
1299                    }
1300                    broadcastIntentLocked(null, null, intent,
1301                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1302                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1303
1304                    if (mShowDialogs) {
1305                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1306                                mContext, proc, (ActivityRecord)data.get("activity"),
1307                                msg.arg1 != 0);
1308                        d.show();
1309                        proc.anrDialog = d;
1310                    } else {
1311                        // Just kill the app if there is no dialog to be shown.
1312                        killAppAtUsersRequest(proc, null);
1313                    }
1314                }
1315
1316                ensureBootCompleted();
1317            } break;
1318            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1319                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1320                synchronized (ActivityManagerService.this) {
1321                    ProcessRecord proc = (ProcessRecord) data.get("app");
1322                    if (proc == null) {
1323                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1324                        break;
1325                    }
1326                    if (proc.crashDialog != null) {
1327                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1328                        return;
1329                    }
1330                    AppErrorResult res = (AppErrorResult) data.get("result");
1331                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1332                        Dialog d = new StrictModeViolationDialog(mContext,
1333                                ActivityManagerService.this, res, proc);
1334                        d.show();
1335                        proc.crashDialog = d;
1336                    } else {
1337                        // The device is asleep, so just pretend that the user
1338                        // saw a crash dialog and hit "force quit".
1339                        res.set(0);
1340                    }
1341                }
1342                ensureBootCompleted();
1343            } break;
1344            case SHOW_FACTORY_ERROR_MSG: {
1345                Dialog d = new FactoryErrorDialog(
1346                    mContext, msg.getData().getCharSequence("msg"));
1347                d.show();
1348                ensureBootCompleted();
1349            } break;
1350            case UPDATE_CONFIGURATION_MSG: {
1351                final ContentResolver resolver = mContext.getContentResolver();
1352                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1353            } break;
1354            case GC_BACKGROUND_PROCESSES_MSG: {
1355                synchronized (ActivityManagerService.this) {
1356                    performAppGcsIfAppropriateLocked();
1357                }
1358            } break;
1359            case WAIT_FOR_DEBUGGER_MSG: {
1360                synchronized (ActivityManagerService.this) {
1361                    ProcessRecord app = (ProcessRecord)msg.obj;
1362                    if (msg.arg1 != 0) {
1363                        if (!app.waitedForDebugger) {
1364                            Dialog d = new AppWaitingForDebuggerDialog(
1365                                    ActivityManagerService.this,
1366                                    mContext, app);
1367                            app.waitDialog = d;
1368                            app.waitedForDebugger = true;
1369                            d.show();
1370                        }
1371                    } else {
1372                        if (app.waitDialog != null) {
1373                            app.waitDialog.dismiss();
1374                            app.waitDialog = null;
1375                        }
1376                    }
1377                }
1378            } break;
1379            case SERVICE_TIMEOUT_MSG: {
1380                if (mDidDexOpt) {
1381                    mDidDexOpt = false;
1382                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1383                    nmsg.obj = msg.obj;
1384                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1385                    return;
1386                }
1387                mServices.serviceTimeout((ProcessRecord)msg.obj);
1388            } break;
1389            case UPDATE_TIME_ZONE: {
1390                synchronized (ActivityManagerService.this) {
1391                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1392                        ProcessRecord r = mLruProcesses.get(i);
1393                        if (r.thread != null) {
1394                            try {
1395                                r.thread.updateTimeZone();
1396                            } catch (RemoteException ex) {
1397                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1398                            }
1399                        }
1400                    }
1401                }
1402            } break;
1403            case CLEAR_DNS_CACHE_MSG: {
1404                synchronized (ActivityManagerService.this) {
1405                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1406                        ProcessRecord r = mLruProcesses.get(i);
1407                        if (r.thread != null) {
1408                            try {
1409                                r.thread.clearDnsCache();
1410                            } catch (RemoteException ex) {
1411                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1412                            }
1413                        }
1414                    }
1415                }
1416            } break;
1417            case UPDATE_HTTP_PROXY_MSG: {
1418                ProxyInfo proxy = (ProxyInfo)msg.obj;
1419                String host = "";
1420                String port = "";
1421                String exclList = "";
1422                Uri pacFileUrl = Uri.EMPTY;
1423                if (proxy != null) {
1424                    host = proxy.getHost();
1425                    port = Integer.toString(proxy.getPort());
1426                    exclList = proxy.getExclusionListAsString();
1427                    pacFileUrl = proxy.getPacFileUrl();
1428                }
1429                synchronized (ActivityManagerService.this) {
1430                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1431                        ProcessRecord r = mLruProcesses.get(i);
1432                        if (r.thread != null) {
1433                            try {
1434                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1435                            } catch (RemoteException ex) {
1436                                Slog.w(TAG, "Failed to update http proxy for: " +
1437                                        r.info.processName);
1438                            }
1439                        }
1440                    }
1441                }
1442            } break;
1443            case SHOW_UID_ERROR_MSG: {
1444                String title = "System UIDs Inconsistent";
1445                String text = "UIDs on the system are inconsistent, you need to wipe your"
1446                        + " data partition or your device will be unstable.";
1447                Log.e(TAG, title + ": " + text);
1448                if (mShowDialogs) {
1449                    // XXX This is a temporary dialog, no need to localize.
1450                    AlertDialog d = new BaseErrorDialog(mContext);
1451                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1452                    d.setCancelable(false);
1453                    d.setTitle(title);
1454                    d.setMessage(text);
1455                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1456                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1457                    mUidAlert = d;
1458                    d.show();
1459                }
1460            } break;
1461            case IM_FEELING_LUCKY_MSG: {
1462                if (mUidAlert != null) {
1463                    mUidAlert.dismiss();
1464                    mUidAlert = null;
1465                }
1466            } break;
1467            case PROC_START_TIMEOUT_MSG: {
1468                if (mDidDexOpt) {
1469                    mDidDexOpt = false;
1470                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1471                    nmsg.obj = msg.obj;
1472                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1473                    return;
1474                }
1475                ProcessRecord app = (ProcessRecord)msg.obj;
1476                synchronized (ActivityManagerService.this) {
1477                    processStartTimedOutLocked(app);
1478                }
1479            } break;
1480            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1481                synchronized (ActivityManagerService.this) {
1482                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1483                }
1484            } break;
1485            case KILL_APPLICATION_MSG: {
1486                synchronized (ActivityManagerService.this) {
1487                    int appid = msg.arg1;
1488                    boolean restart = (msg.arg2 == 1);
1489                    Bundle bundle = (Bundle)msg.obj;
1490                    String pkg = bundle.getString("pkg");
1491                    String reason = bundle.getString("reason");
1492                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1493                            false, UserHandle.USER_ALL, reason);
1494                }
1495            } break;
1496            case FINALIZE_PENDING_INTENT_MSG: {
1497                ((PendingIntentRecord)msg.obj).completeFinalize();
1498            } break;
1499            case POST_HEAVY_NOTIFICATION_MSG: {
1500                INotificationManager inm = NotificationManager.getService();
1501                if (inm == null) {
1502                    return;
1503                }
1504
1505                ActivityRecord root = (ActivityRecord)msg.obj;
1506                ProcessRecord process = root.app;
1507                if (process == null) {
1508                    return;
1509                }
1510
1511                try {
1512                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1513                    String text = mContext.getString(R.string.heavy_weight_notification,
1514                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1515                    Notification notification = new Notification();
1516                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1517                    notification.when = 0;
1518                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1519                    notification.tickerText = text;
1520                    notification.defaults = 0; // please be quiet
1521                    notification.sound = null;
1522                    notification.vibrate = null;
1523                    notification.color = mContext.getResources().getColor(
1524                            com.android.internal.R.color.system_notification_accent_color);
1525                    notification.setLatestEventInfo(context, text,
1526                            mContext.getText(R.string.heavy_weight_notification_detail),
1527                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1528                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1529                                    new UserHandle(root.userId)));
1530
1531                    try {
1532                        int[] outId = new int[1];
1533                        inm.enqueueNotificationWithTag("android", "android", null,
1534                                R.string.heavy_weight_notification,
1535                                notification, outId, root.userId);
1536                    } catch (RuntimeException e) {
1537                        Slog.w(ActivityManagerService.TAG,
1538                                "Error showing notification for heavy-weight app", e);
1539                    } catch (RemoteException e) {
1540                    }
1541                } catch (NameNotFoundException e) {
1542                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1543                }
1544            } break;
1545            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1546                INotificationManager inm = NotificationManager.getService();
1547                if (inm == null) {
1548                    return;
1549                }
1550                try {
1551                    inm.cancelNotificationWithTag("android", null,
1552                            R.string.heavy_weight_notification,  msg.arg1);
1553                } catch (RuntimeException e) {
1554                    Slog.w(ActivityManagerService.TAG,
1555                            "Error canceling notification for service", e);
1556                } catch (RemoteException e) {
1557                }
1558            } break;
1559            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1560                synchronized (ActivityManagerService.this) {
1561                    checkExcessivePowerUsageLocked(true);
1562                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1563                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1564                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1565                }
1566            } break;
1567            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1568                synchronized (ActivityManagerService.this) {
1569                    ActivityRecord ar = (ActivityRecord)msg.obj;
1570                    if (mCompatModeDialog != null) {
1571                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1572                                ar.info.applicationInfo.packageName)) {
1573                            return;
1574                        }
1575                        mCompatModeDialog.dismiss();
1576                        mCompatModeDialog = null;
1577                    }
1578                    if (ar != null && false) {
1579                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1580                                ar.packageName)) {
1581                            int mode = mCompatModePackages.computeCompatModeLocked(
1582                                    ar.info.applicationInfo);
1583                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1584                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1585                                mCompatModeDialog = new CompatModeDialog(
1586                                        ActivityManagerService.this, mContext,
1587                                        ar.info.applicationInfo);
1588                                mCompatModeDialog.show();
1589                            }
1590                        }
1591                    }
1592                }
1593                break;
1594            }
1595            case DISPATCH_PROCESSES_CHANGED: {
1596                dispatchProcessesChanged();
1597                break;
1598            }
1599            case DISPATCH_PROCESS_DIED: {
1600                final int pid = msg.arg1;
1601                final int uid = msg.arg2;
1602                dispatchProcessDied(pid, uid);
1603                break;
1604            }
1605            case REPORT_MEM_USAGE_MSG: {
1606                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1607                Thread thread = new Thread() {
1608                    @Override public void run() {
1609                        final SparseArray<ProcessMemInfo> infoMap
1610                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1611                        for (int i=0, N=memInfos.size(); i<N; i++) {
1612                            ProcessMemInfo mi = memInfos.get(i);
1613                            infoMap.put(mi.pid, mi);
1614                        }
1615                        updateCpuStatsNow();
1616                        synchronized (mProcessCpuTracker) {
1617                            final int N = mProcessCpuTracker.countStats();
1618                            for (int i=0; i<N; i++) {
1619                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1620                                if (st.vsize > 0) {
1621                                    long pss = Debug.getPss(st.pid, null);
1622                                    if (pss > 0) {
1623                                        if (infoMap.indexOfKey(st.pid) < 0) {
1624                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1625                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1626                                            mi.pss = pss;
1627                                            memInfos.add(mi);
1628                                        }
1629                                    }
1630                                }
1631                            }
1632                        }
1633
1634                        long totalPss = 0;
1635                        for (int i=0, N=memInfos.size(); i<N; i++) {
1636                            ProcessMemInfo mi = memInfos.get(i);
1637                            if (mi.pss == 0) {
1638                                mi.pss = Debug.getPss(mi.pid, null);
1639                            }
1640                            totalPss += mi.pss;
1641                        }
1642                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1643                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1644                                if (lhs.oomAdj != rhs.oomAdj) {
1645                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1646                                }
1647                                if (lhs.pss != rhs.pss) {
1648                                    return lhs.pss < rhs.pss ? 1 : -1;
1649                                }
1650                                return 0;
1651                            }
1652                        });
1653
1654                        StringBuilder tag = new StringBuilder(128);
1655                        StringBuilder stack = new StringBuilder(128);
1656                        tag.append("Low on memory -- ");
1657                        appendMemBucket(tag, totalPss, "total", false);
1658                        appendMemBucket(stack, totalPss, "total", true);
1659
1660                        StringBuilder logBuilder = new StringBuilder(1024);
1661                        logBuilder.append("Low on memory:\n");
1662
1663                        boolean firstLine = true;
1664                        int lastOomAdj = Integer.MIN_VALUE;
1665                        for (int i=0, N=memInfos.size(); i<N; i++) {
1666                            ProcessMemInfo mi = memInfos.get(i);
1667
1668                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1669                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1670                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1671                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1672                                if (lastOomAdj != mi.oomAdj) {
1673                                    lastOomAdj = mi.oomAdj;
1674                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1675                                        tag.append(" / ");
1676                                    }
1677                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1678                                        if (firstLine) {
1679                                            stack.append(":");
1680                                            firstLine = false;
1681                                        }
1682                                        stack.append("\n\t at ");
1683                                    } else {
1684                                        stack.append("$");
1685                                    }
1686                                } else {
1687                                    tag.append(" ");
1688                                    stack.append("$");
1689                                }
1690                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1691                                    appendMemBucket(tag, mi.pss, mi.name, false);
1692                                }
1693                                appendMemBucket(stack, mi.pss, mi.name, true);
1694                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1695                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1696                                    stack.append("(");
1697                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1698                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1699                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1700                                            stack.append(":");
1701                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1702                                        }
1703                                    }
1704                                    stack.append(")");
1705                                }
1706                            }
1707
1708                            logBuilder.append("  ");
1709                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1710                            logBuilder.append(' ');
1711                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1712                            logBuilder.append(' ');
1713                            ProcessList.appendRamKb(logBuilder, mi.pss);
1714                            logBuilder.append(" kB: ");
1715                            logBuilder.append(mi.name);
1716                            logBuilder.append(" (");
1717                            logBuilder.append(mi.pid);
1718                            logBuilder.append(") ");
1719                            logBuilder.append(mi.adjType);
1720                            logBuilder.append('\n');
1721                            if (mi.adjReason != null) {
1722                                logBuilder.append("                      ");
1723                                logBuilder.append(mi.adjReason);
1724                                logBuilder.append('\n');
1725                            }
1726                        }
1727
1728                        logBuilder.append("           ");
1729                        ProcessList.appendRamKb(logBuilder, totalPss);
1730                        logBuilder.append(" kB: TOTAL\n");
1731
1732                        long[] infos = new long[Debug.MEMINFO_COUNT];
1733                        Debug.getMemInfo(infos);
1734                        logBuilder.append("  MemInfo: ");
1735                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1736                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1737                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1738                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1739                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1740                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1741                            logBuilder.append("  ZRAM: ");
1742                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1743                            logBuilder.append(" kB RAM, ");
1744                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1745                            logBuilder.append(" kB swap total, ");
1746                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1747                            logBuilder.append(" kB swap free\n");
1748                        }
1749                        Slog.i(TAG, logBuilder.toString());
1750
1751                        StringBuilder dropBuilder = new StringBuilder(1024);
1752                        /*
1753                        StringWriter oomSw = new StringWriter();
1754                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1755                        StringWriter catSw = new StringWriter();
1756                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1757                        String[] emptyArgs = new String[] { };
1758                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1759                        oomPw.flush();
1760                        String oomString = oomSw.toString();
1761                        */
1762                        dropBuilder.append(stack);
1763                        dropBuilder.append('\n');
1764                        dropBuilder.append('\n');
1765                        dropBuilder.append(logBuilder);
1766                        dropBuilder.append('\n');
1767                        /*
1768                        dropBuilder.append(oomString);
1769                        dropBuilder.append('\n');
1770                        */
1771                        StringWriter catSw = new StringWriter();
1772                        synchronized (ActivityManagerService.this) {
1773                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1774                            String[] emptyArgs = new String[] { };
1775                            catPw.println();
1776                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1777                            catPw.println();
1778                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1779                                    false, false, null);
1780                            catPw.println();
1781                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1782                            catPw.flush();
1783                        }
1784                        dropBuilder.append(catSw.toString());
1785                        addErrorToDropBox("lowmem", null, "system_server", null,
1786                                null, tag.toString(), dropBuilder.toString(), null, null);
1787                        //Slog.i(TAG, "Sent to dropbox:");
1788                        //Slog.i(TAG, dropBuilder.toString());
1789                        synchronized (ActivityManagerService.this) {
1790                            long now = SystemClock.uptimeMillis();
1791                            if (mLastMemUsageReportTime < now) {
1792                                mLastMemUsageReportTime = now;
1793                            }
1794                        }
1795                    }
1796                };
1797                thread.start();
1798                break;
1799            }
1800            case START_USER_SWITCH_MSG: {
1801                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1802                break;
1803            }
1804            case REPORT_USER_SWITCH_MSG: {
1805                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1806                break;
1807            }
1808            case CONTINUE_USER_SWITCH_MSG: {
1809                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1810                break;
1811            }
1812            case USER_SWITCH_TIMEOUT_MSG: {
1813                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1814                break;
1815            }
1816            case IMMERSIVE_MODE_LOCK_MSG: {
1817                final boolean nextState = (msg.arg1 != 0);
1818                if (mUpdateLock.isHeld() != nextState) {
1819                    if (DEBUG_IMMERSIVE) {
1820                        final ActivityRecord r = (ActivityRecord) msg.obj;
1821                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1822                    }
1823                    if (nextState) {
1824                        mUpdateLock.acquire();
1825                    } else {
1826                        mUpdateLock.release();
1827                    }
1828                }
1829                break;
1830            }
1831            case PERSIST_URI_GRANTS_MSG: {
1832                writeGrantedUriPermissions();
1833                break;
1834            }
1835            case REQUEST_ALL_PSS_MSG: {
1836                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1837                break;
1838            }
1839            case START_PROFILES_MSG: {
1840                synchronized (ActivityManagerService.this) {
1841                    startProfilesLocked();
1842                }
1843                break;
1844            }
1845            case UPDATE_TIME: {
1846                synchronized (ActivityManagerService.this) {
1847                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1848                        ProcessRecord r = mLruProcesses.get(i);
1849                        if (r.thread != null) {
1850                            try {
1851                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1852                            } catch (RemoteException ex) {
1853                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1854                            }
1855                        }
1856                    }
1857                }
1858                break;
1859            }
1860            case SYSTEM_USER_START_MSG: {
1861                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1862                        Integer.toString(msg.arg1), msg.arg1);
1863                mSystemServiceManager.startUser(msg.arg1);
1864                break;
1865            }
1866            case SYSTEM_USER_CURRENT_MSG: {
1867                mBatteryStatsService.noteEvent(
1868                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1869                        Integer.toString(msg.arg2), msg.arg2);
1870                mBatteryStatsService.noteEvent(
1871                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1872                        Integer.toString(msg.arg1), msg.arg1);
1873                mSystemServiceManager.switchUser(msg.arg1);
1874                mLockToAppRequest.clearPrompt();
1875                break;
1876            }
1877            case ENTER_ANIMATION_COMPLETE_MSG: {
1878                synchronized (ActivityManagerService.this) {
1879                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1880                    if (r != null && r.app != null && r.app.thread != null) {
1881                        try {
1882                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1883                        } catch (RemoteException e) {
1884                        }
1885                    }
1886                }
1887                break;
1888            }
1889            case FINISH_BOOTING_MSG: {
1890                if (msg.arg1 != 0) {
1891                    finishBooting();
1892                }
1893                if (msg.arg2 != 0) {
1894                    enableScreenAfterBoot();
1895                }
1896                break;
1897            }
1898            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1899                try {
1900                    Locale l = (Locale) msg.obj;
1901                    IBinder service = ServiceManager.getService("mount");
1902                    IMountService mountService = IMountService.Stub.asInterface(service);
1903                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1904                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1905                } catch (RemoteException e) {
1906                    Log.e(TAG, "Error storing locale for decryption UI", e);
1907                }
1908                break;
1909            }
1910            }
1911        }
1912    };
1913
1914    static final int COLLECT_PSS_BG_MSG = 1;
1915
1916    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1917        @Override
1918        public void handleMessage(Message msg) {
1919            switch (msg.what) {
1920            case COLLECT_PSS_BG_MSG: {
1921                long start = SystemClock.uptimeMillis();
1922                MemInfoReader memInfo = null;
1923                synchronized (ActivityManagerService.this) {
1924                    if (mFullPssPending) {
1925                        mFullPssPending = false;
1926                        memInfo = new MemInfoReader();
1927                    }
1928                }
1929                if (memInfo != null) {
1930                    updateCpuStatsNow();
1931                    long nativeTotalPss = 0;
1932                    synchronized (mProcessCpuTracker) {
1933                        final int N = mProcessCpuTracker.countStats();
1934                        for (int j=0; j<N; j++) {
1935                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1936                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1937                                // This is definitely an application process; skip it.
1938                                continue;
1939                            }
1940                            synchronized (mPidsSelfLocked) {
1941                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1942                                    // This is one of our own processes; skip it.
1943                                    continue;
1944                                }
1945                            }
1946                            nativeTotalPss += Debug.getPss(st.pid, null);
1947                        }
1948                    }
1949                    memInfo.readMemInfo();
1950                    synchronized (ActivityManagerService.this) {
1951                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1952                                + (SystemClock.uptimeMillis()-start) + "ms");
1953                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1954                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1955                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1956                                        +memInfo.getSlabSizeKb(),
1957                                nativeTotalPss);
1958                    }
1959                }
1960
1961                int i=0, num=0;
1962                long[] tmp = new long[1];
1963                do {
1964                    ProcessRecord proc;
1965                    int procState;
1966                    int pid;
1967                    synchronized (ActivityManagerService.this) {
1968                        if (i >= mPendingPssProcesses.size()) {
1969                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1970                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1971                            mPendingPssProcesses.clear();
1972                            return;
1973                        }
1974                        proc = mPendingPssProcesses.get(i);
1975                        procState = proc.pssProcState;
1976                        if (proc.thread != null && procState == proc.setProcState) {
1977                            pid = proc.pid;
1978                        } else {
1979                            proc = null;
1980                            pid = 0;
1981                        }
1982                        i++;
1983                    }
1984                    if (proc != null) {
1985                        long pss = Debug.getPss(pid, tmp);
1986                        synchronized (ActivityManagerService.this) {
1987                            if (proc.thread != null && proc.setProcState == procState
1988                                    && proc.pid == pid) {
1989                                num++;
1990                                proc.lastPssTime = SystemClock.uptimeMillis();
1991                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1992                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1993                                        + ": " + pss + " lastPss=" + proc.lastPss
1994                                        + " state=" + ProcessList.makeProcStateString(procState));
1995                                if (proc.initialIdlePss == 0) {
1996                                    proc.initialIdlePss = pss;
1997                                }
1998                                proc.lastPss = pss;
1999                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
2000                                    proc.lastCachedPss = pss;
2001                                }
2002                            }
2003                        }
2004                    }
2005                } while (true);
2006            }
2007            }
2008        }
2009    };
2010
2011    /**
2012     * Monitor for package changes and update our internal state.
2013     */
2014    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
2015        @Override
2016        public void onPackageRemoved(String packageName, int uid) {
2017            // Remove all tasks with activities in the specified package from the list of recent tasks
2018            final int eventUserId = getChangingUserId();
2019            synchronized (ActivityManagerService.this) {
2020                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2021                    TaskRecord tr = mRecentTasks.get(i);
2022                    if (tr.userId != eventUserId) continue;
2023
2024                    ComponentName cn = tr.intent.getComponent();
2025                    if (cn != null && cn.getPackageName().equals(packageName)) {
2026                        // If the package name matches, remove the task and kill the process
2027                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
2028                    }
2029                }
2030            }
2031        }
2032
2033        @Override
2034        public boolean onPackageChanged(String packageName, int uid, String[] components) {
2035            onPackageModified(packageName);
2036            return true;
2037        }
2038
2039        @Override
2040        public void onPackageModified(String packageName) {
2041            final int eventUserId = getChangingUserId();
2042            final IPackageManager pm = AppGlobals.getPackageManager();
2043            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
2044                    new ArrayList<Pair<Intent, Integer>>();
2045            final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
2046            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
2047            // Copy the list of recent tasks so that we don't hold onto the lock on
2048            // ActivityManagerService for long periods while checking if components exist.
2049            synchronized (ActivityManagerService.this) {
2050                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2051                    TaskRecord tr = mRecentTasks.get(i);
2052                    if (tr.userId != eventUserId) continue;
2053
2054                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
2055                }
2056            }
2057            // Check the recent tasks and filter out all tasks with components that no longer exist.
2058            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
2059                Pair<Intent, Integer> p = recentTaskIntents.get(i);
2060                ComponentName cn = p.first.getComponent();
2061                if (cn != null && cn.getPackageName().equals(packageName)) {
2062                    if (componentsKnownToExist.contains(cn)) {
2063                        // If we know that the component still exists in the package, then skip
2064                        continue;
2065                    }
2066                    try {
2067                        ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId);
2068                        if (info != null) {
2069                            componentsKnownToExist.add(cn);
2070                        } else {
2071                            tasksToRemove.add(p.second);
2072                        }
2073                    } catch (RemoteException e) {
2074                        Log.e(TAG, "Failed to query activity info for component: " + cn, e);
2075                    }
2076                }
2077            }
2078            // Prune all the tasks with removed components from the list of recent tasks
2079            synchronized (ActivityManagerService.this) {
2080                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
2081                    // Remove the task but don't kill the process (since other components in that
2082                    // package may still be running and in the background)
2083                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
2084                }
2085            }
2086        }
2087
2088        @Override
2089        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2090            // Force stop the specified packages
2091            int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
2092            if (packages != null) {
2093                for (String pkg : packages) {
2094                    synchronized (ActivityManagerService.this) {
2095                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
2096                                userId, "finished booting")) {
2097                            return true;
2098                        }
2099                    }
2100                }
2101            }
2102            return false;
2103        }
2104    };
2105
2106    public void setSystemProcess() {
2107        try {
2108            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2109            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2110            ServiceManager.addService("meminfo", new MemBinder(this));
2111            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2112            ServiceManager.addService("dbinfo", new DbBinder(this));
2113            if (MONITOR_CPU_USAGE) {
2114                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2115            }
2116            ServiceManager.addService("permission", new PermissionController(this));
2117
2118            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2119                    "android", STOCK_PM_FLAGS);
2120            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2121
2122            synchronized (this) {
2123                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2124                app.persistent = true;
2125                app.pid = MY_PID;
2126                app.maxAdj = ProcessList.SYSTEM_ADJ;
2127                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2128                mProcessNames.put(app.processName, app.uid, app);
2129                synchronized (mPidsSelfLocked) {
2130                    mPidsSelfLocked.put(app.pid, app);
2131                }
2132                updateLruProcessLocked(app, false, null);
2133                updateOomAdjLocked();
2134            }
2135        } catch (PackageManager.NameNotFoundException e) {
2136            throw new RuntimeException(
2137                    "Unable to find android system package", e);
2138        }
2139    }
2140
2141    public void setWindowManager(WindowManagerService wm) {
2142        mWindowManager = wm;
2143        mStackSupervisor.setWindowManager(wm);
2144    }
2145
2146    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2147        mUsageStatsService = usageStatsManager;
2148    }
2149
2150    public void startObservingNativeCrashes() {
2151        final NativeCrashListener ncl = new NativeCrashListener(this);
2152        ncl.start();
2153    }
2154
2155    public IAppOpsService getAppOpsService() {
2156        return mAppOpsService;
2157    }
2158
2159    static class MemBinder extends Binder {
2160        ActivityManagerService mActivityManagerService;
2161        MemBinder(ActivityManagerService activityManagerService) {
2162            mActivityManagerService = activityManagerService;
2163        }
2164
2165        @Override
2166        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2167            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2168                    != PackageManager.PERMISSION_GRANTED) {
2169                pw.println("Permission Denial: can't dump meminfo from from pid="
2170                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2171                        + " without permission " + android.Manifest.permission.DUMP);
2172                return;
2173            }
2174
2175            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2176        }
2177    }
2178
2179    static class GraphicsBinder extends Binder {
2180        ActivityManagerService mActivityManagerService;
2181        GraphicsBinder(ActivityManagerService activityManagerService) {
2182            mActivityManagerService = activityManagerService;
2183        }
2184
2185        @Override
2186        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2187            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2188                    != PackageManager.PERMISSION_GRANTED) {
2189                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2190                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2191                        + " without permission " + android.Manifest.permission.DUMP);
2192                return;
2193            }
2194
2195            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2196        }
2197    }
2198
2199    static class DbBinder extends Binder {
2200        ActivityManagerService mActivityManagerService;
2201        DbBinder(ActivityManagerService activityManagerService) {
2202            mActivityManagerService = activityManagerService;
2203        }
2204
2205        @Override
2206        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2207            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2208                    != PackageManager.PERMISSION_GRANTED) {
2209                pw.println("Permission Denial: can't dump dbinfo from from pid="
2210                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2211                        + " without permission " + android.Manifest.permission.DUMP);
2212                return;
2213            }
2214
2215            mActivityManagerService.dumpDbInfo(fd, pw, args);
2216        }
2217    }
2218
2219    static class CpuBinder extends Binder {
2220        ActivityManagerService mActivityManagerService;
2221        CpuBinder(ActivityManagerService activityManagerService) {
2222            mActivityManagerService = activityManagerService;
2223        }
2224
2225        @Override
2226        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2227            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2228                    != PackageManager.PERMISSION_GRANTED) {
2229                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2230                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2231                        + " without permission " + android.Manifest.permission.DUMP);
2232                return;
2233            }
2234
2235            synchronized (mActivityManagerService.mProcessCpuTracker) {
2236                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2237                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2238                        SystemClock.uptimeMillis()));
2239            }
2240        }
2241    }
2242
2243    public static final class Lifecycle extends SystemService {
2244        private final ActivityManagerService mService;
2245
2246        public Lifecycle(Context context) {
2247            super(context);
2248            mService = new ActivityManagerService(context);
2249        }
2250
2251        @Override
2252        public void onStart() {
2253            mService.start();
2254        }
2255
2256        public ActivityManagerService getService() {
2257            return mService;
2258        }
2259    }
2260
2261    // Note: This method is invoked on the main thread but may need to attach various
2262    // handlers to other threads.  So take care to be explicit about the looper.
2263    public ActivityManagerService(Context systemContext) {
2264        mContext = systemContext;
2265        mFactoryTest = FactoryTest.getMode();
2266        mSystemThread = ActivityThread.currentActivityThread();
2267
2268        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2269
2270        mHandlerThread = new ServiceThread(TAG,
2271                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2272        mHandlerThread.start();
2273        mHandler = new MainHandler(mHandlerThread.getLooper());
2274
2275        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2276                "foreground", BROADCAST_FG_TIMEOUT, false);
2277        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2278                "background", BROADCAST_BG_TIMEOUT, true);
2279        mBroadcastQueues[0] = mFgBroadcastQueue;
2280        mBroadcastQueues[1] = mBgBroadcastQueue;
2281
2282        mServices = new ActiveServices(this);
2283        mProviderMap = new ProviderMap(this);
2284
2285        // TODO: Move creation of battery stats service outside of activity manager service.
2286        File dataDir = Environment.getDataDirectory();
2287        File systemDir = new File(dataDir, "system");
2288        systemDir.mkdirs();
2289        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2290        mBatteryStatsService.getActiveStatistics().readLocked();
2291        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2292        mOnBattery = DEBUG_POWER ? true
2293                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2294        mBatteryStatsService.getActiveStatistics().setCallback(this);
2295
2296        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2297
2298        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2299
2300        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2301
2302        // User 0 is the first and only user that runs at boot.
2303        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2304        mUserLru.add(Integer.valueOf(0));
2305        updateStartedUserArrayLocked();
2306
2307        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2308            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2309
2310        mConfiguration.setToDefaults();
2311        mConfiguration.setLocale(Locale.getDefault());
2312
2313        mConfigurationSeq = mConfiguration.seq = 1;
2314        mProcessCpuTracker.init();
2315
2316        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2317        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2318        mStackSupervisor = new ActivityStackSupervisor(this);
2319        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2320
2321        mProcessCpuThread = new Thread("CpuTracker") {
2322            @Override
2323            public void run() {
2324                while (true) {
2325                    try {
2326                        try {
2327                            synchronized(this) {
2328                                final long now = SystemClock.uptimeMillis();
2329                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2330                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2331                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2332                                //        + ", write delay=" + nextWriteDelay);
2333                                if (nextWriteDelay < nextCpuDelay) {
2334                                    nextCpuDelay = nextWriteDelay;
2335                                }
2336                                if (nextCpuDelay > 0) {
2337                                    mProcessCpuMutexFree.set(true);
2338                                    this.wait(nextCpuDelay);
2339                                }
2340                            }
2341                        } catch (InterruptedException e) {
2342                        }
2343                        updateCpuStatsNow();
2344                    } catch (Exception e) {
2345                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2346                    }
2347                }
2348            }
2349        };
2350
2351        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2352
2353        Watchdog.getInstance().addMonitor(this);
2354        Watchdog.getInstance().addThread(mHandler);
2355    }
2356
2357    public void setSystemServiceManager(SystemServiceManager mgr) {
2358        mSystemServiceManager = mgr;
2359    }
2360
2361    private void start() {
2362        Process.removeAllProcessGroups();
2363        mProcessCpuThread.start();
2364
2365        mBatteryStatsService.publish(mContext);
2366        mAppOpsService.publish(mContext);
2367        Slog.d("AppOps", "AppOpsService published");
2368        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2369    }
2370
2371    public void initPowerManagement() {
2372        mStackSupervisor.initPowerManagement();
2373        mBatteryStatsService.initPowerManagement();
2374    }
2375
2376    @Override
2377    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2378            throws RemoteException {
2379        if (code == SYSPROPS_TRANSACTION) {
2380            // We need to tell all apps about the system property change.
2381            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2382            synchronized(this) {
2383                final int NP = mProcessNames.getMap().size();
2384                for (int ip=0; ip<NP; ip++) {
2385                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2386                    final int NA = apps.size();
2387                    for (int ia=0; ia<NA; ia++) {
2388                        ProcessRecord app = apps.valueAt(ia);
2389                        if (app.thread != null) {
2390                            procs.add(app.thread.asBinder());
2391                        }
2392                    }
2393                }
2394            }
2395
2396            int N = procs.size();
2397            for (int i=0; i<N; i++) {
2398                Parcel data2 = Parcel.obtain();
2399                try {
2400                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2401                } catch (RemoteException e) {
2402                }
2403                data2.recycle();
2404            }
2405        }
2406        try {
2407            return super.onTransact(code, data, reply, flags);
2408        } catch (RuntimeException e) {
2409            // The activity manager only throws security exceptions, so let's
2410            // log all others.
2411            if (!(e instanceof SecurityException)) {
2412                Slog.wtf(TAG, "Activity Manager Crash", e);
2413            }
2414            throw e;
2415        }
2416    }
2417
2418    void updateCpuStats() {
2419        final long now = SystemClock.uptimeMillis();
2420        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2421            return;
2422        }
2423        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2424            synchronized (mProcessCpuThread) {
2425                mProcessCpuThread.notify();
2426            }
2427        }
2428    }
2429
2430    void updateCpuStatsNow() {
2431        synchronized (mProcessCpuTracker) {
2432            mProcessCpuMutexFree.set(false);
2433            final long now = SystemClock.uptimeMillis();
2434            boolean haveNewCpuStats = false;
2435
2436            if (MONITOR_CPU_USAGE &&
2437                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2438                mLastCpuTime.set(now);
2439                haveNewCpuStats = true;
2440                mProcessCpuTracker.update();
2441                //Slog.i(TAG, mProcessCpu.printCurrentState());
2442                //Slog.i(TAG, "Total CPU usage: "
2443                //        + mProcessCpu.getTotalCpuPercent() + "%");
2444
2445                // Slog the cpu usage if the property is set.
2446                if ("true".equals(SystemProperties.get("events.cpu"))) {
2447                    int user = mProcessCpuTracker.getLastUserTime();
2448                    int system = mProcessCpuTracker.getLastSystemTime();
2449                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2450                    int irq = mProcessCpuTracker.getLastIrqTime();
2451                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2452                    int idle = mProcessCpuTracker.getLastIdleTime();
2453
2454                    int total = user + system + iowait + irq + softIrq + idle;
2455                    if (total == 0) total = 1;
2456
2457                    EventLog.writeEvent(EventLogTags.CPU,
2458                            ((user+system+iowait+irq+softIrq) * 100) / total,
2459                            (user * 100) / total,
2460                            (system * 100) / total,
2461                            (iowait * 100) / total,
2462                            (irq * 100) / total,
2463                            (softIrq * 100) / total);
2464                }
2465            }
2466
2467            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2468            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2469            synchronized(bstats) {
2470                synchronized(mPidsSelfLocked) {
2471                    if (haveNewCpuStats) {
2472                        if (mOnBattery) {
2473                            int perc = bstats.startAddingCpuLocked();
2474                            int totalUTime = 0;
2475                            int totalSTime = 0;
2476                            final int N = mProcessCpuTracker.countStats();
2477                            for (int i=0; i<N; i++) {
2478                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2479                                if (!st.working) {
2480                                    continue;
2481                                }
2482                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2483                                int otherUTime = (st.rel_utime*perc)/100;
2484                                int otherSTime = (st.rel_stime*perc)/100;
2485                                totalUTime += otherUTime;
2486                                totalSTime += otherSTime;
2487                                if (pr != null) {
2488                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2489                                    if (ps == null || !ps.isActive()) {
2490                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2491                                                pr.info.uid, pr.processName);
2492                                    }
2493                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2494                                            st.rel_stime-otherSTime);
2495                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2496                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2497                                } else {
2498                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2499                                    if (ps == null || !ps.isActive()) {
2500                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2501                                                bstats.mapUid(st.uid), st.name);
2502                                    }
2503                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2504                                            st.rel_stime-otherSTime);
2505                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2506                                }
2507                            }
2508                            bstats.finishAddingCpuLocked(perc, totalUTime,
2509                                    totalSTime, cpuSpeedTimes);
2510                        }
2511                    }
2512                }
2513
2514                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2515                    mLastWriteTime = now;
2516                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2517                }
2518            }
2519        }
2520    }
2521
2522    @Override
2523    public void batteryNeedsCpuUpdate() {
2524        updateCpuStatsNow();
2525    }
2526
2527    @Override
2528    public void batteryPowerChanged(boolean onBattery) {
2529        // When plugging in, update the CPU stats first before changing
2530        // the plug state.
2531        updateCpuStatsNow();
2532        synchronized (this) {
2533            synchronized(mPidsSelfLocked) {
2534                mOnBattery = DEBUG_POWER ? true : onBattery;
2535            }
2536        }
2537    }
2538
2539    /**
2540     * Initialize the application bind args. These are passed to each
2541     * process when the bindApplication() IPC is sent to the process. They're
2542     * lazily setup to make sure the services are running when they're asked for.
2543     */
2544    private HashMap<String, IBinder> getCommonServicesLocked() {
2545        if (mAppBindArgs == null) {
2546            mAppBindArgs = new HashMap<String, IBinder>();
2547
2548            // Setup the application init args
2549            mAppBindArgs.put("package", ServiceManager.getService("package"));
2550            mAppBindArgs.put("window", ServiceManager.getService("window"));
2551            mAppBindArgs.put(Context.ALARM_SERVICE,
2552                    ServiceManager.getService(Context.ALARM_SERVICE));
2553        }
2554        return mAppBindArgs;
2555    }
2556
2557    final void setFocusedActivityLocked(ActivityRecord r) {
2558        if (mFocusedActivity != r) {
2559            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2560            mFocusedActivity = r;
2561            if (r.task != null && r.task.voiceInteractor != null) {
2562                startRunningVoiceLocked();
2563            } else {
2564                finishRunningVoiceLocked();
2565            }
2566            mStackSupervisor.setFocusedStack(r);
2567            if (r != null) {
2568                mWindowManager.setFocusedApp(r.appToken, true);
2569            }
2570            applyUpdateLockStateLocked(r);
2571        }
2572    }
2573
2574    final void clearFocusedActivity(ActivityRecord r) {
2575        if (mFocusedActivity == r) {
2576            mFocusedActivity = null;
2577        }
2578    }
2579
2580    @Override
2581    public void setFocusedStack(int stackId) {
2582        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2583        synchronized (ActivityManagerService.this) {
2584            ActivityStack stack = mStackSupervisor.getStack(stackId);
2585            if (stack != null) {
2586                ActivityRecord r = stack.topRunningActivityLocked(null);
2587                if (r != null) {
2588                    setFocusedActivityLocked(r);
2589                }
2590            }
2591        }
2592    }
2593
2594    @Override
2595    public void notifyActivityDrawn(IBinder token) {
2596        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2597        synchronized (this) {
2598            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2599            if (r != null) {
2600                r.task.stack.notifyActivityDrawnLocked(r);
2601            }
2602        }
2603    }
2604
2605    final void applyUpdateLockStateLocked(ActivityRecord r) {
2606        // Modifications to the UpdateLock state are done on our handler, outside
2607        // the activity manager's locks.  The new state is determined based on the
2608        // state *now* of the relevant activity record.  The object is passed to
2609        // the handler solely for logging detail, not to be consulted/modified.
2610        final boolean nextState = r != null && r.immersive;
2611        mHandler.sendMessage(
2612                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2613    }
2614
2615    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2616        Message msg = Message.obtain();
2617        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2618        msg.obj = r.task.askedCompatMode ? null : r;
2619        mHandler.sendMessage(msg);
2620    }
2621
2622    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2623            String what, Object obj, ProcessRecord srcApp) {
2624        app.lastActivityTime = now;
2625
2626        if (app.activities.size() > 0) {
2627            // Don't want to touch dependent processes that are hosting activities.
2628            return index;
2629        }
2630
2631        int lrui = mLruProcesses.lastIndexOf(app);
2632        if (lrui < 0) {
2633            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2634                    + what + " " + obj + " from " + srcApp);
2635            return index;
2636        }
2637
2638        if (lrui >= index) {
2639            // Don't want to cause this to move dependent processes *back* in the
2640            // list as if they were less frequently used.
2641            return index;
2642        }
2643
2644        if (lrui >= mLruProcessActivityStart) {
2645            // Don't want to touch dependent processes that are hosting activities.
2646            return index;
2647        }
2648
2649        mLruProcesses.remove(lrui);
2650        if (index > 0) {
2651            index--;
2652        }
2653        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2654                + " in LRU list: " + app);
2655        mLruProcesses.add(index, app);
2656        return index;
2657    }
2658
2659    final void removeLruProcessLocked(ProcessRecord app) {
2660        int lrui = mLruProcesses.lastIndexOf(app);
2661        if (lrui >= 0) {
2662            if (!app.killed) {
2663                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2664                Process.killProcessQuiet(app.pid);
2665                Process.killProcessGroup(app.info.uid, app.pid);
2666            }
2667            if (lrui <= mLruProcessActivityStart) {
2668                mLruProcessActivityStart--;
2669            }
2670            if (lrui <= mLruProcessServiceStart) {
2671                mLruProcessServiceStart--;
2672            }
2673            mLruProcesses.remove(lrui);
2674        }
2675    }
2676
2677    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2678            ProcessRecord client) {
2679        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2680                || app.treatLikeActivity;
2681        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2682        if (!activityChange && hasActivity) {
2683            // The process has activities, so we are only allowing activity-based adjustments
2684            // to move it.  It should be kept in the front of the list with other
2685            // processes that have activities, and we don't want those to change their
2686            // order except due to activity operations.
2687            return;
2688        }
2689
2690        mLruSeq++;
2691        final long now = SystemClock.uptimeMillis();
2692        app.lastActivityTime = now;
2693
2694        // First a quick reject: if the app is already at the position we will
2695        // put it, then there is nothing to do.
2696        if (hasActivity) {
2697            final int N = mLruProcesses.size();
2698            if (N > 0 && mLruProcesses.get(N-1) == app) {
2699                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2700                return;
2701            }
2702        } else {
2703            if (mLruProcessServiceStart > 0
2704                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2705                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2706                return;
2707            }
2708        }
2709
2710        int lrui = mLruProcesses.lastIndexOf(app);
2711
2712        if (app.persistent && lrui >= 0) {
2713            // We don't care about the position of persistent processes, as long as
2714            // they are in the list.
2715            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2716            return;
2717        }
2718
2719        /* In progress: compute new position first, so we can avoid doing work
2720           if the process is not actually going to move.  Not yet working.
2721        int addIndex;
2722        int nextIndex;
2723        boolean inActivity = false, inService = false;
2724        if (hasActivity) {
2725            // Process has activities, put it at the very tipsy-top.
2726            addIndex = mLruProcesses.size();
2727            nextIndex = mLruProcessServiceStart;
2728            inActivity = true;
2729        } else if (hasService) {
2730            // Process has services, put it at the top of the service list.
2731            addIndex = mLruProcessActivityStart;
2732            nextIndex = mLruProcessServiceStart;
2733            inActivity = true;
2734            inService = true;
2735        } else  {
2736            // Process not otherwise of interest, it goes to the top of the non-service area.
2737            addIndex = mLruProcessServiceStart;
2738            if (client != null) {
2739                int clientIndex = mLruProcesses.lastIndexOf(client);
2740                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2741                        + app);
2742                if (clientIndex >= 0 && addIndex > clientIndex) {
2743                    addIndex = clientIndex;
2744                }
2745            }
2746            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2747        }
2748
2749        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2750                + mLruProcessActivityStart + "): " + app);
2751        */
2752
2753        if (lrui >= 0) {
2754            if (lrui < mLruProcessActivityStart) {
2755                mLruProcessActivityStart--;
2756            }
2757            if (lrui < mLruProcessServiceStart) {
2758                mLruProcessServiceStart--;
2759            }
2760            /*
2761            if (addIndex > lrui) {
2762                addIndex--;
2763            }
2764            if (nextIndex > lrui) {
2765                nextIndex--;
2766            }
2767            */
2768            mLruProcesses.remove(lrui);
2769        }
2770
2771        /*
2772        mLruProcesses.add(addIndex, app);
2773        if (inActivity) {
2774            mLruProcessActivityStart++;
2775        }
2776        if (inService) {
2777            mLruProcessActivityStart++;
2778        }
2779        */
2780
2781        int nextIndex;
2782        if (hasActivity) {
2783            final int N = mLruProcesses.size();
2784            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2785                // Process doesn't have activities, but has clients with
2786                // activities...  move it up, but one below the top (the top
2787                // should always have a real activity).
2788                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2789                mLruProcesses.add(N-1, app);
2790                // To keep it from spamming the LRU list (by making a bunch of clients),
2791                // we will push down any other entries owned by the app.
2792                final int uid = app.info.uid;
2793                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2794                    ProcessRecord subProc = mLruProcesses.get(i);
2795                    if (subProc.info.uid == uid) {
2796                        // We want to push this one down the list.  If the process after
2797                        // it is for the same uid, however, don't do so, because we don't
2798                        // want them internally to be re-ordered.
2799                        if (mLruProcesses.get(i-1).info.uid != uid) {
2800                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2801                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2802                            ProcessRecord tmp = mLruProcesses.get(i);
2803                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2804                            mLruProcesses.set(i-1, tmp);
2805                            i--;
2806                        }
2807                    } else {
2808                        // A gap, we can stop here.
2809                        break;
2810                    }
2811                }
2812            } else {
2813                // Process has activities, put it at the very tipsy-top.
2814                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2815                mLruProcesses.add(app);
2816            }
2817            nextIndex = mLruProcessServiceStart;
2818        } else if (hasService) {
2819            // Process has services, put it at the top of the service list.
2820            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2821            mLruProcesses.add(mLruProcessActivityStart, app);
2822            nextIndex = mLruProcessServiceStart;
2823            mLruProcessActivityStart++;
2824        } else  {
2825            // Process not otherwise of interest, it goes to the top of the non-service area.
2826            int index = mLruProcessServiceStart;
2827            if (client != null) {
2828                // If there is a client, don't allow the process to be moved up higher
2829                // in the list than that client.
2830                int clientIndex = mLruProcesses.lastIndexOf(client);
2831                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2832                        + " when updating " + app);
2833                if (clientIndex <= lrui) {
2834                    // Don't allow the client index restriction to push it down farther in the
2835                    // list than it already is.
2836                    clientIndex = lrui;
2837                }
2838                if (clientIndex >= 0 && index > clientIndex) {
2839                    index = clientIndex;
2840                }
2841            }
2842            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2843            mLruProcesses.add(index, app);
2844            nextIndex = index-1;
2845            mLruProcessActivityStart++;
2846            mLruProcessServiceStart++;
2847        }
2848
2849        // If the app is currently using a content provider or service,
2850        // bump those processes as well.
2851        for (int j=app.connections.size()-1; j>=0; j--) {
2852            ConnectionRecord cr = app.connections.valueAt(j);
2853            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2854                    && cr.binding.service.app != null
2855                    && cr.binding.service.app.lruSeq != mLruSeq
2856                    && !cr.binding.service.app.persistent) {
2857                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2858                        "service connection", cr, app);
2859            }
2860        }
2861        for (int j=app.conProviders.size()-1; j>=0; j--) {
2862            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2863            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2864                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2865                        "provider reference", cpr, app);
2866            }
2867        }
2868    }
2869
2870    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2871        if (uid == Process.SYSTEM_UID) {
2872            // The system gets to run in any process.  If there are multiple
2873            // processes with the same uid, just pick the first (this
2874            // should never happen).
2875            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2876            if (procs == null) return null;
2877            final int N = procs.size();
2878            for (int i = 0; i < N; i++) {
2879                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2880            }
2881        }
2882        ProcessRecord proc = mProcessNames.get(processName, uid);
2883        if (false && proc != null && !keepIfLarge
2884                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2885                && proc.lastCachedPss >= 4000) {
2886            // Turn this condition on to cause killing to happen regularly, for testing.
2887            if (proc.baseProcessTracker != null) {
2888                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2889            }
2890            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2891        } else if (proc != null && !keepIfLarge
2892                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2893                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2894            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2895            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2896                if (proc.baseProcessTracker != null) {
2897                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2898                }
2899                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2900            }
2901        }
2902        return proc;
2903    }
2904
2905    void ensurePackageDexOpt(String packageName) {
2906        IPackageManager pm = AppGlobals.getPackageManager();
2907        try {
2908            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2909                mDidDexOpt = true;
2910            }
2911        } catch (RemoteException e) {
2912        }
2913    }
2914
2915    boolean isNextTransitionForward() {
2916        int transit = mWindowManager.getPendingAppTransition();
2917        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2918                || transit == AppTransition.TRANSIT_TASK_OPEN
2919                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2920    }
2921
2922    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2923            String processName, String abiOverride, int uid, Runnable crashHandler) {
2924        synchronized(this) {
2925            ApplicationInfo info = new ApplicationInfo();
2926            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2927            // For isolated processes, the former contains the parent's uid and the latter the
2928            // actual uid of the isolated process.
2929            // In the special case introduced by this method (which is, starting an isolated
2930            // process directly from the SystemServer without an actual parent app process) the
2931            // closest thing to a parent's uid is SYSTEM_UID.
2932            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2933            // the |isolated| logic in the ProcessRecord constructor.
2934            info.uid = Process.SYSTEM_UID;
2935            info.processName = processName;
2936            info.className = entryPoint;
2937            info.packageName = "android";
2938            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2939                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2940                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2941                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2942                    crashHandler);
2943            return proc != null ? proc.pid : 0;
2944        }
2945    }
2946
2947    final ProcessRecord startProcessLocked(String processName,
2948            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2949            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2950            boolean isolated, boolean keepIfLarge) {
2951        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2952                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2953                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2954                null /* crashHandler */);
2955    }
2956
2957    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2958            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2959            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2960            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2961        long startTime = SystemClock.elapsedRealtime();
2962        ProcessRecord app;
2963        if (!isolated) {
2964            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2965            checkTime(startTime, "startProcess: after getProcessRecord");
2966        } else {
2967            // If this is an isolated process, it can't re-use an existing process.
2968            app = null;
2969        }
2970        // We don't have to do anything more if:
2971        // (1) There is an existing application record; and
2972        // (2) The caller doesn't think it is dead, OR there is no thread
2973        //     object attached to it so we know it couldn't have crashed; and
2974        // (3) There is a pid assigned to it, so it is either starting or
2975        //     already running.
2976        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2977                + " app=" + app + " knownToBeDead=" + knownToBeDead
2978                + " thread=" + (app != null ? app.thread : null)
2979                + " pid=" + (app != null ? app.pid : -1));
2980        if (app != null && app.pid > 0) {
2981            if (!knownToBeDead || app.thread == null) {
2982                // We already have the app running, or are waiting for it to
2983                // come up (we have a pid but not yet its thread), so keep it.
2984                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2985                // If this is a new package in the process, add the package to the list
2986                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2987                checkTime(startTime, "startProcess: done, added package to proc");
2988                return app;
2989            }
2990
2991            // An application record is attached to a previous process,
2992            // clean it up now.
2993            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2994            checkTime(startTime, "startProcess: bad proc running, killing");
2995            Process.killProcessGroup(app.info.uid, app.pid);
2996            handleAppDiedLocked(app, true, true);
2997            checkTime(startTime, "startProcess: done killing old proc");
2998        }
2999
3000        String hostingNameStr = hostingName != null
3001                ? hostingName.flattenToShortString() : null;
3002
3003        if (!isolated) {
3004            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
3005                // If we are in the background, then check to see if this process
3006                // is bad.  If so, we will just silently fail.
3007                if (mBadProcesses.get(info.processName, info.uid) != null) {
3008                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3009                            + "/" + info.processName);
3010                    return null;
3011                }
3012            } else {
3013                // When the user is explicitly starting a process, then clear its
3014                // crash count so that we won't make it bad until they see at
3015                // least one crash dialog again, and make the process good again
3016                // if it had been bad.
3017                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3018                        + "/" + info.processName);
3019                mProcessCrashTimes.remove(info.processName, info.uid);
3020                if (mBadProcesses.get(info.processName, info.uid) != null) {
3021                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3022                            UserHandle.getUserId(info.uid), info.uid,
3023                            info.processName);
3024                    mBadProcesses.remove(info.processName, info.uid);
3025                    if (app != null) {
3026                        app.bad = false;
3027                    }
3028                }
3029            }
3030        }
3031
3032        if (app == null) {
3033            checkTime(startTime, "startProcess: creating new process record");
3034            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3035            app.crashHandler = crashHandler;
3036            if (app == null) {
3037                Slog.w(TAG, "Failed making new process record for "
3038                        + processName + "/" + info.uid + " isolated=" + isolated);
3039                return null;
3040            }
3041            mProcessNames.put(processName, app.uid, app);
3042            if (isolated) {
3043                mIsolatedProcesses.put(app.uid, app);
3044            }
3045            checkTime(startTime, "startProcess: done creating new process record");
3046        } else {
3047            // If this is a new package in the process, add the package to the list
3048            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3049            checkTime(startTime, "startProcess: added package to existing proc");
3050        }
3051
3052        // If the system is not ready yet, then hold off on starting this
3053        // process until it is.
3054        if (!mProcessesReady
3055                && !isAllowedWhileBooting(info)
3056                && !allowWhileBooting) {
3057            if (!mProcessesOnHold.contains(app)) {
3058                mProcessesOnHold.add(app);
3059            }
3060            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
3061            checkTime(startTime, "startProcess: returning with proc on hold");
3062            return app;
3063        }
3064
3065        checkTime(startTime, "startProcess: stepping in to startProcess");
3066        startProcessLocked(
3067                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3068        checkTime(startTime, "startProcess: done starting proc!");
3069        return (app.pid != 0) ? app : null;
3070    }
3071
3072    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3073        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3074    }
3075
3076    private final void startProcessLocked(ProcessRecord app,
3077            String hostingType, String hostingNameStr) {
3078        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3079                null /* entryPoint */, null /* entryPointArgs */);
3080    }
3081
3082    private final void startProcessLocked(ProcessRecord app, String hostingType,
3083            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3084        long startTime = SystemClock.elapsedRealtime();
3085        if (app.pid > 0 && app.pid != MY_PID) {
3086            checkTime(startTime, "startProcess: removing from pids map");
3087            synchronized (mPidsSelfLocked) {
3088                mPidsSelfLocked.remove(app.pid);
3089                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3090            }
3091            checkTime(startTime, "startProcess: done removing from pids map");
3092            app.setPid(0);
3093        }
3094
3095        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3096                "startProcessLocked removing on hold: " + app);
3097        mProcessesOnHold.remove(app);
3098
3099        checkTime(startTime, "startProcess: starting to update cpu stats");
3100        updateCpuStats();
3101        checkTime(startTime, "startProcess: done updating cpu stats");
3102
3103        try {
3104            int uid = app.uid;
3105
3106            int[] gids = null;
3107            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3108            if (!app.isolated) {
3109                int[] permGids = null;
3110                try {
3111                    checkTime(startTime, "startProcess: getting gids from package manager");
3112                    final PackageManager pm = mContext.getPackageManager();
3113                    permGids = pm.getPackageGids(app.info.packageName);
3114
3115                    if (Environment.isExternalStorageEmulated()) {
3116                        checkTime(startTime, "startProcess: checking external storage perm");
3117                        if (pm.checkPermission(
3118                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3119                                app.info.packageName) == PERMISSION_GRANTED) {
3120                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3121                        } else {
3122                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3123                        }
3124                    }
3125                } catch (PackageManager.NameNotFoundException e) {
3126                    Slog.w(TAG, "Unable to retrieve gids", e);
3127                }
3128
3129                /*
3130                 * Add shared application and profile GIDs so applications can share some
3131                 * resources like shared libraries and access user-wide resources
3132                 */
3133                if (permGids == null) {
3134                    gids = new int[2];
3135                } else {
3136                    gids = new int[permGids.length + 2];
3137                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3138                }
3139                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3140                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3141            }
3142            checkTime(startTime, "startProcess: building args");
3143            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3144                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3145                        && mTopComponent != null
3146                        && app.processName.equals(mTopComponent.getPackageName())) {
3147                    uid = 0;
3148                }
3149                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3150                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3151                    uid = 0;
3152                }
3153            }
3154            int debugFlags = 0;
3155            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3156                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3157                // Also turn on CheckJNI for debuggable apps. It's quite
3158                // awkward to turn on otherwise.
3159                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3160            }
3161            // Run the app in safe mode if its manifest requests so or the
3162            // system is booted in safe mode.
3163            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3164                mSafeMode == true) {
3165                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3166            }
3167            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3168                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3169            }
3170            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3171                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3172            }
3173            if ("1".equals(SystemProperties.get("debug.assert"))) {
3174                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3175            }
3176
3177            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3178            if (requiredAbi == null) {
3179                requiredAbi = Build.SUPPORTED_ABIS[0];
3180            }
3181
3182            String instructionSet = null;
3183            if (app.info.primaryCpuAbi != null) {
3184                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3185            }
3186
3187            // Start the process.  It will either succeed and return a result containing
3188            // the PID of the new process, or else throw a RuntimeException.
3189            boolean isActivityProcess = (entryPoint == null);
3190            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3191            checkTime(startTime, "startProcess: asking zygote to start proc");
3192            Process.ProcessStartResult startResult = Process.start(entryPoint,
3193                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3194                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3195                    app.info.dataDir, entryPointArgs);
3196            checkTime(startTime, "startProcess: returned from zygote!");
3197
3198            if (app.isolated) {
3199                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3200            }
3201            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3202            checkTime(startTime, "startProcess: done updating battery stats");
3203
3204            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3205                    UserHandle.getUserId(uid), startResult.pid, uid,
3206                    app.processName, hostingType,
3207                    hostingNameStr != null ? hostingNameStr : "");
3208
3209            if (app.persistent) {
3210                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3211            }
3212
3213            checkTime(startTime, "startProcess: building log message");
3214            StringBuilder buf = mStringBuilder;
3215            buf.setLength(0);
3216            buf.append("Start proc ");
3217            buf.append(app.processName);
3218            if (!isActivityProcess) {
3219                buf.append(" [");
3220                buf.append(entryPoint);
3221                buf.append("]");
3222            }
3223            buf.append(" for ");
3224            buf.append(hostingType);
3225            if (hostingNameStr != null) {
3226                buf.append(" ");
3227                buf.append(hostingNameStr);
3228            }
3229            buf.append(": pid=");
3230            buf.append(startResult.pid);
3231            buf.append(" uid=");
3232            buf.append(uid);
3233            buf.append(" gids={");
3234            if (gids != null) {
3235                for (int gi=0; gi<gids.length; gi++) {
3236                    if (gi != 0) buf.append(", ");
3237                    buf.append(gids[gi]);
3238
3239                }
3240            }
3241            buf.append("}");
3242            if (requiredAbi != null) {
3243                buf.append(" abi=");
3244                buf.append(requiredAbi);
3245            }
3246            Slog.i(TAG, buf.toString());
3247            app.setPid(startResult.pid);
3248            app.usingWrapper = startResult.usingWrapper;
3249            app.removed = false;
3250            app.killed = false;
3251            app.killedByAm = false;
3252            checkTime(startTime, "startProcess: starting to update pids map");
3253            synchronized (mPidsSelfLocked) {
3254                this.mPidsSelfLocked.put(startResult.pid, app);
3255                if (isActivityProcess) {
3256                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3257                    msg.obj = app;
3258                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3259                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3260                }
3261            }
3262            checkTime(startTime, "startProcess: done updating pids map");
3263        } catch (RuntimeException e) {
3264            // XXX do better error recovery.
3265            app.setPid(0);
3266            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3267            if (app.isolated) {
3268                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3269            }
3270            Slog.e(TAG, "Failure starting process " + app.processName, e);
3271        }
3272    }
3273
3274    void updateUsageStats(ActivityRecord component, boolean resumed) {
3275        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3276        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3277        if (resumed) {
3278            if (mUsageStatsService != null) {
3279                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3280                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3281            }
3282            synchronized (stats) {
3283                stats.noteActivityResumedLocked(component.app.uid);
3284            }
3285        } else {
3286            if (mUsageStatsService != null) {
3287                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3288                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3289            }
3290            synchronized (stats) {
3291                stats.noteActivityPausedLocked(component.app.uid);
3292            }
3293        }
3294    }
3295
3296    Intent getHomeIntent() {
3297        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3298        intent.setComponent(mTopComponent);
3299        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3300            intent.addCategory(Intent.CATEGORY_HOME);
3301        }
3302        return intent;
3303    }
3304
3305    boolean startHomeActivityLocked(int userId) {
3306        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3307                && mTopAction == null) {
3308            // We are running in factory test mode, but unable to find
3309            // the factory test app, so just sit around displaying the
3310            // error message and don't try to start anything.
3311            return false;
3312        }
3313        Intent intent = getHomeIntent();
3314        ActivityInfo aInfo =
3315            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3316        if (aInfo != null) {
3317            intent.setComponent(new ComponentName(
3318                    aInfo.applicationInfo.packageName, aInfo.name));
3319            // Don't do this if the home app is currently being
3320            // instrumented.
3321            aInfo = new ActivityInfo(aInfo);
3322            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3323            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3324                    aInfo.applicationInfo.uid, true);
3325            if (app == null || app.instrumentationClass == null) {
3326                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3327                mStackSupervisor.startHomeActivity(intent, aInfo);
3328            }
3329        }
3330
3331        return true;
3332    }
3333
3334    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3335        ActivityInfo ai = null;
3336        ComponentName comp = intent.getComponent();
3337        try {
3338            if (comp != null) {
3339                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3340            } else {
3341                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3342                        intent,
3343                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3344                            flags, userId);
3345
3346                if (info != null) {
3347                    ai = info.activityInfo;
3348                }
3349            }
3350        } catch (RemoteException e) {
3351            // ignore
3352        }
3353
3354        return ai;
3355    }
3356
3357    /**
3358     * Starts the "new version setup screen" if appropriate.
3359     */
3360    void startSetupActivityLocked() {
3361        // Only do this once per boot.
3362        if (mCheckedForSetup) {
3363            return;
3364        }
3365
3366        // We will show this screen if the current one is a different
3367        // version than the last one shown, and we are not running in
3368        // low-level factory test mode.
3369        final ContentResolver resolver = mContext.getContentResolver();
3370        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3371                Settings.Global.getInt(resolver,
3372                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3373            mCheckedForSetup = true;
3374
3375            // See if we should be showing the platform update setup UI.
3376            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3377            List<ResolveInfo> ris = mContext.getPackageManager()
3378                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3379
3380            // We don't allow third party apps to replace this.
3381            ResolveInfo ri = null;
3382            for (int i=0; ris != null && i<ris.size(); i++) {
3383                if ((ris.get(i).activityInfo.applicationInfo.flags
3384                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3385                    ri = ris.get(i);
3386                    break;
3387                }
3388            }
3389
3390            if (ri != null) {
3391                String vers = ri.activityInfo.metaData != null
3392                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3393                        : null;
3394                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3395                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3396                            Intent.METADATA_SETUP_VERSION);
3397                }
3398                String lastVers = Settings.Secure.getString(
3399                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3400                if (vers != null && !vers.equals(lastVers)) {
3401                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3402                    intent.setComponent(new ComponentName(
3403                            ri.activityInfo.packageName, ri.activityInfo.name));
3404                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3405                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3406                            null);
3407                }
3408            }
3409        }
3410    }
3411
3412    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3413        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3414    }
3415
3416    void enforceNotIsolatedCaller(String caller) {
3417        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3418            throw new SecurityException("Isolated process not allowed to call " + caller);
3419        }
3420    }
3421
3422    void enforceShellRestriction(String restriction, int userHandle) {
3423        if (Binder.getCallingUid() == Process.SHELL_UID) {
3424            if (userHandle < 0
3425                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3426                throw new SecurityException("Shell does not have permission to access user "
3427                        + userHandle);
3428            }
3429        }
3430    }
3431
3432    @Override
3433    public int getFrontActivityScreenCompatMode() {
3434        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3435        synchronized (this) {
3436            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3437        }
3438    }
3439
3440    @Override
3441    public void setFrontActivityScreenCompatMode(int mode) {
3442        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3443                "setFrontActivityScreenCompatMode");
3444        synchronized (this) {
3445            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3446        }
3447    }
3448
3449    @Override
3450    public int getPackageScreenCompatMode(String packageName) {
3451        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3452        synchronized (this) {
3453            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3454        }
3455    }
3456
3457    @Override
3458    public void setPackageScreenCompatMode(String packageName, int mode) {
3459        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3460                "setPackageScreenCompatMode");
3461        synchronized (this) {
3462            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3463        }
3464    }
3465
3466    @Override
3467    public boolean getPackageAskScreenCompat(String packageName) {
3468        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3469        synchronized (this) {
3470            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3471        }
3472    }
3473
3474    @Override
3475    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3476        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3477                "setPackageAskScreenCompat");
3478        synchronized (this) {
3479            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3480        }
3481    }
3482
3483    private void dispatchProcessesChanged() {
3484        int N;
3485        synchronized (this) {
3486            N = mPendingProcessChanges.size();
3487            if (mActiveProcessChanges.length < N) {
3488                mActiveProcessChanges = new ProcessChangeItem[N];
3489            }
3490            mPendingProcessChanges.toArray(mActiveProcessChanges);
3491            mAvailProcessChanges.addAll(mPendingProcessChanges);
3492            mPendingProcessChanges.clear();
3493            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3494        }
3495
3496        int i = mProcessObservers.beginBroadcast();
3497        while (i > 0) {
3498            i--;
3499            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3500            if (observer != null) {
3501                try {
3502                    for (int j=0; j<N; j++) {
3503                        ProcessChangeItem item = mActiveProcessChanges[j];
3504                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3505                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3506                                    + item.pid + " uid=" + item.uid + ": "
3507                                    + item.foregroundActivities);
3508                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3509                                    item.foregroundActivities);
3510                        }
3511                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3512                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3513                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3514                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3515                        }
3516                    }
3517                } catch (RemoteException e) {
3518                }
3519            }
3520        }
3521        mProcessObservers.finishBroadcast();
3522    }
3523
3524    private void dispatchProcessDied(int pid, int uid) {
3525        int i = mProcessObservers.beginBroadcast();
3526        while (i > 0) {
3527            i--;
3528            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3529            if (observer != null) {
3530                try {
3531                    observer.onProcessDied(pid, uid);
3532                } catch (RemoteException e) {
3533                }
3534            }
3535        }
3536        mProcessObservers.finishBroadcast();
3537    }
3538
3539    @Override
3540    public final int startActivity(IApplicationThread caller, String callingPackage,
3541            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3542            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3543        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3544            resultWho, requestCode, startFlags, profilerInfo, options,
3545            UserHandle.getCallingUserId());
3546    }
3547
3548    @Override
3549    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3550            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3551            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3552        enforceNotIsolatedCaller("startActivity");
3553        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3554                false, ALLOW_FULL_ONLY, "startActivity", null);
3555        // TODO: Switch to user app stacks here.
3556        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3557                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3558                profilerInfo, null, null, options, userId, null, null);
3559    }
3560
3561    @Override
3562    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3563            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3564            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3565
3566        // This is very dangerous -- it allows you to perform a start activity (including
3567        // permission grants) as any app that may launch one of your own activities.  So
3568        // we will only allow this to be done from activities that are part of the core framework,
3569        // and then only when they are running as the system.
3570        final ActivityRecord sourceRecord;
3571        final int targetUid;
3572        final String targetPackage;
3573        synchronized (this) {
3574            if (resultTo == null) {
3575                throw new SecurityException("Must be called from an activity");
3576            }
3577            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3578            if (sourceRecord == null) {
3579                throw new SecurityException("Called with bad activity token: " + resultTo);
3580            }
3581            if (!sourceRecord.info.packageName.equals("android")) {
3582                throw new SecurityException(
3583                        "Must be called from an activity that is declared in the android package");
3584            }
3585            if (sourceRecord.app == null) {
3586                throw new SecurityException("Called without a process attached to activity");
3587            }
3588            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3589                // This is still okay, as long as this activity is running under the
3590                // uid of the original calling activity.
3591                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3592                    throw new SecurityException(
3593                            "Calling activity in uid " + sourceRecord.app.uid
3594                                    + " must be system uid or original calling uid "
3595                                    + sourceRecord.launchedFromUid);
3596                }
3597            }
3598            targetUid = sourceRecord.launchedFromUid;
3599            targetPackage = sourceRecord.launchedFromPackage;
3600        }
3601
3602        // TODO: Switch to user app stacks here.
3603        try {
3604            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3605                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3606                    null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null);
3607            return ret;
3608        } catch (SecurityException e) {
3609            // XXX need to figure out how to propagate to original app.
3610            // A SecurityException here is generally actually a fault of the original
3611            // calling activity (such as a fairly granting permissions), so propagate it
3612            // back to them.
3613            /*
3614            StringBuilder msg = new StringBuilder();
3615            msg.append("While launching");
3616            msg.append(intent.toString());
3617            msg.append(": ");
3618            msg.append(e.getMessage());
3619            */
3620            throw e;
3621        }
3622    }
3623
3624    @Override
3625    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3626            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3627            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3628        enforceNotIsolatedCaller("startActivityAndWait");
3629        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3630                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3631        WaitResult res = new WaitResult();
3632        // TODO: Switch to user app stacks here.
3633        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3634                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3635                options, userId, null, null);
3636        return res;
3637    }
3638
3639    @Override
3640    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3641            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3642            int startFlags, Configuration config, Bundle options, int userId) {
3643        enforceNotIsolatedCaller("startActivityWithConfig");
3644        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3645                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3646        // TODO: Switch to user app stacks here.
3647        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3648                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3649                null, null, config, options, userId, null, null);
3650        return ret;
3651    }
3652
3653    @Override
3654    public int startActivityIntentSender(IApplicationThread caller,
3655            IntentSender intent, Intent fillInIntent, String resolvedType,
3656            IBinder resultTo, String resultWho, int requestCode,
3657            int flagsMask, int flagsValues, Bundle options) {
3658        enforceNotIsolatedCaller("startActivityIntentSender");
3659        // Refuse possible leaked file descriptors
3660        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3661            throw new IllegalArgumentException("File descriptors passed in Intent");
3662        }
3663
3664        IIntentSender sender = intent.getTarget();
3665        if (!(sender instanceof PendingIntentRecord)) {
3666            throw new IllegalArgumentException("Bad PendingIntent object");
3667        }
3668
3669        PendingIntentRecord pir = (PendingIntentRecord)sender;
3670
3671        synchronized (this) {
3672            // If this is coming from the currently resumed activity, it is
3673            // effectively saying that app switches are allowed at this point.
3674            final ActivityStack stack = getFocusedStack();
3675            if (stack.mResumedActivity != null &&
3676                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3677                mAppSwitchesAllowedTime = 0;
3678            }
3679        }
3680        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3681                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3682        return ret;
3683    }
3684
3685    @Override
3686    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3687            Intent intent, String resolvedType, IVoiceInteractionSession session,
3688            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3689            Bundle options, int userId) {
3690        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3691                != PackageManager.PERMISSION_GRANTED) {
3692            String msg = "Permission Denial: startVoiceActivity() from pid="
3693                    + Binder.getCallingPid()
3694                    + ", uid=" + Binder.getCallingUid()
3695                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3696            Slog.w(TAG, msg);
3697            throw new SecurityException(msg);
3698        }
3699        if (session == null || interactor == null) {
3700            throw new NullPointerException("null session or interactor");
3701        }
3702        userId = handleIncomingUser(callingPid, callingUid, userId,
3703                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3704        // TODO: Switch to user app stacks here.
3705        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3706                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3707                null, options, userId, null, null);
3708    }
3709
3710    @Override
3711    public boolean startNextMatchingActivity(IBinder callingActivity,
3712            Intent intent, Bundle options) {
3713        // Refuse possible leaked file descriptors
3714        if (intent != null && intent.hasFileDescriptors() == true) {
3715            throw new IllegalArgumentException("File descriptors passed in Intent");
3716        }
3717
3718        synchronized (this) {
3719            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3720            if (r == null) {
3721                ActivityOptions.abort(options);
3722                return false;
3723            }
3724            if (r.app == null || r.app.thread == null) {
3725                // The caller is not running...  d'oh!
3726                ActivityOptions.abort(options);
3727                return false;
3728            }
3729            intent = new Intent(intent);
3730            // The caller is not allowed to change the data.
3731            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3732            // And we are resetting to find the next component...
3733            intent.setComponent(null);
3734
3735            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3736
3737            ActivityInfo aInfo = null;
3738            try {
3739                List<ResolveInfo> resolves =
3740                    AppGlobals.getPackageManager().queryIntentActivities(
3741                            intent, r.resolvedType,
3742                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3743                            UserHandle.getCallingUserId());
3744
3745                // Look for the original activity in the list...
3746                final int N = resolves != null ? resolves.size() : 0;
3747                for (int i=0; i<N; i++) {
3748                    ResolveInfo rInfo = resolves.get(i);
3749                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3750                            && rInfo.activityInfo.name.equals(r.info.name)) {
3751                        // We found the current one...  the next matching is
3752                        // after it.
3753                        i++;
3754                        if (i<N) {
3755                            aInfo = resolves.get(i).activityInfo;
3756                        }
3757                        if (debug) {
3758                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3759                                    + "/" + r.info.name);
3760                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3761                                    + "/" + aInfo.name);
3762                        }
3763                        break;
3764                    }
3765                }
3766            } catch (RemoteException e) {
3767            }
3768
3769            if (aInfo == null) {
3770                // Nobody who is next!
3771                ActivityOptions.abort(options);
3772                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3773                return false;
3774            }
3775
3776            intent.setComponent(new ComponentName(
3777                    aInfo.applicationInfo.packageName, aInfo.name));
3778            intent.setFlags(intent.getFlags()&~(
3779                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3780                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3781                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3782                    Intent.FLAG_ACTIVITY_NEW_TASK));
3783
3784            // Okay now we need to start the new activity, replacing the
3785            // currently running activity.  This is a little tricky because
3786            // we want to start the new one as if the current one is finished,
3787            // but not finish the current one first so that there is no flicker.
3788            // And thus...
3789            final boolean wasFinishing = r.finishing;
3790            r.finishing = true;
3791
3792            // Propagate reply information over to the new activity.
3793            final ActivityRecord resultTo = r.resultTo;
3794            final String resultWho = r.resultWho;
3795            final int requestCode = r.requestCode;
3796            r.resultTo = null;
3797            if (resultTo != null) {
3798                resultTo.removeResultsLocked(r, resultWho, requestCode);
3799            }
3800
3801            final long origId = Binder.clearCallingIdentity();
3802            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3803                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3804                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3805                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3806            Binder.restoreCallingIdentity(origId);
3807
3808            r.finishing = wasFinishing;
3809            if (res != ActivityManager.START_SUCCESS) {
3810                return false;
3811            }
3812            return true;
3813        }
3814    }
3815
3816    @Override
3817    public final int startActivityFromRecents(int taskId, Bundle options) {
3818        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3819            String msg = "Permission Denial: startActivityFromRecents called without " +
3820                    START_TASKS_FROM_RECENTS;
3821            Slog.w(TAG, msg);
3822            throw new SecurityException(msg);
3823        }
3824        return startActivityFromRecentsInner(taskId, options);
3825    }
3826
3827    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3828        final TaskRecord task;
3829        final int callingUid;
3830        final String callingPackage;
3831        final Intent intent;
3832        final int userId;
3833        synchronized (this) {
3834            task = recentTaskForIdLocked(taskId);
3835            if (task == null) {
3836                throw new IllegalArgumentException("Task " + taskId + " not found.");
3837            }
3838            callingUid = task.mCallingUid;
3839            callingPackage = task.mCallingPackage;
3840            intent = task.intent;
3841            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3842            userId = task.userId;
3843        }
3844        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3845                options, userId, null, task);
3846    }
3847
3848    final int startActivityInPackage(int uid, String callingPackage,
3849            Intent intent, String resolvedType, IBinder resultTo,
3850            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3851            IActivityContainer container, TaskRecord inTask) {
3852
3853        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3854                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3855
3856        // TODO: Switch to user app stacks here.
3857        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3858                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3859                null, null, null, options, userId, container, inTask);
3860        return ret;
3861    }
3862
3863    @Override
3864    public final int startActivities(IApplicationThread caller, String callingPackage,
3865            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3866            int userId) {
3867        enforceNotIsolatedCaller("startActivities");
3868        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3869                false, ALLOW_FULL_ONLY, "startActivity", null);
3870        // TODO: Switch to user app stacks here.
3871        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3872                resolvedTypes, resultTo, options, userId);
3873        return ret;
3874    }
3875
3876    final int startActivitiesInPackage(int uid, String callingPackage,
3877            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3878            Bundle options, int userId) {
3879
3880        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3881                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3882        // TODO: Switch to user app stacks here.
3883        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3884                resultTo, options, userId);
3885        return ret;
3886    }
3887
3888    //explicitly remove thd old information in mRecentTasks when removing existing user.
3889    private void removeRecentTasksForUserLocked(int userId) {
3890        if(userId <= 0) {
3891            Slog.i(TAG, "Can't remove recent task on user " + userId);
3892            return;
3893        }
3894
3895        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3896            TaskRecord tr = mRecentTasks.get(i);
3897            if (tr.userId == userId) {
3898                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3899                        + " when finishing user" + userId);
3900                mRecentTasks.remove(i);
3901                tr.removedFromRecents(mTaskPersister);
3902            }
3903        }
3904
3905        // Remove tasks from persistent storage.
3906        mTaskPersister.wakeup(null, true);
3907    }
3908
3909    // Sort by taskId
3910    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3911        @Override
3912        public int compare(TaskRecord lhs, TaskRecord rhs) {
3913            return rhs.taskId - lhs.taskId;
3914        }
3915    };
3916
3917    // Extract the affiliates of the chain containing mRecentTasks[start].
3918    private int processNextAffiliateChain(int start) {
3919        final TaskRecord startTask = mRecentTasks.get(start);
3920        final int affiliateId = startTask.mAffiliatedTaskId;
3921
3922        // Quick identification of isolated tasks. I.e. those not launched behind.
3923        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3924                startTask.mNextAffiliate == null) {
3925            // There is still a slim chance that there are other tasks that point to this task
3926            // and that the chain is so messed up that this task no longer points to them but
3927            // the gain of this optimization outweighs the risk.
3928            startTask.inRecents = true;
3929            return start + 1;
3930        }
3931
3932        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3933        mTmpRecents.clear();
3934        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3935            final TaskRecord task = mRecentTasks.get(i);
3936            if (task.mAffiliatedTaskId == affiliateId) {
3937                mRecentTasks.remove(i);
3938                mTmpRecents.add(task);
3939            }
3940        }
3941
3942        // Sort them all by taskId. That is the order they were create in and that order will
3943        // always be correct.
3944        Collections.sort(mTmpRecents, mTaskRecordComparator);
3945
3946        // Go through and fix up the linked list.
3947        // The first one is the end of the chain and has no next.
3948        final TaskRecord first = mTmpRecents.get(0);
3949        first.inRecents = true;
3950        if (first.mNextAffiliate != null) {
3951            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3952            first.setNextAffiliate(null);
3953            mTaskPersister.wakeup(first, false);
3954        }
3955        // Everything in the middle is doubly linked from next to prev.
3956        final int tmpSize = mTmpRecents.size();
3957        for (int i = 0; i < tmpSize - 1; ++i) {
3958            final TaskRecord next = mTmpRecents.get(i);
3959            final TaskRecord prev = mTmpRecents.get(i + 1);
3960            if (next.mPrevAffiliate != prev) {
3961                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3962                        " setting prev=" + prev);
3963                next.setPrevAffiliate(prev);
3964                mTaskPersister.wakeup(next, false);
3965            }
3966            if (prev.mNextAffiliate != next) {
3967                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3968                        " setting next=" + next);
3969                prev.setNextAffiliate(next);
3970                mTaskPersister.wakeup(prev, false);
3971            }
3972            prev.inRecents = true;
3973        }
3974        // The last one is the beginning of the list and has no prev.
3975        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3976        if (last.mPrevAffiliate != null) {
3977            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3978            last.setPrevAffiliate(null);
3979            mTaskPersister.wakeup(last, false);
3980        }
3981
3982        // Insert the group back into mRecentTasks at start.
3983        mRecentTasks.addAll(start, mTmpRecents);
3984
3985        // Let the caller know where we left off.
3986        return start + tmpSize;
3987    }
3988
3989    /**
3990     * Update the recent tasks lists: make sure tasks should still be here (their
3991     * applications / activities still exist), update their availability, fixup ordering
3992     * of affiliations.
3993     */
3994    void cleanupRecentTasksLocked(int userId) {
3995        if (mRecentTasks == null) {
3996            // Happens when called from the packagemanager broadcast before boot.
3997            return;
3998        }
3999
4000        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
4001        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
4002        final IPackageManager pm = AppGlobals.getPackageManager();
4003        final ActivityInfo dummyAct = new ActivityInfo();
4004        final ApplicationInfo dummyApp = new ApplicationInfo();
4005
4006        int N = mRecentTasks.size();
4007
4008        int[] users = userId == UserHandle.USER_ALL
4009                ? getUsersLocked() : new int[] { userId };
4010        for (int user : users) {
4011            for (int i = 0; i < N; i++) {
4012                TaskRecord task = mRecentTasks.get(i);
4013                if (task.userId != user) {
4014                    // Only look at tasks for the user ID of interest.
4015                    continue;
4016                }
4017                if (task.autoRemoveRecents && task.getTopActivity() == null) {
4018                    // This situation is broken, and we should just get rid of it now.
4019                    mRecentTasks.remove(i);
4020                    task.removedFromRecents(mTaskPersister);
4021                    i--;
4022                    N--;
4023                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
4024                    continue;
4025                }
4026                // Check whether this activity is currently available.
4027                if (task.realActivity != null) {
4028                    ActivityInfo ai = availActCache.get(task.realActivity);
4029                    if (ai == null) {
4030                        try {
4031                            ai = pm.getActivityInfo(task.realActivity,
4032                                    PackageManager.GET_UNINSTALLED_PACKAGES
4033                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
4034                        } catch (RemoteException e) {
4035                            // Will never happen.
4036                            continue;
4037                        }
4038                        if (ai == null) {
4039                            ai = dummyAct;
4040                        }
4041                        availActCache.put(task.realActivity, ai);
4042                    }
4043                    if (ai == dummyAct) {
4044                        // This could be either because the activity no longer exists, or the
4045                        // app is temporarily gone.  For the former we want to remove the recents
4046                        // entry; for the latter we want to mark it as unavailable.
4047                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
4048                        if (app == null) {
4049                            try {
4050                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
4051                                        PackageManager.GET_UNINSTALLED_PACKAGES
4052                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
4053                            } catch (RemoteException e) {
4054                                // Will never happen.
4055                                continue;
4056                            }
4057                            if (app == null) {
4058                                app = dummyApp;
4059                            }
4060                            availAppCache.put(task.realActivity.getPackageName(), app);
4061                        }
4062                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4063                            // Doesn't exist any more!  Good-bye.
4064                            mRecentTasks.remove(i);
4065                            task.removedFromRecents(mTaskPersister);
4066                            i--;
4067                            N--;
4068                            Slog.w(TAG, "Removing no longer valid recent: " + task);
4069                            continue;
4070                        } else {
4071                            // Otherwise just not available for now.
4072                            if (task.isAvailable) {
4073                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4074                                        + task);
4075                            }
4076                            task.isAvailable = false;
4077                        }
4078                    } else {
4079                        if (!ai.enabled || !ai.applicationInfo.enabled
4080                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4081                            if (task.isAvailable) {
4082                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4083                                        + task + " (enabled=" + ai.enabled + "/"
4084                                        + ai.applicationInfo.enabled +  " flags="
4085                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
4086                            }
4087                            task.isAvailable = false;
4088                        } else {
4089                            if (!task.isAvailable) {
4090                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
4091                                        + task);
4092                            }
4093                            task.isAvailable = true;
4094                        }
4095                    }
4096                }
4097            }
4098        }
4099
4100        // Verify the affiliate chain for each task.
4101        for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
4102        }
4103
4104        mTmpRecents.clear();
4105        // mRecentTasks is now in sorted, affiliated order.
4106    }
4107
4108    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
4109        int N = mRecentTasks.size();
4110        TaskRecord top = task;
4111        int topIndex = taskIndex;
4112        while (top.mNextAffiliate != null && topIndex > 0) {
4113            top = top.mNextAffiliate;
4114            topIndex--;
4115        }
4116        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
4117                + topIndex + " from intial " + taskIndex);
4118        // Find the end of the chain, doing a sanity check along the way.
4119        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
4120        int endIndex = topIndex;
4121        TaskRecord prev = top;
4122        while (endIndex < N) {
4123            TaskRecord cur = mRecentTasks.get(endIndex);
4124            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
4125                    + endIndex + " " + cur);
4126            if (cur == top) {
4127                // Verify start of the chain.
4128                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
4129                    Slog.wtf(TAG, "Bad chain @" + endIndex
4130                            + ": first task has next affiliate: " + prev);
4131                    sane = false;
4132                    break;
4133                }
4134            } else {
4135                // Verify middle of the chain's next points back to the one before.
4136                if (cur.mNextAffiliate != prev
4137                        || cur.mNextAffiliateTaskId != prev.taskId) {
4138                    Slog.wtf(TAG, "Bad chain @" + endIndex
4139                            + ": middle task " + cur + " @" + endIndex
4140                            + " has bad next affiliate "
4141                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4142                            + ", expected " + prev);
4143                    sane = false;
4144                    break;
4145                }
4146            }
4147            if (cur.mPrevAffiliateTaskId == -1) {
4148                // Chain ends here.
4149                if (cur.mPrevAffiliate != null) {
4150                    Slog.wtf(TAG, "Bad chain @" + endIndex
4151                            + ": last task " + cur + " has previous affiliate "
4152                            + cur.mPrevAffiliate);
4153                    sane = false;
4154                }
4155                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4156                break;
4157            } else {
4158                // Verify middle of the chain's prev points to a valid item.
4159                if (cur.mPrevAffiliate == null) {
4160                    Slog.wtf(TAG, "Bad chain @" + endIndex
4161                            + ": task " + cur + " has previous affiliate "
4162                            + cur.mPrevAffiliate + " but should be id "
4163                            + cur.mPrevAffiliate);
4164                    sane = false;
4165                    break;
4166                }
4167            }
4168            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4169                Slog.wtf(TAG, "Bad chain @" + endIndex
4170                        + ": task " + cur + " has affiliated id "
4171                        + cur.mAffiliatedTaskId + " but should be "
4172                        + task.mAffiliatedTaskId);
4173                sane = false;
4174                break;
4175            }
4176            prev = cur;
4177            endIndex++;
4178            if (endIndex >= N) {
4179                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4180                        + ": last task " + prev);
4181                sane = false;
4182                break;
4183            }
4184        }
4185        if (sane) {
4186            if (endIndex < taskIndex) {
4187                Slog.wtf(TAG, "Bad chain @" + endIndex
4188                        + ": did not extend to task " + task + " @" + taskIndex);
4189                sane = false;
4190            }
4191        }
4192        if (sane) {
4193            // All looks good, we can just move all of the affiliated tasks
4194            // to the top.
4195            for (int i=topIndex; i<=endIndex; i++) {
4196                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4197                        + " from " + i + " to " + (i-topIndex));
4198                TaskRecord cur = mRecentTasks.remove(i);
4199                mRecentTasks.add(i-topIndex, cur);
4200            }
4201            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4202                    + " to " + endIndex);
4203            return true;
4204        }
4205
4206        // Whoops, couldn't do it.
4207        return false;
4208    }
4209
4210    final void addRecentTaskLocked(TaskRecord task) {
4211        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4212                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4213
4214        int N = mRecentTasks.size();
4215        // Quick case: check if the top-most recent task is the same.
4216        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4217            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4218            return;
4219        }
4220        // Another quick case: check if this is part of a set of affiliated
4221        // tasks that are at the top.
4222        if (isAffiliated && N > 0 && task.inRecents
4223                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4224            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4225                    + " at top when adding " + task);
4226            return;
4227        }
4228        // Another quick case: never add voice sessions.
4229        if (task.voiceSession != null) {
4230            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4231            return;
4232        }
4233
4234        boolean needAffiliationFix = false;
4235
4236        // Slightly less quick case: the task is already in recents, so all we need
4237        // to do is move it.
4238        if (task.inRecents) {
4239            int taskIndex = mRecentTasks.indexOf(task);
4240            if (taskIndex >= 0) {
4241                if (!isAffiliated) {
4242                    // Simple case: this is not an affiliated task, so we just move it to the front.
4243                    mRecentTasks.remove(taskIndex);
4244                    mRecentTasks.add(0, task);
4245                    notifyTaskPersisterLocked(task, false);
4246                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4247                            + " from " + taskIndex);
4248                    return;
4249                } else {
4250                    // More complicated: need to keep all affiliated tasks together.
4251                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4252                        // All went well.
4253                        return;
4254                    }
4255
4256                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4257                    // everything and then go through our general path of adding a new task.
4258                    needAffiliationFix = true;
4259                }
4260            } else {
4261                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4262                needAffiliationFix = true;
4263            }
4264        }
4265
4266        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4267        trimRecentsForTask(task, true);
4268
4269        N = mRecentTasks.size();
4270        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4271            final TaskRecord tr = mRecentTasks.remove(N - 1);
4272            tr.removedFromRecents(mTaskPersister);
4273            N--;
4274        }
4275        task.inRecents = true;
4276        if (!isAffiliated || needAffiliationFix) {
4277            // If this is a simple non-affiliated task, or we had some failure trying to
4278            // handle it as part of an affilated task, then just place it at the top.
4279            mRecentTasks.add(0, task);
4280        } else if (isAffiliated) {
4281            // If this is a new affiliated task, then move all of the affiliated tasks
4282            // to the front and insert this new one.
4283            TaskRecord other = task.mNextAffiliate;
4284            if (other == null) {
4285                other = task.mPrevAffiliate;
4286            }
4287            if (other != null) {
4288                int otherIndex = mRecentTasks.indexOf(other);
4289                if (otherIndex >= 0) {
4290                    // Insert new task at appropriate location.
4291                    int taskIndex;
4292                    if (other == task.mNextAffiliate) {
4293                        // We found the index of our next affiliation, which is who is
4294                        // before us in the list, so add after that point.
4295                        taskIndex = otherIndex+1;
4296                    } else {
4297                        // We found the index of our previous affiliation, which is who is
4298                        // after us in the list, so add at their position.
4299                        taskIndex = otherIndex;
4300                    }
4301                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4302                            + taskIndex + ": " + task);
4303                    mRecentTasks.add(taskIndex, task);
4304
4305                    // Now move everything to the front.
4306                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4307                        // All went well.
4308                        return;
4309                    }
4310
4311                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4312                    // everything and then go through our general path of adding a new task.
4313                    needAffiliationFix = true;
4314                } else {
4315                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4316                            + other);
4317                    needAffiliationFix = true;
4318                }
4319            } else {
4320                if (DEBUG_RECENTS) Slog.d(TAG,
4321                        "addRecent: adding affiliated task without next/prev:" + task);
4322                needAffiliationFix = true;
4323            }
4324        }
4325        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4326
4327        if (needAffiliationFix) {
4328            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4329            cleanupRecentTasksLocked(task.userId);
4330        }
4331    }
4332
4333    /**
4334     * If needed, remove oldest existing entries in recents that are for the same kind
4335     * of task as the given one.
4336     */
4337    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4338        int N = mRecentTasks.size();
4339        final Intent intent = task.intent;
4340        final boolean document = intent != null && intent.isDocument();
4341
4342        int maxRecents = task.maxRecents - 1;
4343        for (int i=0; i<N; i++) {
4344            final TaskRecord tr = mRecentTasks.get(i);
4345            if (task != tr) {
4346                if (task.userId != tr.userId) {
4347                    continue;
4348                }
4349                if (i > MAX_RECENT_BITMAPS) {
4350                    tr.freeLastThumbnail();
4351                }
4352                final Intent trIntent = tr.intent;
4353                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4354                    (intent == null || !intent.filterEquals(trIntent))) {
4355                    continue;
4356                }
4357                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4358                if (document && trIsDocument) {
4359                    // These are the same document activity (not necessarily the same doc).
4360                    if (maxRecents > 0) {
4361                        --maxRecents;
4362                        continue;
4363                    }
4364                    // Hit the maximum number of documents for this task. Fall through
4365                    // and remove this document from recents.
4366                } else if (document || trIsDocument) {
4367                    // Only one of these is a document. Not the droid we're looking for.
4368                    continue;
4369                }
4370            }
4371
4372            if (!doTrim) {
4373                // If the caller is not actually asking for a trim, just tell them we reached
4374                // a point where the trim would happen.
4375                return i;
4376            }
4377
4378            // Either task and tr are the same or, their affinities match or their intents match
4379            // and neither of them is a document, or they are documents using the same activity
4380            // and their maxRecents has been reached.
4381            tr.disposeThumbnail();
4382            mRecentTasks.remove(i);
4383            if (task != tr) {
4384                tr.removedFromRecents(mTaskPersister);
4385            }
4386            i--;
4387            N--;
4388            if (task.intent == null) {
4389                // If the new recent task we are adding is not fully
4390                // specified, then replace it with the existing recent task.
4391                task = tr;
4392            }
4393            notifyTaskPersisterLocked(tr, false);
4394        }
4395
4396        return -1;
4397    }
4398
4399    @Override
4400    public void reportActivityFullyDrawn(IBinder token) {
4401        synchronized (this) {
4402            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4403            if (r == null) {
4404                return;
4405            }
4406            r.reportFullyDrawnLocked();
4407        }
4408    }
4409
4410    @Override
4411    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4412        synchronized (this) {
4413            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4414            if (r == null) {
4415                return;
4416            }
4417            final long origId = Binder.clearCallingIdentity();
4418            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4419            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4420                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4421            if (config != null) {
4422                r.frozenBeforeDestroy = true;
4423                if (!updateConfigurationLocked(config, r, false, false)) {
4424                    mStackSupervisor.resumeTopActivitiesLocked();
4425                }
4426            }
4427            Binder.restoreCallingIdentity(origId);
4428        }
4429    }
4430
4431    @Override
4432    public int getRequestedOrientation(IBinder token) {
4433        synchronized (this) {
4434            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4435            if (r == null) {
4436                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4437            }
4438            return mWindowManager.getAppOrientation(r.appToken);
4439        }
4440    }
4441
4442    /**
4443     * This is the internal entry point for handling Activity.finish().
4444     *
4445     * @param token The Binder token referencing the Activity we want to finish.
4446     * @param resultCode Result code, if any, from this Activity.
4447     * @param resultData Result data (Intent), if any, from this Activity.
4448     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4449     *            the root Activity in the task.
4450     *
4451     * @return Returns true if the activity successfully finished, or false if it is still running.
4452     */
4453    @Override
4454    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4455            boolean finishTask) {
4456        // Refuse possible leaked file descriptors
4457        if (resultData != null && resultData.hasFileDescriptors() == true) {
4458            throw new IllegalArgumentException("File descriptors passed in Intent");
4459        }
4460
4461        synchronized(this) {
4462            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4463            if (r == null) {
4464                return true;
4465            }
4466            // Keep track of the root activity of the task before we finish it
4467            TaskRecord tr = r.task;
4468            ActivityRecord rootR = tr.getRootActivity();
4469            // Do not allow task to finish in Lock Task mode.
4470            if (tr == mStackSupervisor.mLockTaskModeTask) {
4471                if (rootR == r) {
4472                    mStackSupervisor.showLockTaskToast();
4473                    return false;
4474                }
4475            }
4476            if (mController != null) {
4477                // Find the first activity that is not finishing.
4478                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4479                if (next != null) {
4480                    // ask watcher if this is allowed
4481                    boolean resumeOK = true;
4482                    try {
4483                        resumeOK = mController.activityResuming(next.packageName);
4484                    } catch (RemoteException e) {
4485                        mController = null;
4486                        Watchdog.getInstance().setActivityController(null);
4487                    }
4488
4489                    if (!resumeOK) {
4490                        return false;
4491                    }
4492                }
4493            }
4494            final long origId = Binder.clearCallingIdentity();
4495            try {
4496                boolean res;
4497                if (finishTask && r == rootR) {
4498                    // If requested, remove the task that is associated to this activity only if it
4499                    // was the root activity in the task.  The result code and data is ignored because
4500                    // we don't support returning them across task boundaries.
4501                    res = removeTaskByIdLocked(tr.taskId, 0);
4502                } else {
4503                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4504                            resultData, "app-request", true);
4505                }
4506                return res;
4507            } finally {
4508                Binder.restoreCallingIdentity(origId);
4509            }
4510        }
4511    }
4512
4513    @Override
4514    public final void finishHeavyWeightApp() {
4515        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4516                != PackageManager.PERMISSION_GRANTED) {
4517            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4518                    + Binder.getCallingPid()
4519                    + ", uid=" + Binder.getCallingUid()
4520                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4521            Slog.w(TAG, msg);
4522            throw new SecurityException(msg);
4523        }
4524
4525        synchronized(this) {
4526            if (mHeavyWeightProcess == null) {
4527                return;
4528            }
4529
4530            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4531                    mHeavyWeightProcess.activities);
4532            for (int i=0; i<activities.size(); i++) {
4533                ActivityRecord r = activities.get(i);
4534                if (!r.finishing) {
4535                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4536                            null, "finish-heavy", true);
4537                }
4538            }
4539
4540            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4541                    mHeavyWeightProcess.userId, 0));
4542            mHeavyWeightProcess = null;
4543        }
4544    }
4545
4546    @Override
4547    public void crashApplication(int uid, int initialPid, String packageName,
4548            String message) {
4549        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4550                != PackageManager.PERMISSION_GRANTED) {
4551            String msg = "Permission Denial: crashApplication() from pid="
4552                    + Binder.getCallingPid()
4553                    + ", uid=" + Binder.getCallingUid()
4554                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4555            Slog.w(TAG, msg);
4556            throw new SecurityException(msg);
4557        }
4558
4559        synchronized(this) {
4560            ProcessRecord proc = null;
4561
4562            // Figure out which process to kill.  We don't trust that initialPid
4563            // still has any relation to current pids, so must scan through the
4564            // list.
4565            synchronized (mPidsSelfLocked) {
4566                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4567                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4568                    if (p.uid != uid) {
4569                        continue;
4570                    }
4571                    if (p.pid == initialPid) {
4572                        proc = p;
4573                        break;
4574                    }
4575                    if (p.pkgList.containsKey(packageName)) {
4576                        proc = p;
4577                    }
4578                }
4579            }
4580
4581            if (proc == null) {
4582                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4583                        + " initialPid=" + initialPid
4584                        + " packageName=" + packageName);
4585                return;
4586            }
4587
4588            if (proc.thread != null) {
4589                if (proc.pid == Process.myPid()) {
4590                    Log.w(TAG, "crashApplication: trying to crash self!");
4591                    return;
4592                }
4593                long ident = Binder.clearCallingIdentity();
4594                try {
4595                    proc.thread.scheduleCrash(message);
4596                } catch (RemoteException e) {
4597                }
4598                Binder.restoreCallingIdentity(ident);
4599            }
4600        }
4601    }
4602
4603    @Override
4604    public final void finishSubActivity(IBinder token, String resultWho,
4605            int requestCode) {
4606        synchronized(this) {
4607            final long origId = Binder.clearCallingIdentity();
4608            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4609            if (r != null) {
4610                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4611            }
4612            Binder.restoreCallingIdentity(origId);
4613        }
4614    }
4615
4616    @Override
4617    public boolean finishActivityAffinity(IBinder token) {
4618        synchronized(this) {
4619            final long origId = Binder.clearCallingIdentity();
4620            try {
4621                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4622
4623                ActivityRecord rootR = r.task.getRootActivity();
4624                // Do not allow task to finish in Lock Task mode.
4625                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4626                    if (rootR == r) {
4627                        mStackSupervisor.showLockTaskToast();
4628                        return false;
4629                    }
4630                }
4631                boolean res = false;
4632                if (r != null) {
4633                    res = r.task.stack.finishActivityAffinityLocked(r);
4634                }
4635                return res;
4636            } finally {
4637                Binder.restoreCallingIdentity(origId);
4638            }
4639        }
4640    }
4641
4642    @Override
4643    public void finishVoiceTask(IVoiceInteractionSession session) {
4644        synchronized(this) {
4645            final long origId = Binder.clearCallingIdentity();
4646            try {
4647                mStackSupervisor.finishVoiceTask(session);
4648            } finally {
4649                Binder.restoreCallingIdentity(origId);
4650            }
4651        }
4652
4653    }
4654
4655    @Override
4656    public boolean releaseActivityInstance(IBinder token) {
4657        synchronized(this) {
4658            final long origId = Binder.clearCallingIdentity();
4659            try {
4660                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4661                if (r.task == null || r.task.stack == null) {
4662                    return false;
4663                }
4664                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4665            } finally {
4666                Binder.restoreCallingIdentity(origId);
4667            }
4668        }
4669    }
4670
4671    @Override
4672    public void releaseSomeActivities(IApplicationThread appInt) {
4673        synchronized(this) {
4674            final long origId = Binder.clearCallingIdentity();
4675            try {
4676                ProcessRecord app = getRecordForAppLocked(appInt);
4677                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4678            } finally {
4679                Binder.restoreCallingIdentity(origId);
4680            }
4681        }
4682    }
4683
4684    @Override
4685    public boolean willActivityBeVisible(IBinder token) {
4686        synchronized(this) {
4687            ActivityStack stack = ActivityRecord.getStackLocked(token);
4688            if (stack != null) {
4689                return stack.willActivityBeVisibleLocked(token);
4690            }
4691            return false;
4692        }
4693    }
4694
4695    @Override
4696    public void overridePendingTransition(IBinder token, String packageName,
4697            int enterAnim, int exitAnim) {
4698        synchronized(this) {
4699            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4700            if (self == null) {
4701                return;
4702            }
4703
4704            final long origId = Binder.clearCallingIdentity();
4705
4706            if (self.state == ActivityState.RESUMED
4707                    || self.state == ActivityState.PAUSING) {
4708                mWindowManager.overridePendingAppTransition(packageName,
4709                        enterAnim, exitAnim, null);
4710            }
4711
4712            Binder.restoreCallingIdentity(origId);
4713        }
4714    }
4715
4716    /**
4717     * Main function for removing an existing process from the activity manager
4718     * as a result of that process going away.  Clears out all connections
4719     * to the process.
4720     */
4721    private final void handleAppDiedLocked(ProcessRecord app,
4722            boolean restarting, boolean allowRestart) {
4723        int pid = app.pid;
4724        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4725        if (!kept && !restarting) {
4726            removeLruProcessLocked(app);
4727            if (pid > 0) {
4728                ProcessList.remove(pid);
4729            }
4730        }
4731
4732        if (mProfileProc == app) {
4733            clearProfilerLocked();
4734        }
4735
4736        // Remove this application's activities from active lists.
4737        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4738
4739        app.activities.clear();
4740
4741        if (app.instrumentationClass != null) {
4742            Slog.w(TAG, "Crash of app " + app.processName
4743                  + " running instrumentation " + app.instrumentationClass);
4744            Bundle info = new Bundle();
4745            info.putString("shortMsg", "Process crashed.");
4746            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4747        }
4748
4749        if (!restarting) {
4750            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4751                // If there was nothing to resume, and we are not already
4752                // restarting this process, but there is a visible activity that
4753                // is hosted by the process...  then make sure all visible
4754                // activities are running, taking care of restarting this
4755                // process.
4756                if (hasVisibleActivities) {
4757                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4758                }
4759            }
4760        }
4761    }
4762
4763    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4764        IBinder threadBinder = thread.asBinder();
4765        // Find the application record.
4766        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4767            ProcessRecord rec = mLruProcesses.get(i);
4768            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4769                return i;
4770            }
4771        }
4772        return -1;
4773    }
4774
4775    final ProcessRecord getRecordForAppLocked(
4776            IApplicationThread thread) {
4777        if (thread == null) {
4778            return null;
4779        }
4780
4781        int appIndex = getLRURecordIndexForAppLocked(thread);
4782        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4783    }
4784
4785    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4786        // If there are no longer any background processes running,
4787        // and the app that died was not running instrumentation,
4788        // then tell everyone we are now low on memory.
4789        boolean haveBg = false;
4790        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4791            ProcessRecord rec = mLruProcesses.get(i);
4792            if (rec.thread != null
4793                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4794                haveBg = true;
4795                break;
4796            }
4797        }
4798
4799        if (!haveBg) {
4800            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4801            if (doReport) {
4802                long now = SystemClock.uptimeMillis();
4803                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4804                    doReport = false;
4805                } else {
4806                    mLastMemUsageReportTime = now;
4807                }
4808            }
4809            final ArrayList<ProcessMemInfo> memInfos
4810                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4811            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4812            long now = SystemClock.uptimeMillis();
4813            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4814                ProcessRecord rec = mLruProcesses.get(i);
4815                if (rec == dyingProc || rec.thread == null) {
4816                    continue;
4817                }
4818                if (doReport) {
4819                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4820                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4821                }
4822                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4823                    // The low memory report is overriding any current
4824                    // state for a GC request.  Make sure to do
4825                    // heavy/important/visible/foreground processes first.
4826                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4827                        rec.lastRequestedGc = 0;
4828                    } else {
4829                        rec.lastRequestedGc = rec.lastLowMemory;
4830                    }
4831                    rec.reportLowMemory = true;
4832                    rec.lastLowMemory = now;
4833                    mProcessesToGc.remove(rec);
4834                    addProcessToGcListLocked(rec);
4835                }
4836            }
4837            if (doReport) {
4838                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4839                mHandler.sendMessage(msg);
4840            }
4841            scheduleAppGcsLocked();
4842        }
4843    }
4844
4845    final void appDiedLocked(ProcessRecord app) {
4846       appDiedLocked(app, app.pid, app.thread);
4847    }
4848
4849    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4850        // First check if this ProcessRecord is actually active for the pid.
4851        synchronized (mPidsSelfLocked) {
4852            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4853            if (curProc != app) {
4854                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4855                return;
4856            }
4857        }
4858
4859        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4860        synchronized (stats) {
4861            stats.noteProcessDiedLocked(app.info.uid, pid);
4862        }
4863
4864        Process.killProcessQuiet(pid);
4865        Process.killProcessGroup(app.info.uid, pid);
4866        app.killed = true;
4867
4868        // Clean up already done if the process has been re-started.
4869        if (app.pid == pid && app.thread != null &&
4870                app.thread.asBinder() == thread.asBinder()) {
4871            boolean doLowMem = app.instrumentationClass == null;
4872            boolean doOomAdj = doLowMem;
4873            if (!app.killedByAm) {
4874                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4875                        + ") has died");
4876                mAllowLowerMemLevel = true;
4877            } else {
4878                // Note that we always want to do oom adj to update our state with the
4879                // new number of procs.
4880                mAllowLowerMemLevel = false;
4881                doLowMem = false;
4882            }
4883            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4884            if (DEBUG_CLEANUP) Slog.v(
4885                TAG, "Dying app: " + app + ", pid: " + pid
4886                + ", thread: " + thread.asBinder());
4887            handleAppDiedLocked(app, false, true);
4888
4889            if (doOomAdj) {
4890                updateOomAdjLocked();
4891            }
4892            if (doLowMem) {
4893                doLowMemReportIfNeededLocked(app);
4894            }
4895        } else if (app.pid != pid) {
4896            // A new process has already been started.
4897            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4898                    + ") has died and restarted (pid " + app.pid + ").");
4899            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4900        } else if (DEBUG_PROCESSES) {
4901            Slog.d(TAG, "Received spurious death notification for thread "
4902                    + thread.asBinder());
4903        }
4904    }
4905
4906    /**
4907     * If a stack trace dump file is configured, dump process stack traces.
4908     * @param clearTraces causes the dump file to be erased prior to the new
4909     *    traces being written, if true; when false, the new traces will be
4910     *    appended to any existing file content.
4911     * @param firstPids of dalvik VM processes to dump stack traces for first
4912     * @param lastPids of dalvik VM processes to dump stack traces for last
4913     * @param nativeProcs optional list of native process names to dump stack crawls
4914     * @return file containing stack traces, or null if no dump file is configured
4915     */
4916    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4917            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4918        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4919        if (tracesPath == null || tracesPath.length() == 0) {
4920            return null;
4921        }
4922
4923        File tracesFile = new File(tracesPath);
4924        try {
4925            File tracesDir = tracesFile.getParentFile();
4926            if (!tracesDir.exists()) {
4927                tracesDir.mkdirs();
4928                if (!SELinux.restorecon(tracesDir)) {
4929                    return null;
4930                }
4931            }
4932            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4933
4934            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4935            tracesFile.createNewFile();
4936            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4937        } catch (IOException e) {
4938            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4939            return null;
4940        }
4941
4942        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4943        return tracesFile;
4944    }
4945
4946    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4947            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4948        // Use a FileObserver to detect when traces finish writing.
4949        // The order of traces is considered important to maintain for legibility.
4950        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4951            @Override
4952            public synchronized void onEvent(int event, String path) { notify(); }
4953        };
4954
4955        try {
4956            observer.startWatching();
4957
4958            // First collect all of the stacks of the most important pids.
4959            if (firstPids != null) {
4960                try {
4961                    int num = firstPids.size();
4962                    for (int i = 0; i < num; i++) {
4963                        synchronized (observer) {
4964                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4965                            observer.wait(200);  // Wait for write-close, give up after 200msec
4966                        }
4967                    }
4968                } catch (InterruptedException e) {
4969                    Slog.wtf(TAG, e);
4970                }
4971            }
4972
4973            // Next collect the stacks of the native pids
4974            if (nativeProcs != null) {
4975                int[] pids = Process.getPidsForCommands(nativeProcs);
4976                if (pids != null) {
4977                    for (int pid : pids) {
4978                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4979                    }
4980                }
4981            }
4982
4983            // Lastly, measure CPU usage.
4984            if (processCpuTracker != null) {
4985                processCpuTracker.init();
4986                System.gc();
4987                processCpuTracker.update();
4988                try {
4989                    synchronized (processCpuTracker) {
4990                        processCpuTracker.wait(500); // measure over 1/2 second.
4991                    }
4992                } catch (InterruptedException e) {
4993                }
4994                processCpuTracker.update();
4995
4996                // We'll take the stack crawls of just the top apps using CPU.
4997                final int N = processCpuTracker.countWorkingStats();
4998                int numProcs = 0;
4999                for (int i=0; i<N && numProcs<5; i++) {
5000                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5001                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5002                        numProcs++;
5003                        try {
5004                            synchronized (observer) {
5005                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5006                                observer.wait(200);  // Wait for write-close, give up after 200msec
5007                            }
5008                        } catch (InterruptedException e) {
5009                            Slog.wtf(TAG, e);
5010                        }
5011
5012                    }
5013                }
5014            }
5015        } finally {
5016            observer.stopWatching();
5017        }
5018    }
5019
5020    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5021        if (true || IS_USER_BUILD) {
5022            return;
5023        }
5024        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5025        if (tracesPath == null || tracesPath.length() == 0) {
5026            return;
5027        }
5028
5029        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5030        StrictMode.allowThreadDiskWrites();
5031        try {
5032            final File tracesFile = new File(tracesPath);
5033            final File tracesDir = tracesFile.getParentFile();
5034            final File tracesTmp = new File(tracesDir, "__tmp__");
5035            try {
5036                if (!tracesDir.exists()) {
5037                    tracesDir.mkdirs();
5038                    if (!SELinux.restorecon(tracesDir.getPath())) {
5039                        return;
5040                    }
5041                }
5042                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
5043
5044                if (tracesFile.exists()) {
5045                    tracesTmp.delete();
5046                    tracesFile.renameTo(tracesTmp);
5047                }
5048                StringBuilder sb = new StringBuilder();
5049                Time tobj = new Time();
5050                tobj.set(System.currentTimeMillis());
5051                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5052                sb.append(": ");
5053                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5054                sb.append(" since ");
5055                sb.append(msg);
5056                FileOutputStream fos = new FileOutputStream(tracesFile);
5057                fos.write(sb.toString().getBytes());
5058                if (app == null) {
5059                    fos.write("\n*** No application process!".getBytes());
5060                }
5061                fos.close();
5062                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5063            } catch (IOException e) {
5064                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5065                return;
5066            }
5067
5068            if (app != null) {
5069                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5070                firstPids.add(app.pid);
5071                dumpStackTraces(tracesPath, firstPids, null, null, null);
5072            }
5073
5074            File lastTracesFile = null;
5075            File curTracesFile = null;
5076            for (int i=9; i>=0; i--) {
5077                String name = String.format(Locale.US, "slow%02d.txt", i);
5078                curTracesFile = new File(tracesDir, name);
5079                if (curTracesFile.exists()) {
5080                    if (lastTracesFile != null) {
5081                        curTracesFile.renameTo(lastTracesFile);
5082                    } else {
5083                        curTracesFile.delete();
5084                    }
5085                }
5086                lastTracesFile = curTracesFile;
5087            }
5088            tracesFile.renameTo(curTracesFile);
5089            if (tracesTmp.exists()) {
5090                tracesTmp.renameTo(tracesFile);
5091            }
5092        } finally {
5093            StrictMode.setThreadPolicy(oldPolicy);
5094        }
5095    }
5096
5097    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
5098            ActivityRecord parent, boolean aboveSystem, final String annotation) {
5099        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
5100        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
5101
5102        if (mController != null) {
5103            try {
5104                // 0 == continue, -1 = kill process immediately
5105                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
5106                if (res < 0 && app.pid != MY_PID) {
5107                    app.kill("anr", true);
5108                }
5109            } catch (RemoteException e) {
5110                mController = null;
5111                Watchdog.getInstance().setActivityController(null);
5112            }
5113        }
5114
5115        long anrTime = SystemClock.uptimeMillis();
5116        if (MONITOR_CPU_USAGE) {
5117            updateCpuStatsNow();
5118        }
5119
5120        synchronized (this) {
5121            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5122            if (mShuttingDown) {
5123                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5124                return;
5125            } else if (app.notResponding) {
5126                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5127                return;
5128            } else if (app.crashing) {
5129                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5130                return;
5131            }
5132
5133            // In case we come through here for the same app before completing
5134            // this one, mark as anring now so we will bail out.
5135            app.notResponding = true;
5136
5137            // Log the ANR to the event log.
5138            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5139                    app.processName, app.info.flags, annotation);
5140
5141            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5142            firstPids.add(app.pid);
5143
5144            int parentPid = app.pid;
5145            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5146            if (parentPid != app.pid) firstPids.add(parentPid);
5147
5148            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5149
5150            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5151                ProcessRecord r = mLruProcesses.get(i);
5152                if (r != null && r.thread != null) {
5153                    int pid = r.pid;
5154                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5155                        if (r.persistent) {
5156                            firstPids.add(pid);
5157                        } else {
5158                            lastPids.put(pid, Boolean.TRUE);
5159                        }
5160                    }
5161                }
5162            }
5163        }
5164
5165        // Log the ANR to the main log.
5166        StringBuilder info = new StringBuilder();
5167        info.setLength(0);
5168        info.append("ANR in ").append(app.processName);
5169        if (activity != null && activity.shortComponentName != null) {
5170            info.append(" (").append(activity.shortComponentName).append(")");
5171        }
5172        info.append("\n");
5173        info.append("PID: ").append(app.pid).append("\n");
5174        if (annotation != null) {
5175            info.append("Reason: ").append(annotation).append("\n");
5176        }
5177        if (parent != null && parent != activity) {
5178            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5179        }
5180
5181        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5182
5183        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5184                NATIVE_STACKS_OF_INTEREST);
5185
5186        String cpuInfo = null;
5187        if (MONITOR_CPU_USAGE) {
5188            updateCpuStatsNow();
5189            synchronized (mProcessCpuTracker) {
5190                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5191            }
5192            info.append(processCpuTracker.printCurrentLoad());
5193            info.append(cpuInfo);
5194        }
5195
5196        info.append(processCpuTracker.printCurrentState(anrTime));
5197
5198        Slog.e(TAG, info.toString());
5199        if (tracesFile == null) {
5200            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5201            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5202        }
5203
5204        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5205                cpuInfo, tracesFile, null);
5206
5207        if (mController != null) {
5208            try {
5209                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5210                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5211                if (res != 0) {
5212                    if (res < 0 && app.pid != MY_PID) {
5213                        app.kill("anr", true);
5214                    } else {
5215                        synchronized (this) {
5216                            mServices.scheduleServiceTimeoutLocked(app);
5217                        }
5218                    }
5219                    return;
5220                }
5221            } catch (RemoteException e) {
5222                mController = null;
5223                Watchdog.getInstance().setActivityController(null);
5224            }
5225        }
5226
5227        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5228        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5229                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5230
5231        synchronized (this) {
5232            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5233                app.kill("bg anr", true);
5234                return;
5235            }
5236
5237            // Set the app's notResponding state, and look up the errorReportReceiver
5238            makeAppNotRespondingLocked(app,
5239                    activity != null ? activity.shortComponentName : null,
5240                    annotation != null ? "ANR " + annotation : "ANR",
5241                    info.toString());
5242
5243            // Bring up the infamous App Not Responding dialog
5244            Message msg = Message.obtain();
5245            HashMap<String, Object> map = new HashMap<String, Object>();
5246            msg.what = SHOW_NOT_RESPONDING_MSG;
5247            msg.obj = map;
5248            msg.arg1 = aboveSystem ? 1 : 0;
5249            map.put("app", app);
5250            if (activity != null) {
5251                map.put("activity", activity);
5252            }
5253
5254            mHandler.sendMessage(msg);
5255        }
5256    }
5257
5258    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5259        if (!mLaunchWarningShown) {
5260            mLaunchWarningShown = true;
5261            mHandler.post(new Runnable() {
5262                @Override
5263                public void run() {
5264                    synchronized (ActivityManagerService.this) {
5265                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5266                        d.show();
5267                        mHandler.postDelayed(new Runnable() {
5268                            @Override
5269                            public void run() {
5270                                synchronized (ActivityManagerService.this) {
5271                                    d.dismiss();
5272                                    mLaunchWarningShown = false;
5273                                }
5274                            }
5275                        }, 4000);
5276                    }
5277                }
5278            });
5279        }
5280    }
5281
5282    @Override
5283    public boolean clearApplicationUserData(final String packageName,
5284            final IPackageDataObserver observer, int userId) {
5285        enforceNotIsolatedCaller("clearApplicationUserData");
5286        int uid = Binder.getCallingUid();
5287        int pid = Binder.getCallingPid();
5288        userId = handleIncomingUser(pid, uid,
5289                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5290        long callingId = Binder.clearCallingIdentity();
5291        try {
5292            IPackageManager pm = AppGlobals.getPackageManager();
5293            int pkgUid = -1;
5294            synchronized(this) {
5295                try {
5296                    pkgUid = pm.getPackageUid(packageName, userId);
5297                } catch (RemoteException e) {
5298                }
5299                if (pkgUid == -1) {
5300                    Slog.w(TAG, "Invalid packageName: " + packageName);
5301                    if (observer != null) {
5302                        try {
5303                            observer.onRemoveCompleted(packageName, false);
5304                        } catch (RemoteException e) {
5305                            Slog.i(TAG, "Observer no longer exists.");
5306                        }
5307                    }
5308                    return false;
5309                }
5310                if (uid == pkgUid || checkComponentPermission(
5311                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5312                        pid, uid, -1, true)
5313                        == PackageManager.PERMISSION_GRANTED) {
5314                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5315                } else {
5316                    throw new SecurityException("PID " + pid + " does not have permission "
5317                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5318                                    + " of package " + packageName);
5319                }
5320
5321                // Remove all tasks match the cleared application package and user
5322                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5323                    final TaskRecord tr = mRecentTasks.get(i);
5324                    final String taskPackageName =
5325                            tr.getBaseIntent().getComponent().getPackageName();
5326                    if (tr.userId != userId) continue;
5327                    if (!taskPackageName.equals(packageName)) continue;
5328                    removeTaskByIdLocked(tr.taskId, 0);
5329                }
5330            }
5331
5332            try {
5333                // Clear application user data
5334                pm.clearApplicationUserData(packageName, observer, userId);
5335
5336                synchronized(this) {
5337                    // Remove all permissions granted from/to this package
5338                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5339                }
5340
5341                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5342                        Uri.fromParts("package", packageName, null));
5343                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5344                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5345                        null, null, 0, null, null, null, false, false, userId);
5346            } catch (RemoteException e) {
5347            }
5348        } finally {
5349            Binder.restoreCallingIdentity(callingId);
5350        }
5351        return true;
5352    }
5353
5354    @Override
5355    public void killBackgroundProcesses(final String packageName, int userId) {
5356        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5357                != PackageManager.PERMISSION_GRANTED &&
5358                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5359                        != PackageManager.PERMISSION_GRANTED) {
5360            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5361                    + Binder.getCallingPid()
5362                    + ", uid=" + Binder.getCallingUid()
5363                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5364            Slog.w(TAG, msg);
5365            throw new SecurityException(msg);
5366        }
5367
5368        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5369                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5370        long callingId = Binder.clearCallingIdentity();
5371        try {
5372            IPackageManager pm = AppGlobals.getPackageManager();
5373            synchronized(this) {
5374                int appId = -1;
5375                try {
5376                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5377                } catch (RemoteException e) {
5378                }
5379                if (appId == -1) {
5380                    Slog.w(TAG, "Invalid packageName: " + packageName);
5381                    return;
5382                }
5383                killPackageProcessesLocked(packageName, appId, userId,
5384                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5385            }
5386        } finally {
5387            Binder.restoreCallingIdentity(callingId);
5388        }
5389    }
5390
5391    @Override
5392    public void killAllBackgroundProcesses() {
5393        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5394                != PackageManager.PERMISSION_GRANTED) {
5395            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5396                    + Binder.getCallingPid()
5397                    + ", uid=" + Binder.getCallingUid()
5398                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5399            Slog.w(TAG, msg);
5400            throw new SecurityException(msg);
5401        }
5402
5403        long callingId = Binder.clearCallingIdentity();
5404        try {
5405            synchronized(this) {
5406                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5407                final int NP = mProcessNames.getMap().size();
5408                for (int ip=0; ip<NP; ip++) {
5409                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5410                    final int NA = apps.size();
5411                    for (int ia=0; ia<NA; ia++) {
5412                        ProcessRecord app = apps.valueAt(ia);
5413                        if (app.persistent) {
5414                            // we don't kill persistent processes
5415                            continue;
5416                        }
5417                        if (app.removed) {
5418                            procs.add(app);
5419                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5420                            app.removed = true;
5421                            procs.add(app);
5422                        }
5423                    }
5424                }
5425
5426                int N = procs.size();
5427                for (int i=0; i<N; i++) {
5428                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5429                }
5430                mAllowLowerMemLevel = true;
5431                updateOomAdjLocked();
5432                doLowMemReportIfNeededLocked(null);
5433            }
5434        } finally {
5435            Binder.restoreCallingIdentity(callingId);
5436        }
5437    }
5438
5439    @Override
5440    public void forceStopPackage(final String packageName, int userId) {
5441        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5442                != PackageManager.PERMISSION_GRANTED) {
5443            String msg = "Permission Denial: forceStopPackage() from pid="
5444                    + Binder.getCallingPid()
5445                    + ", uid=" + Binder.getCallingUid()
5446                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5447            Slog.w(TAG, msg);
5448            throw new SecurityException(msg);
5449        }
5450        final int callingPid = Binder.getCallingPid();
5451        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5452                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5453        long callingId = Binder.clearCallingIdentity();
5454        try {
5455            IPackageManager pm = AppGlobals.getPackageManager();
5456            synchronized(this) {
5457                int[] users = userId == UserHandle.USER_ALL
5458                        ? getUsersLocked() : new int[] { userId };
5459                for (int user : users) {
5460                    int pkgUid = -1;
5461                    try {
5462                        pkgUid = pm.getPackageUid(packageName, user);
5463                    } catch (RemoteException e) {
5464                    }
5465                    if (pkgUid == -1) {
5466                        Slog.w(TAG, "Invalid packageName: " + packageName);
5467                        continue;
5468                    }
5469                    try {
5470                        pm.setPackageStoppedState(packageName, true, user);
5471                    } catch (RemoteException e) {
5472                    } catch (IllegalArgumentException e) {
5473                        Slog.w(TAG, "Failed trying to unstop package "
5474                                + packageName + ": " + e);
5475                    }
5476                    if (isUserRunningLocked(user, false)) {
5477                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5478                    }
5479                }
5480            }
5481        } finally {
5482            Binder.restoreCallingIdentity(callingId);
5483        }
5484    }
5485
5486    @Override
5487    public void addPackageDependency(String packageName) {
5488        synchronized (this) {
5489            int callingPid = Binder.getCallingPid();
5490            if (callingPid == Process.myPid()) {
5491                //  Yeah, um, no.
5492                Slog.w(TAG, "Can't addPackageDependency on system process");
5493                return;
5494            }
5495            ProcessRecord proc;
5496            synchronized (mPidsSelfLocked) {
5497                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5498            }
5499            if (proc != null) {
5500                if (proc.pkgDeps == null) {
5501                    proc.pkgDeps = new ArraySet<String>(1);
5502                }
5503                proc.pkgDeps.add(packageName);
5504            }
5505        }
5506    }
5507
5508    /*
5509     * The pkg name and app id have to be specified.
5510     */
5511    @Override
5512    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5513        if (pkg == null) {
5514            return;
5515        }
5516        // Make sure the uid is valid.
5517        if (appid < 0) {
5518            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5519            return;
5520        }
5521        int callerUid = Binder.getCallingUid();
5522        // Only the system server can kill an application
5523        if (callerUid == Process.SYSTEM_UID) {
5524            // Post an aysnc message to kill the application
5525            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5526            msg.arg1 = appid;
5527            msg.arg2 = 0;
5528            Bundle bundle = new Bundle();
5529            bundle.putString("pkg", pkg);
5530            bundle.putString("reason", reason);
5531            msg.obj = bundle;
5532            mHandler.sendMessage(msg);
5533        } else {
5534            throw new SecurityException(callerUid + " cannot kill pkg: " +
5535                    pkg);
5536        }
5537    }
5538
5539    @Override
5540    public void closeSystemDialogs(String reason) {
5541        enforceNotIsolatedCaller("closeSystemDialogs");
5542
5543        final int pid = Binder.getCallingPid();
5544        final int uid = Binder.getCallingUid();
5545        final long origId = Binder.clearCallingIdentity();
5546        try {
5547            synchronized (this) {
5548                // Only allow this from foreground processes, so that background
5549                // applications can't abuse it to prevent system UI from being shown.
5550                if (uid >= Process.FIRST_APPLICATION_UID) {
5551                    ProcessRecord proc;
5552                    synchronized (mPidsSelfLocked) {
5553                        proc = mPidsSelfLocked.get(pid);
5554                    }
5555                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5556                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5557                                + " from background process " + proc);
5558                        return;
5559                    }
5560                }
5561                closeSystemDialogsLocked(reason);
5562            }
5563        } finally {
5564            Binder.restoreCallingIdentity(origId);
5565        }
5566    }
5567
5568    void closeSystemDialogsLocked(String reason) {
5569        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5570        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5571                | Intent.FLAG_RECEIVER_FOREGROUND);
5572        if (reason != null) {
5573            intent.putExtra("reason", reason);
5574        }
5575        mWindowManager.closeSystemDialogs(reason);
5576
5577        mStackSupervisor.closeSystemDialogsLocked();
5578
5579        broadcastIntentLocked(null, null, intent, null,
5580                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5581                Process.SYSTEM_UID, UserHandle.USER_ALL);
5582    }
5583
5584    @Override
5585    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5586        enforceNotIsolatedCaller("getProcessMemoryInfo");
5587        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5588        for (int i=pids.length-1; i>=0; i--) {
5589            ProcessRecord proc;
5590            int oomAdj;
5591            synchronized (this) {
5592                synchronized (mPidsSelfLocked) {
5593                    proc = mPidsSelfLocked.get(pids[i]);
5594                    oomAdj = proc != null ? proc.setAdj : 0;
5595                }
5596            }
5597            infos[i] = new Debug.MemoryInfo();
5598            Debug.getMemoryInfo(pids[i], infos[i]);
5599            if (proc != null) {
5600                synchronized (this) {
5601                    if (proc.thread != null && proc.setAdj == oomAdj) {
5602                        // Record this for posterity if the process has been stable.
5603                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5604                                infos[i].getTotalUss(), false, proc.pkgList);
5605                    }
5606                }
5607            }
5608        }
5609        return infos;
5610    }
5611
5612    @Override
5613    public long[] getProcessPss(int[] pids) {
5614        enforceNotIsolatedCaller("getProcessPss");
5615        long[] pss = new long[pids.length];
5616        for (int i=pids.length-1; i>=0; i--) {
5617            ProcessRecord proc;
5618            int oomAdj;
5619            synchronized (this) {
5620                synchronized (mPidsSelfLocked) {
5621                    proc = mPidsSelfLocked.get(pids[i]);
5622                    oomAdj = proc != null ? proc.setAdj : 0;
5623                }
5624            }
5625            long[] tmpUss = new long[1];
5626            pss[i] = Debug.getPss(pids[i], tmpUss);
5627            if (proc != null) {
5628                synchronized (this) {
5629                    if (proc.thread != null && proc.setAdj == oomAdj) {
5630                        // Record this for posterity if the process has been stable.
5631                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5632                    }
5633                }
5634            }
5635        }
5636        return pss;
5637    }
5638
5639    @Override
5640    public void killApplicationProcess(String processName, int uid) {
5641        if (processName == null) {
5642            return;
5643        }
5644
5645        int callerUid = Binder.getCallingUid();
5646        // Only the system server can kill an application
5647        if (callerUid == Process.SYSTEM_UID) {
5648            synchronized (this) {
5649                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5650                if (app != null && app.thread != null) {
5651                    try {
5652                        app.thread.scheduleSuicide();
5653                    } catch (RemoteException e) {
5654                        // If the other end already died, then our work here is done.
5655                    }
5656                } else {
5657                    Slog.w(TAG, "Process/uid not found attempting kill of "
5658                            + processName + " / " + uid);
5659                }
5660            }
5661        } else {
5662            throw new SecurityException(callerUid + " cannot kill app process: " +
5663                    processName);
5664        }
5665    }
5666
5667    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5668        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5669                false, true, false, false, UserHandle.getUserId(uid), reason);
5670        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5671                Uri.fromParts("package", packageName, null));
5672        if (!mProcessesReady) {
5673            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5674                    | Intent.FLAG_RECEIVER_FOREGROUND);
5675        }
5676        intent.putExtra(Intent.EXTRA_UID, uid);
5677        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5678        broadcastIntentLocked(null, null, intent,
5679                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5680                false, false,
5681                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5682    }
5683
5684    private void forceStopUserLocked(int userId, String reason) {
5685        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5686        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5687        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5688                | Intent.FLAG_RECEIVER_FOREGROUND);
5689        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5690        broadcastIntentLocked(null, null, intent,
5691                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5692                false, false,
5693                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5694    }
5695
5696    private final boolean killPackageProcessesLocked(String packageName, int appId,
5697            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5698            boolean doit, boolean evenPersistent, String reason) {
5699        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5700
5701        // Remove all processes this package may have touched: all with the
5702        // same UID (except for the system or root user), and all whose name
5703        // matches the package name.
5704        final int NP = mProcessNames.getMap().size();
5705        for (int ip=0; ip<NP; ip++) {
5706            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5707            final int NA = apps.size();
5708            for (int ia=0; ia<NA; ia++) {
5709                ProcessRecord app = apps.valueAt(ia);
5710                if (app.persistent && !evenPersistent) {
5711                    // we don't kill persistent processes
5712                    continue;
5713                }
5714                if (app.removed) {
5715                    if (doit) {
5716                        procs.add(app);
5717                    }
5718                    continue;
5719                }
5720
5721                // Skip process if it doesn't meet our oom adj requirement.
5722                if (app.setAdj < minOomAdj) {
5723                    continue;
5724                }
5725
5726                // If no package is specified, we call all processes under the
5727                // give user id.
5728                if (packageName == null) {
5729                    if (app.userId != userId) {
5730                        continue;
5731                    }
5732                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5733                        continue;
5734                    }
5735                // Package has been specified, we want to hit all processes
5736                // that match it.  We need to qualify this by the processes
5737                // that are running under the specified app and user ID.
5738                } else {
5739                    final boolean isDep = app.pkgDeps != null
5740                            && app.pkgDeps.contains(packageName);
5741                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5742                        continue;
5743                    }
5744                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5745                        continue;
5746                    }
5747                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5748                        continue;
5749                    }
5750                }
5751
5752                // Process has passed all conditions, kill it!
5753                if (!doit) {
5754                    return true;
5755                }
5756                app.removed = true;
5757                procs.add(app);
5758            }
5759        }
5760
5761        int N = procs.size();
5762        for (int i=0; i<N; i++) {
5763            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5764        }
5765        updateOomAdjLocked();
5766        return N > 0;
5767    }
5768
5769    private final boolean forceStopPackageLocked(String name, int appId,
5770            boolean callerWillRestart, boolean purgeCache, boolean doit,
5771            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5772        int i;
5773        int N;
5774
5775        if (userId == UserHandle.USER_ALL && name == null) {
5776            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5777        }
5778
5779        if (appId < 0 && name != null) {
5780            try {
5781                appId = UserHandle.getAppId(
5782                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5783            } catch (RemoteException e) {
5784            }
5785        }
5786
5787        if (doit) {
5788            if (name != null) {
5789                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5790                        + " user=" + userId + ": " + reason);
5791            } else {
5792                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5793            }
5794
5795            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5796            for (int ip=pmap.size()-1; ip>=0; ip--) {
5797                SparseArray<Long> ba = pmap.valueAt(ip);
5798                for (i=ba.size()-1; i>=0; i--) {
5799                    boolean remove = false;
5800                    final int entUid = ba.keyAt(i);
5801                    if (name != null) {
5802                        if (userId == UserHandle.USER_ALL) {
5803                            if (UserHandle.getAppId(entUid) == appId) {
5804                                remove = true;
5805                            }
5806                        } else {
5807                            if (entUid == UserHandle.getUid(userId, appId)) {
5808                                remove = true;
5809                            }
5810                        }
5811                    } else if (UserHandle.getUserId(entUid) == userId) {
5812                        remove = true;
5813                    }
5814                    if (remove) {
5815                        ba.removeAt(i);
5816                    }
5817                }
5818                if (ba.size() == 0) {
5819                    pmap.removeAt(ip);
5820                }
5821            }
5822        }
5823
5824        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5825                -100, callerWillRestart, true, doit, evenPersistent,
5826                name == null ? ("stop user " + userId) : ("stop " + name));
5827
5828        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5829            if (!doit) {
5830                return true;
5831            }
5832            didSomething = true;
5833        }
5834
5835        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5836            if (!doit) {
5837                return true;
5838            }
5839            didSomething = true;
5840        }
5841
5842        if (name == null) {
5843            // Remove all sticky broadcasts from this user.
5844            mStickyBroadcasts.remove(userId);
5845        }
5846
5847        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5848        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5849                userId, providers)) {
5850            if (!doit) {
5851                return true;
5852            }
5853            didSomething = true;
5854        }
5855        N = providers.size();
5856        for (i=0; i<N; i++) {
5857            removeDyingProviderLocked(null, providers.get(i), true);
5858        }
5859
5860        // Remove transient permissions granted from/to this package/user
5861        removeUriPermissionsForPackageLocked(name, userId, false);
5862
5863        if (name == null || uninstalling) {
5864            // Remove pending intents.  For now we only do this when force
5865            // stopping users, because we have some problems when doing this
5866            // for packages -- app widgets are not currently cleaned up for
5867            // such packages, so they can be left with bad pending intents.
5868            if (mIntentSenderRecords.size() > 0) {
5869                Iterator<WeakReference<PendingIntentRecord>> it
5870                        = mIntentSenderRecords.values().iterator();
5871                while (it.hasNext()) {
5872                    WeakReference<PendingIntentRecord> wpir = it.next();
5873                    if (wpir == null) {
5874                        it.remove();
5875                        continue;
5876                    }
5877                    PendingIntentRecord pir = wpir.get();
5878                    if (pir == null) {
5879                        it.remove();
5880                        continue;
5881                    }
5882                    if (name == null) {
5883                        // Stopping user, remove all objects for the user.
5884                        if (pir.key.userId != userId) {
5885                            // Not the same user, skip it.
5886                            continue;
5887                        }
5888                    } else {
5889                        if (UserHandle.getAppId(pir.uid) != appId) {
5890                            // Different app id, skip it.
5891                            continue;
5892                        }
5893                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5894                            // Different user, skip it.
5895                            continue;
5896                        }
5897                        if (!pir.key.packageName.equals(name)) {
5898                            // Different package, skip it.
5899                            continue;
5900                        }
5901                    }
5902                    if (!doit) {
5903                        return true;
5904                    }
5905                    didSomething = true;
5906                    it.remove();
5907                    pir.canceled = true;
5908                    if (pir.key.activity != null) {
5909                        pir.key.activity.pendingResults.remove(pir.ref);
5910                    }
5911                }
5912            }
5913        }
5914
5915        if (doit) {
5916            if (purgeCache && name != null) {
5917                AttributeCache ac = AttributeCache.instance();
5918                if (ac != null) {
5919                    ac.removePackage(name);
5920                }
5921            }
5922            if (mBooted) {
5923                mStackSupervisor.resumeTopActivitiesLocked();
5924                mStackSupervisor.scheduleIdleLocked();
5925            }
5926        }
5927
5928        return didSomething;
5929    }
5930
5931    private final boolean removeProcessLocked(ProcessRecord app,
5932            boolean callerWillRestart, boolean allowRestart, String reason) {
5933        final String name = app.processName;
5934        final int uid = app.uid;
5935        if (DEBUG_PROCESSES) Slog.d(
5936            TAG, "Force removing proc " + app.toShortString() + " (" + name
5937            + "/" + uid + ")");
5938
5939        mProcessNames.remove(name, uid);
5940        mIsolatedProcesses.remove(app.uid);
5941        if (mHeavyWeightProcess == app) {
5942            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5943                    mHeavyWeightProcess.userId, 0));
5944            mHeavyWeightProcess = null;
5945        }
5946        boolean needRestart = false;
5947        if (app.pid > 0 && app.pid != MY_PID) {
5948            int pid = app.pid;
5949            synchronized (mPidsSelfLocked) {
5950                mPidsSelfLocked.remove(pid);
5951                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5952            }
5953            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5954            if (app.isolated) {
5955                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5956            }
5957            app.kill(reason, true);
5958            handleAppDiedLocked(app, true, allowRestart);
5959            removeLruProcessLocked(app);
5960
5961            if (app.persistent && !app.isolated) {
5962                if (!callerWillRestart) {
5963                    addAppLocked(app.info, false, null /* ABI override */);
5964                } else {
5965                    needRestart = true;
5966                }
5967            }
5968        } else {
5969            mRemovedProcesses.add(app);
5970        }
5971
5972        return needRestart;
5973    }
5974
5975    private final void processStartTimedOutLocked(ProcessRecord app) {
5976        final int pid = app.pid;
5977        boolean gone = false;
5978        synchronized (mPidsSelfLocked) {
5979            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5980            if (knownApp != null && knownApp.thread == null) {
5981                mPidsSelfLocked.remove(pid);
5982                gone = true;
5983            }
5984        }
5985
5986        if (gone) {
5987            Slog.w(TAG, "Process " + app + " failed to attach");
5988            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5989                    pid, app.uid, app.processName);
5990            mProcessNames.remove(app.processName, app.uid);
5991            mIsolatedProcesses.remove(app.uid);
5992            if (mHeavyWeightProcess == app) {
5993                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5994                        mHeavyWeightProcess.userId, 0));
5995                mHeavyWeightProcess = null;
5996            }
5997            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5998            if (app.isolated) {
5999                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6000            }
6001            // Take care of any launching providers waiting for this process.
6002            checkAppInLaunchingProvidersLocked(app, true);
6003            // Take care of any services that are waiting for the process.
6004            mServices.processStartTimedOutLocked(app);
6005            app.kill("start timeout", true);
6006            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6007                Slog.w(TAG, "Unattached app died before backup, skipping");
6008                try {
6009                    IBackupManager bm = IBackupManager.Stub.asInterface(
6010                            ServiceManager.getService(Context.BACKUP_SERVICE));
6011                    bm.agentDisconnected(app.info.packageName);
6012                } catch (RemoteException e) {
6013                    // Can't happen; the backup manager is local
6014                }
6015            }
6016            if (isPendingBroadcastProcessLocked(pid)) {
6017                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6018                skipPendingBroadcastLocked(pid);
6019            }
6020        } else {
6021            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6022        }
6023    }
6024
6025    private final boolean attachApplicationLocked(IApplicationThread thread,
6026            int pid) {
6027
6028        // Find the application record that is being attached...  either via
6029        // the pid if we are running in multiple processes, or just pull the
6030        // next app record if we are emulating process with anonymous threads.
6031        ProcessRecord app;
6032        if (pid != MY_PID && pid >= 0) {
6033            synchronized (mPidsSelfLocked) {
6034                app = mPidsSelfLocked.get(pid);
6035            }
6036        } else {
6037            app = null;
6038        }
6039
6040        if (app == null) {
6041            Slog.w(TAG, "No pending application record for pid " + pid
6042                    + " (IApplicationThread " + thread + "); dropping process");
6043            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6044            if (pid > 0 && pid != MY_PID) {
6045                Process.killProcessQuiet(pid);
6046                //TODO: Process.killProcessGroup(app.info.uid, pid);
6047            } else {
6048                try {
6049                    thread.scheduleExit();
6050                } catch (Exception e) {
6051                    // Ignore exceptions.
6052                }
6053            }
6054            return false;
6055        }
6056
6057        // If this application record is still attached to a previous
6058        // process, clean it up now.
6059        if (app.thread != null) {
6060            handleAppDiedLocked(app, true, true);
6061        }
6062
6063        // Tell the process all about itself.
6064
6065        if (localLOGV) Slog.v(
6066                TAG, "Binding process pid " + pid + " to record " + app);
6067
6068        final String processName = app.processName;
6069        try {
6070            AppDeathRecipient adr = new AppDeathRecipient(
6071                    app, pid, thread);
6072            thread.asBinder().linkToDeath(adr, 0);
6073            app.deathRecipient = adr;
6074        } catch (RemoteException e) {
6075            app.resetPackageList(mProcessStats);
6076            startProcessLocked(app, "link fail", processName);
6077            return false;
6078        }
6079
6080        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6081
6082        app.makeActive(thread, mProcessStats);
6083        app.curAdj = app.setAdj = -100;
6084        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6085        app.forcingToForeground = null;
6086        updateProcessForegroundLocked(app, false, false);
6087        app.hasShownUi = false;
6088        app.debugging = false;
6089        app.cached = false;
6090
6091        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6092
6093        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6094        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6095
6096        if (!normalMode) {
6097            Slog.i(TAG, "Launching preboot mode app: " + app);
6098        }
6099
6100        if (localLOGV) Slog.v(
6101            TAG, "New app record " + app
6102            + " thread=" + thread.asBinder() + " pid=" + pid);
6103        try {
6104            int testMode = IApplicationThread.DEBUG_OFF;
6105            if (mDebugApp != null && mDebugApp.equals(processName)) {
6106                testMode = mWaitForDebugger
6107                    ? IApplicationThread.DEBUG_WAIT
6108                    : IApplicationThread.DEBUG_ON;
6109                app.debugging = true;
6110                if (mDebugTransient) {
6111                    mDebugApp = mOrigDebugApp;
6112                    mWaitForDebugger = mOrigWaitForDebugger;
6113                }
6114            }
6115            String profileFile = app.instrumentationProfileFile;
6116            ParcelFileDescriptor profileFd = null;
6117            int samplingInterval = 0;
6118            boolean profileAutoStop = false;
6119            if (mProfileApp != null && mProfileApp.equals(processName)) {
6120                mProfileProc = app;
6121                profileFile = mProfileFile;
6122                profileFd = mProfileFd;
6123                samplingInterval = mSamplingInterval;
6124                profileAutoStop = mAutoStopProfiler;
6125            }
6126            boolean enableOpenGlTrace = false;
6127            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6128                enableOpenGlTrace = true;
6129                mOpenGlTraceApp = null;
6130            }
6131
6132            // If the app is being launched for restore or full backup, set it up specially
6133            boolean isRestrictedBackupMode = false;
6134            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6135                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6136                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6137                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6138            }
6139
6140            ensurePackageDexOpt(app.instrumentationInfo != null
6141                    ? app.instrumentationInfo.packageName
6142                    : app.info.packageName);
6143            if (app.instrumentationClass != null) {
6144                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6145            }
6146            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6147                    + processName + " with config " + mConfiguration);
6148            ApplicationInfo appInfo = app.instrumentationInfo != null
6149                    ? app.instrumentationInfo : app.info;
6150            app.compat = compatibilityInfoForPackageLocked(appInfo);
6151            if (profileFd != null) {
6152                profileFd = profileFd.dup();
6153            }
6154            ProfilerInfo profilerInfo = profileFile == null ? null
6155                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6156            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6157                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6158                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6159                    isRestrictedBackupMode || !normalMode, app.persistent,
6160                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6161                    mCoreSettingsObserver.getCoreSettingsLocked());
6162            updateLruProcessLocked(app, false, null);
6163            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6164        } catch (Exception e) {
6165            // todo: Yikes!  What should we do?  For now we will try to
6166            // start another process, but that could easily get us in
6167            // an infinite loop of restarting processes...
6168            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6169
6170            app.resetPackageList(mProcessStats);
6171            app.unlinkDeathRecipient();
6172            startProcessLocked(app, "bind fail", processName);
6173            return false;
6174        }
6175
6176        // Remove this record from the list of starting applications.
6177        mPersistentStartingProcesses.remove(app);
6178        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6179                "Attach application locked removing on hold: " + app);
6180        mProcessesOnHold.remove(app);
6181
6182        boolean badApp = false;
6183        boolean didSomething = false;
6184
6185        // See if the top visible activity is waiting to run in this process...
6186        if (normalMode) {
6187            try {
6188                if (mStackSupervisor.attachApplicationLocked(app)) {
6189                    didSomething = true;
6190                }
6191            } catch (Exception e) {
6192                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6193                badApp = true;
6194            }
6195        }
6196
6197        // Find any services that should be running in this process...
6198        if (!badApp) {
6199            try {
6200                didSomething |= mServices.attachApplicationLocked(app, processName);
6201            } catch (Exception e) {
6202                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6203                badApp = true;
6204            }
6205        }
6206
6207        // Check if a next-broadcast receiver is in this process...
6208        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6209            try {
6210                didSomething |= sendPendingBroadcastsLocked(app);
6211            } catch (Exception e) {
6212                // If the app died trying to launch the receiver we declare it 'bad'
6213                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6214                badApp = true;
6215            }
6216        }
6217
6218        // Check whether the next backup agent is in this process...
6219        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6220            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6221            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6222            try {
6223                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6224                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6225                        mBackupTarget.backupMode);
6226            } catch (Exception e) {
6227                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6228                badApp = true;
6229            }
6230        }
6231
6232        if (badApp) {
6233            app.kill("error during init", true);
6234            handleAppDiedLocked(app, false, true);
6235            return false;
6236        }
6237
6238        if (!didSomething) {
6239            updateOomAdjLocked();
6240        }
6241
6242        return true;
6243    }
6244
6245    @Override
6246    public final void attachApplication(IApplicationThread thread) {
6247        synchronized (this) {
6248            int callingPid = Binder.getCallingPid();
6249            final long origId = Binder.clearCallingIdentity();
6250            attachApplicationLocked(thread, callingPid);
6251            Binder.restoreCallingIdentity(origId);
6252        }
6253    }
6254
6255    @Override
6256    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6257        final long origId = Binder.clearCallingIdentity();
6258        synchronized (this) {
6259            ActivityStack stack = ActivityRecord.getStackLocked(token);
6260            if (stack != null) {
6261                ActivityRecord r =
6262                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6263                if (stopProfiling) {
6264                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6265                        try {
6266                            mProfileFd.close();
6267                        } catch (IOException e) {
6268                        }
6269                        clearProfilerLocked();
6270                    }
6271                }
6272            }
6273        }
6274        Binder.restoreCallingIdentity(origId);
6275    }
6276
6277    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6278        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6279                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6280    }
6281
6282    void enableScreenAfterBoot() {
6283        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6284                SystemClock.uptimeMillis());
6285        mWindowManager.enableScreenAfterBoot();
6286
6287        synchronized (this) {
6288            updateEventDispatchingLocked();
6289        }
6290    }
6291
6292    @Override
6293    public void showBootMessage(final CharSequence msg, final boolean always) {
6294        enforceNotIsolatedCaller("showBootMessage");
6295        mWindowManager.showBootMessage(msg, always);
6296    }
6297
6298    @Override
6299    public void keyguardWaitingForActivityDrawn() {
6300        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6301        final long token = Binder.clearCallingIdentity();
6302        try {
6303            synchronized (this) {
6304                if (DEBUG_LOCKSCREEN) logLockScreen("");
6305                mWindowManager.keyguardWaitingForActivityDrawn();
6306                if (mLockScreenShown) {
6307                    mLockScreenShown = false;
6308                    comeOutOfSleepIfNeededLocked();
6309                }
6310            }
6311        } finally {
6312            Binder.restoreCallingIdentity(token);
6313        }
6314    }
6315
6316    final void finishBooting() {
6317        synchronized (this) {
6318            if (!mBootAnimationComplete) {
6319                mCallFinishBooting = true;
6320                return;
6321            }
6322            mCallFinishBooting = false;
6323        }
6324
6325        // Register receivers to handle package update events
6326        mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false);
6327
6328        // Let system services know.
6329        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6330
6331        synchronized (this) {
6332            // Ensure that any processes we had put on hold are now started
6333            // up.
6334            final int NP = mProcessesOnHold.size();
6335            if (NP > 0) {
6336                ArrayList<ProcessRecord> procs =
6337                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6338                for (int ip=0; ip<NP; ip++) {
6339                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6340                            + procs.get(ip));
6341                    startProcessLocked(procs.get(ip), "on-hold", null);
6342                }
6343            }
6344
6345            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6346                // Start looking for apps that are abusing wake locks.
6347                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6348                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6349                // Tell anyone interested that we are done booting!
6350                SystemProperties.set("sys.boot_completed", "1");
6351
6352                // And trigger dev.bootcomplete if we are not showing encryption progress
6353                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6354                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6355                    SystemProperties.set("dev.bootcomplete", "1");
6356                }
6357                for (int i=0; i<mStartedUsers.size(); i++) {
6358                    UserStartedState uss = mStartedUsers.valueAt(i);
6359                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6360                        uss.mState = UserStartedState.STATE_RUNNING;
6361                        final int userId = mStartedUsers.keyAt(i);
6362                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6363                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6364                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6365                        broadcastIntentLocked(null, null, intent, null,
6366                                new IIntentReceiver.Stub() {
6367                                    @Override
6368                                    public void performReceive(Intent intent, int resultCode,
6369                                            String data, Bundle extras, boolean ordered,
6370                                            boolean sticky, int sendingUser) {
6371                                        synchronized (ActivityManagerService.this) {
6372                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6373                                                    true, false);
6374                                        }
6375                                    }
6376                                },
6377                                0, null, null,
6378                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6379                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6380                                userId);
6381                    }
6382                }
6383                scheduleStartProfilesLocked();
6384            }
6385        }
6386    }
6387
6388    @Override
6389    public void bootAnimationComplete() {
6390        final boolean callFinishBooting;
6391        synchronized (this) {
6392            callFinishBooting = mCallFinishBooting;
6393            mBootAnimationComplete = true;
6394        }
6395        if (callFinishBooting) {
6396            finishBooting();
6397        }
6398    }
6399
6400    final void ensureBootCompleted() {
6401        boolean booting;
6402        boolean enableScreen;
6403        synchronized (this) {
6404            booting = mBooting;
6405            mBooting = false;
6406            enableScreen = !mBooted;
6407            mBooted = true;
6408        }
6409
6410        if (booting) {
6411            finishBooting();
6412        }
6413
6414        if (enableScreen) {
6415            enableScreenAfterBoot();
6416        }
6417    }
6418
6419    @Override
6420    public final void activityResumed(IBinder token) {
6421        final long origId = Binder.clearCallingIdentity();
6422        synchronized(this) {
6423            ActivityStack stack = ActivityRecord.getStackLocked(token);
6424            if (stack != null) {
6425                ActivityRecord.activityResumedLocked(token);
6426            }
6427        }
6428        Binder.restoreCallingIdentity(origId);
6429    }
6430
6431    @Override
6432    public final void activityPaused(IBinder token) {
6433        final long origId = Binder.clearCallingIdentity();
6434        synchronized(this) {
6435            ActivityStack stack = ActivityRecord.getStackLocked(token);
6436            if (stack != null) {
6437                stack.activityPausedLocked(token, false);
6438            }
6439        }
6440        Binder.restoreCallingIdentity(origId);
6441    }
6442
6443    @Override
6444    public final void activityStopped(IBinder token, Bundle icicle,
6445            PersistableBundle persistentState, CharSequence description) {
6446        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6447
6448        // Refuse possible leaked file descriptors
6449        if (icicle != null && icicle.hasFileDescriptors()) {
6450            throw new IllegalArgumentException("File descriptors passed in Bundle");
6451        }
6452
6453        final long origId = Binder.clearCallingIdentity();
6454
6455        synchronized (this) {
6456            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6457            if (r != null) {
6458                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6459            }
6460        }
6461
6462        trimApplications();
6463
6464        Binder.restoreCallingIdentity(origId);
6465    }
6466
6467    @Override
6468    public final void activityDestroyed(IBinder token) {
6469        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6470        synchronized (this) {
6471            ActivityStack stack = ActivityRecord.getStackLocked(token);
6472            if (stack != null) {
6473                stack.activityDestroyedLocked(token);
6474            }
6475        }
6476    }
6477
6478    @Override
6479    public final void backgroundResourcesReleased(IBinder token) {
6480        final long origId = Binder.clearCallingIdentity();
6481        try {
6482            synchronized (this) {
6483                ActivityStack stack = ActivityRecord.getStackLocked(token);
6484                if (stack != null) {
6485                    stack.backgroundResourcesReleased(token);
6486                }
6487            }
6488        } finally {
6489            Binder.restoreCallingIdentity(origId);
6490        }
6491    }
6492
6493    @Override
6494    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6495        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6496    }
6497
6498    @Override
6499    public final void notifyEnterAnimationComplete(IBinder token) {
6500        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6501    }
6502
6503    @Override
6504    public String getCallingPackage(IBinder token) {
6505        synchronized (this) {
6506            ActivityRecord r = getCallingRecordLocked(token);
6507            return r != null ? r.info.packageName : null;
6508        }
6509    }
6510
6511    @Override
6512    public ComponentName getCallingActivity(IBinder token) {
6513        synchronized (this) {
6514            ActivityRecord r = getCallingRecordLocked(token);
6515            return r != null ? r.intent.getComponent() : null;
6516        }
6517    }
6518
6519    private ActivityRecord getCallingRecordLocked(IBinder token) {
6520        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6521        if (r == null) {
6522            return null;
6523        }
6524        return r.resultTo;
6525    }
6526
6527    @Override
6528    public ComponentName getActivityClassForToken(IBinder token) {
6529        synchronized(this) {
6530            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6531            if (r == null) {
6532                return null;
6533            }
6534            return r.intent.getComponent();
6535        }
6536    }
6537
6538    @Override
6539    public String getPackageForToken(IBinder token) {
6540        synchronized(this) {
6541            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6542            if (r == null) {
6543                return null;
6544            }
6545            return r.packageName;
6546        }
6547    }
6548
6549    @Override
6550    public IIntentSender getIntentSender(int type,
6551            String packageName, IBinder token, String resultWho,
6552            int requestCode, Intent[] intents, String[] resolvedTypes,
6553            int flags, Bundle options, int userId) {
6554        enforceNotIsolatedCaller("getIntentSender");
6555        // Refuse possible leaked file descriptors
6556        if (intents != null) {
6557            if (intents.length < 1) {
6558                throw new IllegalArgumentException("Intents array length must be >= 1");
6559            }
6560            for (int i=0; i<intents.length; i++) {
6561                Intent intent = intents[i];
6562                if (intent != null) {
6563                    if (intent.hasFileDescriptors()) {
6564                        throw new IllegalArgumentException("File descriptors passed in Intent");
6565                    }
6566                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6567                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6568                        throw new IllegalArgumentException(
6569                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6570                    }
6571                    intents[i] = new Intent(intent);
6572                }
6573            }
6574            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6575                throw new IllegalArgumentException(
6576                        "Intent array length does not match resolvedTypes length");
6577            }
6578        }
6579        if (options != null) {
6580            if (options.hasFileDescriptors()) {
6581                throw new IllegalArgumentException("File descriptors passed in options");
6582            }
6583        }
6584
6585        synchronized(this) {
6586            int callingUid = Binder.getCallingUid();
6587            int origUserId = userId;
6588            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6589                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6590                    ALLOW_NON_FULL, "getIntentSender", null);
6591            if (origUserId == UserHandle.USER_CURRENT) {
6592                // We don't want to evaluate this until the pending intent is
6593                // actually executed.  However, we do want to always do the
6594                // security checking for it above.
6595                userId = UserHandle.USER_CURRENT;
6596            }
6597            try {
6598                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6599                    int uid = AppGlobals.getPackageManager()
6600                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6601                    if (!UserHandle.isSameApp(callingUid, uid)) {
6602                        String msg = "Permission Denial: getIntentSender() from pid="
6603                            + Binder.getCallingPid()
6604                            + ", uid=" + Binder.getCallingUid()
6605                            + ", (need uid=" + uid + ")"
6606                            + " is not allowed to send as package " + packageName;
6607                        Slog.w(TAG, msg);
6608                        throw new SecurityException(msg);
6609                    }
6610                }
6611
6612                return getIntentSenderLocked(type, packageName, callingUid, userId,
6613                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6614
6615            } catch (RemoteException e) {
6616                throw new SecurityException(e);
6617            }
6618        }
6619    }
6620
6621    IIntentSender getIntentSenderLocked(int type, String packageName,
6622            int callingUid, int userId, IBinder token, String resultWho,
6623            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6624            Bundle options) {
6625        if (DEBUG_MU)
6626            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6627        ActivityRecord activity = null;
6628        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6629            activity = ActivityRecord.isInStackLocked(token);
6630            if (activity == null) {
6631                return null;
6632            }
6633            if (activity.finishing) {
6634                return null;
6635            }
6636        }
6637
6638        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6639        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6640        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6641        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6642                |PendingIntent.FLAG_UPDATE_CURRENT);
6643
6644        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6645                type, packageName, activity, resultWho,
6646                requestCode, intents, resolvedTypes, flags, options, userId);
6647        WeakReference<PendingIntentRecord> ref;
6648        ref = mIntentSenderRecords.get(key);
6649        PendingIntentRecord rec = ref != null ? ref.get() : null;
6650        if (rec != null) {
6651            if (!cancelCurrent) {
6652                if (updateCurrent) {
6653                    if (rec.key.requestIntent != null) {
6654                        rec.key.requestIntent.replaceExtras(intents != null ?
6655                                intents[intents.length - 1] : null);
6656                    }
6657                    if (intents != null) {
6658                        intents[intents.length-1] = rec.key.requestIntent;
6659                        rec.key.allIntents = intents;
6660                        rec.key.allResolvedTypes = resolvedTypes;
6661                    } else {
6662                        rec.key.allIntents = null;
6663                        rec.key.allResolvedTypes = null;
6664                    }
6665                }
6666                return rec;
6667            }
6668            rec.canceled = true;
6669            mIntentSenderRecords.remove(key);
6670        }
6671        if (noCreate) {
6672            return rec;
6673        }
6674        rec = new PendingIntentRecord(this, key, callingUid);
6675        mIntentSenderRecords.put(key, rec.ref);
6676        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6677            if (activity.pendingResults == null) {
6678                activity.pendingResults
6679                        = new HashSet<WeakReference<PendingIntentRecord>>();
6680            }
6681            activity.pendingResults.add(rec.ref);
6682        }
6683        return rec;
6684    }
6685
6686    @Override
6687    public void cancelIntentSender(IIntentSender sender) {
6688        if (!(sender instanceof PendingIntentRecord)) {
6689            return;
6690        }
6691        synchronized(this) {
6692            PendingIntentRecord rec = (PendingIntentRecord)sender;
6693            try {
6694                int uid = AppGlobals.getPackageManager()
6695                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6696                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6697                    String msg = "Permission Denial: cancelIntentSender() from pid="
6698                        + Binder.getCallingPid()
6699                        + ", uid=" + Binder.getCallingUid()
6700                        + " is not allowed to cancel packges "
6701                        + rec.key.packageName;
6702                    Slog.w(TAG, msg);
6703                    throw new SecurityException(msg);
6704                }
6705            } catch (RemoteException e) {
6706                throw new SecurityException(e);
6707            }
6708            cancelIntentSenderLocked(rec, true);
6709        }
6710    }
6711
6712    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6713        rec.canceled = true;
6714        mIntentSenderRecords.remove(rec.key);
6715        if (cleanActivity && rec.key.activity != null) {
6716            rec.key.activity.pendingResults.remove(rec.ref);
6717        }
6718    }
6719
6720    @Override
6721    public String getPackageForIntentSender(IIntentSender pendingResult) {
6722        if (!(pendingResult instanceof PendingIntentRecord)) {
6723            return null;
6724        }
6725        try {
6726            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6727            return res.key.packageName;
6728        } catch (ClassCastException e) {
6729        }
6730        return null;
6731    }
6732
6733    @Override
6734    public int getUidForIntentSender(IIntentSender sender) {
6735        if (sender instanceof PendingIntentRecord) {
6736            try {
6737                PendingIntentRecord res = (PendingIntentRecord)sender;
6738                return res.uid;
6739            } catch (ClassCastException e) {
6740            }
6741        }
6742        return -1;
6743    }
6744
6745    @Override
6746    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6747        if (!(pendingResult instanceof PendingIntentRecord)) {
6748            return false;
6749        }
6750        try {
6751            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6752            if (res.key.allIntents == null) {
6753                return false;
6754            }
6755            for (int i=0; i<res.key.allIntents.length; i++) {
6756                Intent intent = res.key.allIntents[i];
6757                if (intent.getPackage() != null && intent.getComponent() != null) {
6758                    return false;
6759                }
6760            }
6761            return true;
6762        } catch (ClassCastException e) {
6763        }
6764        return false;
6765    }
6766
6767    @Override
6768    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6769        if (!(pendingResult instanceof PendingIntentRecord)) {
6770            return false;
6771        }
6772        try {
6773            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6774            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6775                return true;
6776            }
6777            return false;
6778        } catch (ClassCastException e) {
6779        }
6780        return false;
6781    }
6782
6783    @Override
6784    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6785        if (!(pendingResult instanceof PendingIntentRecord)) {
6786            return null;
6787        }
6788        try {
6789            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6790            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6791        } catch (ClassCastException e) {
6792        }
6793        return null;
6794    }
6795
6796    @Override
6797    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6798        if (!(pendingResult instanceof PendingIntentRecord)) {
6799            return null;
6800        }
6801        try {
6802            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6803            Intent intent = res.key.requestIntent;
6804            if (intent != null) {
6805                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6806                        || res.lastTagPrefix.equals(prefix))) {
6807                    return res.lastTag;
6808                }
6809                res.lastTagPrefix = prefix;
6810                StringBuilder sb = new StringBuilder(128);
6811                if (prefix != null) {
6812                    sb.append(prefix);
6813                }
6814                if (intent.getAction() != null) {
6815                    sb.append(intent.getAction());
6816                } else if (intent.getComponent() != null) {
6817                    intent.getComponent().appendShortString(sb);
6818                } else {
6819                    sb.append("?");
6820                }
6821                return res.lastTag = sb.toString();
6822            }
6823        } catch (ClassCastException e) {
6824        }
6825        return null;
6826    }
6827
6828    @Override
6829    public void setProcessLimit(int max) {
6830        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6831                "setProcessLimit()");
6832        synchronized (this) {
6833            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6834            mProcessLimitOverride = max;
6835        }
6836        trimApplications();
6837    }
6838
6839    @Override
6840    public int getProcessLimit() {
6841        synchronized (this) {
6842            return mProcessLimitOverride;
6843        }
6844    }
6845
6846    void foregroundTokenDied(ForegroundToken token) {
6847        synchronized (ActivityManagerService.this) {
6848            synchronized (mPidsSelfLocked) {
6849                ForegroundToken cur
6850                    = mForegroundProcesses.get(token.pid);
6851                if (cur != token) {
6852                    return;
6853                }
6854                mForegroundProcesses.remove(token.pid);
6855                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6856                if (pr == null) {
6857                    return;
6858                }
6859                pr.forcingToForeground = null;
6860                updateProcessForegroundLocked(pr, false, false);
6861            }
6862            updateOomAdjLocked();
6863        }
6864    }
6865
6866    @Override
6867    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6868        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6869                "setProcessForeground()");
6870        synchronized(this) {
6871            boolean changed = false;
6872
6873            synchronized (mPidsSelfLocked) {
6874                ProcessRecord pr = mPidsSelfLocked.get(pid);
6875                if (pr == null && isForeground) {
6876                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6877                    return;
6878                }
6879                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6880                if (oldToken != null) {
6881                    oldToken.token.unlinkToDeath(oldToken, 0);
6882                    mForegroundProcesses.remove(pid);
6883                    if (pr != null) {
6884                        pr.forcingToForeground = null;
6885                    }
6886                    changed = true;
6887                }
6888                if (isForeground && token != null) {
6889                    ForegroundToken newToken = new ForegroundToken() {
6890                        @Override
6891                        public void binderDied() {
6892                            foregroundTokenDied(this);
6893                        }
6894                    };
6895                    newToken.pid = pid;
6896                    newToken.token = token;
6897                    try {
6898                        token.linkToDeath(newToken, 0);
6899                        mForegroundProcesses.put(pid, newToken);
6900                        pr.forcingToForeground = token;
6901                        changed = true;
6902                    } catch (RemoteException e) {
6903                        // If the process died while doing this, we will later
6904                        // do the cleanup with the process death link.
6905                    }
6906                }
6907            }
6908
6909            if (changed) {
6910                updateOomAdjLocked();
6911            }
6912        }
6913    }
6914
6915    // =========================================================
6916    // PERMISSIONS
6917    // =========================================================
6918
6919    static class PermissionController extends IPermissionController.Stub {
6920        ActivityManagerService mActivityManagerService;
6921        PermissionController(ActivityManagerService activityManagerService) {
6922            mActivityManagerService = activityManagerService;
6923        }
6924
6925        @Override
6926        public boolean checkPermission(String permission, int pid, int uid) {
6927            return mActivityManagerService.checkPermission(permission, pid,
6928                    uid) == PackageManager.PERMISSION_GRANTED;
6929        }
6930    }
6931
6932    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6933        @Override
6934        public int checkComponentPermission(String permission, int pid, int uid,
6935                int owningUid, boolean exported) {
6936            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6937                    owningUid, exported);
6938        }
6939
6940        @Override
6941        public Object getAMSLock() {
6942            return ActivityManagerService.this;
6943        }
6944    }
6945
6946    /**
6947     * This can be called with or without the global lock held.
6948     */
6949    int checkComponentPermission(String permission, int pid, int uid,
6950            int owningUid, boolean exported) {
6951        // We might be performing an operation on behalf of an indirect binder
6952        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6953        // client identity accordingly before proceeding.
6954        Identity tlsIdentity = sCallerIdentity.get();
6955        if (tlsIdentity != null) {
6956            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6957                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6958            uid = tlsIdentity.uid;
6959            pid = tlsIdentity.pid;
6960        }
6961
6962        if (pid == MY_PID) {
6963            return PackageManager.PERMISSION_GRANTED;
6964        }
6965
6966        return ActivityManager.checkComponentPermission(permission, uid,
6967                owningUid, exported);
6968    }
6969
6970    /**
6971     * As the only public entry point for permissions checking, this method
6972     * can enforce the semantic that requesting a check on a null global
6973     * permission is automatically denied.  (Internally a null permission
6974     * string is used when calling {@link #checkComponentPermission} in cases
6975     * when only uid-based security is needed.)
6976     *
6977     * This can be called with or without the global lock held.
6978     */
6979    @Override
6980    public int checkPermission(String permission, int pid, int uid) {
6981        if (permission == null) {
6982            return PackageManager.PERMISSION_DENIED;
6983        }
6984        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6985    }
6986
6987    /**
6988     * Binder IPC calls go through the public entry point.
6989     * This can be called with or without the global lock held.
6990     */
6991    int checkCallingPermission(String permission) {
6992        return checkPermission(permission,
6993                Binder.getCallingPid(),
6994                UserHandle.getAppId(Binder.getCallingUid()));
6995    }
6996
6997    /**
6998     * This can be called with or without the global lock held.
6999     */
7000    void enforceCallingPermission(String permission, String func) {
7001        if (checkCallingPermission(permission)
7002                == PackageManager.PERMISSION_GRANTED) {
7003            return;
7004        }
7005
7006        String msg = "Permission Denial: " + func + " from pid="
7007                + Binder.getCallingPid()
7008                + ", uid=" + Binder.getCallingUid()
7009                + " requires " + permission;
7010        Slog.w(TAG, msg);
7011        throw new SecurityException(msg);
7012    }
7013
7014    /**
7015     * Determine if UID is holding permissions required to access {@link Uri} in
7016     * the given {@link ProviderInfo}. Final permission checking is always done
7017     * in {@link ContentProvider}.
7018     */
7019    private final boolean checkHoldingPermissionsLocked(
7020            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7021        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7022                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7023        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7024            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7025                    != PERMISSION_GRANTED) {
7026                return false;
7027            }
7028        }
7029        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7030    }
7031
7032    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7033            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7034        if (pi.applicationInfo.uid == uid) {
7035            return true;
7036        } else if (!pi.exported) {
7037            return false;
7038        }
7039
7040        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7041        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7042        try {
7043            // check if target holds top-level <provider> permissions
7044            if (!readMet && pi.readPermission != null && considerUidPermissions
7045                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7046                readMet = true;
7047            }
7048            if (!writeMet && pi.writePermission != null && considerUidPermissions
7049                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7050                writeMet = true;
7051            }
7052
7053            // track if unprotected read/write is allowed; any denied
7054            // <path-permission> below removes this ability
7055            boolean allowDefaultRead = pi.readPermission == null;
7056            boolean allowDefaultWrite = pi.writePermission == null;
7057
7058            // check if target holds any <path-permission> that match uri
7059            final PathPermission[] pps = pi.pathPermissions;
7060            if (pps != null) {
7061                final String path = grantUri.uri.getPath();
7062                int i = pps.length;
7063                while (i > 0 && (!readMet || !writeMet)) {
7064                    i--;
7065                    PathPermission pp = pps[i];
7066                    if (pp.match(path)) {
7067                        if (!readMet) {
7068                            final String pprperm = pp.getReadPermission();
7069                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
7070                                    + pprperm + " for " + pp.getPath()
7071                                    + ": match=" + pp.match(path)
7072                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7073                            if (pprperm != null) {
7074                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7075                                        == PERMISSION_GRANTED) {
7076                                    readMet = true;
7077                                } else {
7078                                    allowDefaultRead = false;
7079                                }
7080                            }
7081                        }
7082                        if (!writeMet) {
7083                            final String ppwperm = pp.getWritePermission();
7084                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
7085                                    + ppwperm + " for " + pp.getPath()
7086                                    + ": match=" + pp.match(path)
7087                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7088                            if (ppwperm != null) {
7089                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7090                                        == PERMISSION_GRANTED) {
7091                                    writeMet = true;
7092                                } else {
7093                                    allowDefaultWrite = false;
7094                                }
7095                            }
7096                        }
7097                    }
7098                }
7099            }
7100
7101            // grant unprotected <provider> read/write, if not blocked by
7102            // <path-permission> above
7103            if (allowDefaultRead) readMet = true;
7104            if (allowDefaultWrite) writeMet = true;
7105
7106        } catch (RemoteException e) {
7107            return false;
7108        }
7109
7110        return readMet && writeMet;
7111    }
7112
7113    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7114        ProviderInfo pi = null;
7115        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7116        if (cpr != null) {
7117            pi = cpr.info;
7118        } else {
7119            try {
7120                pi = AppGlobals.getPackageManager().resolveContentProvider(
7121                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7122            } catch (RemoteException ex) {
7123            }
7124        }
7125        return pi;
7126    }
7127
7128    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7129        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7130        if (targetUris != null) {
7131            return targetUris.get(grantUri);
7132        }
7133        return null;
7134    }
7135
7136    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7137            String targetPkg, int targetUid, GrantUri grantUri) {
7138        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7139        if (targetUris == null) {
7140            targetUris = Maps.newArrayMap();
7141            mGrantedUriPermissions.put(targetUid, targetUris);
7142        }
7143
7144        UriPermission perm = targetUris.get(grantUri);
7145        if (perm == null) {
7146            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7147            targetUris.put(grantUri, perm);
7148        }
7149
7150        return perm;
7151    }
7152
7153    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7154            final int modeFlags) {
7155        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7156        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7157                : UriPermission.STRENGTH_OWNED;
7158
7159        // Root gets to do everything.
7160        if (uid == 0) {
7161            return true;
7162        }
7163
7164        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7165        if (perms == null) return false;
7166
7167        // First look for exact match
7168        final UriPermission exactPerm = perms.get(grantUri);
7169        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7170            return true;
7171        }
7172
7173        // No exact match, look for prefixes
7174        final int N = perms.size();
7175        for (int i = 0; i < N; i++) {
7176            final UriPermission perm = perms.valueAt(i);
7177            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7178                    && perm.getStrength(modeFlags) >= minStrength) {
7179                return true;
7180            }
7181        }
7182
7183        return false;
7184    }
7185
7186    /**
7187     * @param uri This uri must NOT contain an embedded userId.
7188     * @param userId The userId in which the uri is to be resolved.
7189     */
7190    @Override
7191    public int checkUriPermission(Uri uri, int pid, int uid,
7192            final int modeFlags, int userId) {
7193        enforceNotIsolatedCaller("checkUriPermission");
7194
7195        // Another redirected-binder-call permissions check as in
7196        // {@link checkComponentPermission}.
7197        Identity tlsIdentity = sCallerIdentity.get();
7198        if (tlsIdentity != null) {
7199            uid = tlsIdentity.uid;
7200            pid = tlsIdentity.pid;
7201        }
7202
7203        // Our own process gets to do everything.
7204        if (pid == MY_PID) {
7205            return PackageManager.PERMISSION_GRANTED;
7206        }
7207        synchronized (this) {
7208            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7209                    ? PackageManager.PERMISSION_GRANTED
7210                    : PackageManager.PERMISSION_DENIED;
7211        }
7212    }
7213
7214    /**
7215     * Check if the targetPkg can be granted permission to access uri by
7216     * the callingUid using the given modeFlags.  Throws a security exception
7217     * if callingUid is not allowed to do this.  Returns the uid of the target
7218     * if the URI permission grant should be performed; returns -1 if it is not
7219     * needed (for example targetPkg already has permission to access the URI).
7220     * If you already know the uid of the target, you can supply it in
7221     * lastTargetUid else set that to -1.
7222     */
7223    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7224            final int modeFlags, int lastTargetUid) {
7225        if (!Intent.isAccessUriMode(modeFlags)) {
7226            return -1;
7227        }
7228
7229        if (targetPkg != null) {
7230            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7231                    "Checking grant " + targetPkg + " permission to " + grantUri);
7232        }
7233
7234        final IPackageManager pm = AppGlobals.getPackageManager();
7235
7236        // If this is not a content: uri, we can't do anything with it.
7237        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7238            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7239                    "Can't grant URI permission for non-content URI: " + grantUri);
7240            return -1;
7241        }
7242
7243        final String authority = grantUri.uri.getAuthority();
7244        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7245        if (pi == null) {
7246            Slog.w(TAG, "No content provider found for permission check: " +
7247                    grantUri.uri.toSafeString());
7248            return -1;
7249        }
7250
7251        int targetUid = lastTargetUid;
7252        if (targetUid < 0 && targetPkg != null) {
7253            try {
7254                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7255                if (targetUid < 0) {
7256                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7257                            "Can't grant URI permission no uid for: " + targetPkg);
7258                    return -1;
7259                }
7260            } catch (RemoteException ex) {
7261                return -1;
7262            }
7263        }
7264
7265        if (targetUid >= 0) {
7266            // First...  does the target actually need this permission?
7267            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7268                // No need to grant the target this permission.
7269                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7270                        "Target " + targetPkg + " already has full permission to " + grantUri);
7271                return -1;
7272            }
7273        } else {
7274            // First...  there is no target package, so can anyone access it?
7275            boolean allowed = pi.exported;
7276            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7277                if (pi.readPermission != null) {
7278                    allowed = false;
7279                }
7280            }
7281            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7282                if (pi.writePermission != null) {
7283                    allowed = false;
7284                }
7285            }
7286            if (allowed) {
7287                return -1;
7288            }
7289        }
7290
7291        /* There is a special cross user grant if:
7292         * - The target is on another user.
7293         * - Apps on the current user can access the uri without any uid permissions.
7294         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7295         * grant uri permissions.
7296         */
7297        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7298                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7299                modeFlags, false /*without considering the uid permissions*/);
7300
7301        // Second...  is the provider allowing granting of URI permissions?
7302        if (!specialCrossUserGrant) {
7303            if (!pi.grantUriPermissions) {
7304                throw new SecurityException("Provider " + pi.packageName
7305                        + "/" + pi.name
7306                        + " does not allow granting of Uri permissions (uri "
7307                        + grantUri + ")");
7308            }
7309            if (pi.uriPermissionPatterns != null) {
7310                final int N = pi.uriPermissionPatterns.length;
7311                boolean allowed = false;
7312                for (int i=0; i<N; i++) {
7313                    if (pi.uriPermissionPatterns[i] != null
7314                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7315                        allowed = true;
7316                        break;
7317                    }
7318                }
7319                if (!allowed) {
7320                    throw new SecurityException("Provider " + pi.packageName
7321                            + "/" + pi.name
7322                            + " does not allow granting of permission to path of Uri "
7323                            + grantUri);
7324                }
7325            }
7326        }
7327
7328        // Third...  does the caller itself have permission to access
7329        // this uri?
7330        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7331            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7332                // Require they hold a strong enough Uri permission
7333                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7334                    throw new SecurityException("Uid " + callingUid
7335                            + " does not have permission to uri " + grantUri);
7336                }
7337            }
7338        }
7339        return targetUid;
7340    }
7341
7342    /**
7343     * @param uri This uri must NOT contain an embedded userId.
7344     * @param userId The userId in which the uri is to be resolved.
7345     */
7346    @Override
7347    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7348            final int modeFlags, int userId) {
7349        enforceNotIsolatedCaller("checkGrantUriPermission");
7350        synchronized(this) {
7351            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7352                    new GrantUri(userId, uri, false), modeFlags, -1);
7353        }
7354    }
7355
7356    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7357            final int modeFlags, UriPermissionOwner owner) {
7358        if (!Intent.isAccessUriMode(modeFlags)) {
7359            return;
7360        }
7361
7362        // So here we are: the caller has the assumed permission
7363        // to the uri, and the target doesn't.  Let's now give this to
7364        // the target.
7365
7366        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7367                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7368
7369        final String authority = grantUri.uri.getAuthority();
7370        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7371        if (pi == null) {
7372            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7373            return;
7374        }
7375
7376        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7377            grantUri.prefix = true;
7378        }
7379        final UriPermission perm = findOrCreateUriPermissionLocked(
7380                pi.packageName, targetPkg, targetUid, grantUri);
7381        perm.grantModes(modeFlags, owner);
7382    }
7383
7384    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7385            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7386        if (targetPkg == null) {
7387            throw new NullPointerException("targetPkg");
7388        }
7389        int targetUid;
7390        final IPackageManager pm = AppGlobals.getPackageManager();
7391        try {
7392            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7393        } catch (RemoteException ex) {
7394            return;
7395        }
7396
7397        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7398                targetUid);
7399        if (targetUid < 0) {
7400            return;
7401        }
7402
7403        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7404                owner);
7405    }
7406
7407    static class NeededUriGrants extends ArrayList<GrantUri> {
7408        final String targetPkg;
7409        final int targetUid;
7410        final int flags;
7411
7412        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7413            this.targetPkg = targetPkg;
7414            this.targetUid = targetUid;
7415            this.flags = flags;
7416        }
7417    }
7418
7419    /**
7420     * Like checkGrantUriPermissionLocked, but takes an Intent.
7421     */
7422    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7423            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7424        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7425                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7426                + " clip=" + (intent != null ? intent.getClipData() : null)
7427                + " from " + intent + "; flags=0x"
7428                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7429
7430        if (targetPkg == null) {
7431            throw new NullPointerException("targetPkg");
7432        }
7433
7434        if (intent == null) {
7435            return null;
7436        }
7437        Uri data = intent.getData();
7438        ClipData clip = intent.getClipData();
7439        if (data == null && clip == null) {
7440            return null;
7441        }
7442        // Default userId for uris in the intent (if they don't specify it themselves)
7443        int contentUserHint = intent.getContentUserHint();
7444        if (contentUserHint == UserHandle.USER_CURRENT) {
7445            contentUserHint = UserHandle.getUserId(callingUid);
7446        }
7447        final IPackageManager pm = AppGlobals.getPackageManager();
7448        int targetUid;
7449        if (needed != null) {
7450            targetUid = needed.targetUid;
7451        } else {
7452            try {
7453                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7454            } catch (RemoteException ex) {
7455                return null;
7456            }
7457            if (targetUid < 0) {
7458                if (DEBUG_URI_PERMISSION) {
7459                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7460                            + " on user " + targetUserId);
7461                }
7462                return null;
7463            }
7464        }
7465        if (data != null) {
7466            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7467            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7468                    targetUid);
7469            if (targetUid > 0) {
7470                if (needed == null) {
7471                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7472                }
7473                needed.add(grantUri);
7474            }
7475        }
7476        if (clip != null) {
7477            for (int i=0; i<clip.getItemCount(); i++) {
7478                Uri uri = clip.getItemAt(i).getUri();
7479                if (uri != null) {
7480                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7481                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7482                            targetUid);
7483                    if (targetUid > 0) {
7484                        if (needed == null) {
7485                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7486                        }
7487                        needed.add(grantUri);
7488                    }
7489                } else {
7490                    Intent clipIntent = clip.getItemAt(i).getIntent();
7491                    if (clipIntent != null) {
7492                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7493                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7494                        if (newNeeded != null) {
7495                            needed = newNeeded;
7496                        }
7497                    }
7498                }
7499            }
7500        }
7501
7502        return needed;
7503    }
7504
7505    /**
7506     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7507     */
7508    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7509            UriPermissionOwner owner) {
7510        if (needed != null) {
7511            for (int i=0; i<needed.size(); i++) {
7512                GrantUri grantUri = needed.get(i);
7513                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7514                        grantUri, needed.flags, owner);
7515            }
7516        }
7517    }
7518
7519    void grantUriPermissionFromIntentLocked(int callingUid,
7520            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7521        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7522                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7523        if (needed == null) {
7524            return;
7525        }
7526
7527        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7528    }
7529
7530    /**
7531     * @param uri This uri must NOT contain an embedded userId.
7532     * @param userId The userId in which the uri is to be resolved.
7533     */
7534    @Override
7535    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7536            final int modeFlags, int userId) {
7537        enforceNotIsolatedCaller("grantUriPermission");
7538        GrantUri grantUri = new GrantUri(userId, uri, false);
7539        synchronized(this) {
7540            final ProcessRecord r = getRecordForAppLocked(caller);
7541            if (r == null) {
7542                throw new SecurityException("Unable to find app for caller "
7543                        + caller
7544                        + " when granting permission to uri " + grantUri);
7545            }
7546            if (targetPkg == null) {
7547                throw new IllegalArgumentException("null target");
7548            }
7549            if (grantUri == null) {
7550                throw new IllegalArgumentException("null uri");
7551            }
7552
7553            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7554                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7555                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7556                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7557
7558            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7559                    UserHandle.getUserId(r.uid));
7560        }
7561    }
7562
7563    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7564        if (perm.modeFlags == 0) {
7565            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7566                    perm.targetUid);
7567            if (perms != null) {
7568                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7569                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7570
7571                perms.remove(perm.uri);
7572                if (perms.isEmpty()) {
7573                    mGrantedUriPermissions.remove(perm.targetUid);
7574                }
7575            }
7576        }
7577    }
7578
7579    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7580        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7581
7582        final IPackageManager pm = AppGlobals.getPackageManager();
7583        final String authority = grantUri.uri.getAuthority();
7584        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7585        if (pi == null) {
7586            Slog.w(TAG, "No content provider found for permission revoke: "
7587                    + grantUri.toSafeString());
7588            return;
7589        }
7590
7591        // Does the caller have this permission on the URI?
7592        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7593            // If they don't have direct access to the URI, then revoke any
7594            // ownerless URI permissions that have been granted to them.
7595            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7596            if (perms != null) {
7597                boolean persistChanged = false;
7598                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7599                    final UriPermission perm = it.next();
7600                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7601                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7602                        if (DEBUG_URI_PERMISSION)
7603                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7604                                    " permission to " + perm.uri);
7605                        persistChanged |= perm.revokeModes(
7606                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7607                        if (perm.modeFlags == 0) {
7608                            it.remove();
7609                        }
7610                    }
7611                }
7612                if (perms.isEmpty()) {
7613                    mGrantedUriPermissions.remove(callingUid);
7614                }
7615                if (persistChanged) {
7616                    schedulePersistUriGrants();
7617                }
7618            }
7619            return;
7620        }
7621
7622        boolean persistChanged = false;
7623
7624        // Go through all of the permissions and remove any that match.
7625        int N = mGrantedUriPermissions.size();
7626        for (int i = 0; i < N; i++) {
7627            final int targetUid = mGrantedUriPermissions.keyAt(i);
7628            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7629
7630            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7631                final UriPermission perm = it.next();
7632                if (perm.uri.sourceUserId == grantUri.sourceUserId
7633                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7634                    if (DEBUG_URI_PERMISSION)
7635                        Slog.v(TAG,
7636                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7637                    persistChanged |= perm.revokeModes(
7638                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7639                    if (perm.modeFlags == 0) {
7640                        it.remove();
7641                    }
7642                }
7643            }
7644
7645            if (perms.isEmpty()) {
7646                mGrantedUriPermissions.remove(targetUid);
7647                N--;
7648                i--;
7649            }
7650        }
7651
7652        if (persistChanged) {
7653            schedulePersistUriGrants();
7654        }
7655    }
7656
7657    /**
7658     * @param uri This uri must NOT contain an embedded userId.
7659     * @param userId The userId in which the uri is to be resolved.
7660     */
7661    @Override
7662    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7663            int userId) {
7664        enforceNotIsolatedCaller("revokeUriPermission");
7665        synchronized(this) {
7666            final ProcessRecord r = getRecordForAppLocked(caller);
7667            if (r == null) {
7668                throw new SecurityException("Unable to find app for caller "
7669                        + caller
7670                        + " when revoking permission to uri " + uri);
7671            }
7672            if (uri == null) {
7673                Slog.w(TAG, "revokeUriPermission: null uri");
7674                return;
7675            }
7676
7677            if (!Intent.isAccessUriMode(modeFlags)) {
7678                return;
7679            }
7680
7681            final IPackageManager pm = AppGlobals.getPackageManager();
7682            final String authority = uri.getAuthority();
7683            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7684            if (pi == null) {
7685                Slog.w(TAG, "No content provider found for permission revoke: "
7686                        + uri.toSafeString());
7687                return;
7688            }
7689
7690            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7691        }
7692    }
7693
7694    /**
7695     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7696     * given package.
7697     *
7698     * @param packageName Package name to match, or {@code null} to apply to all
7699     *            packages.
7700     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7701     *            to all users.
7702     * @param persistable If persistable grants should be removed.
7703     */
7704    private void removeUriPermissionsForPackageLocked(
7705            String packageName, int userHandle, boolean persistable) {
7706        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7707            throw new IllegalArgumentException("Must narrow by either package or user");
7708        }
7709
7710        boolean persistChanged = false;
7711
7712        int N = mGrantedUriPermissions.size();
7713        for (int i = 0; i < N; i++) {
7714            final int targetUid = mGrantedUriPermissions.keyAt(i);
7715            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7716
7717            // Only inspect grants matching user
7718            if (userHandle == UserHandle.USER_ALL
7719                    || userHandle == UserHandle.getUserId(targetUid)) {
7720                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7721                    final UriPermission perm = it.next();
7722
7723                    // Only inspect grants matching package
7724                    if (packageName == null || perm.sourcePkg.equals(packageName)
7725                            || perm.targetPkg.equals(packageName)) {
7726                        persistChanged |= perm.revokeModes(persistable
7727                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7728
7729                        // Only remove when no modes remain; any persisted grants
7730                        // will keep this alive.
7731                        if (perm.modeFlags == 0) {
7732                            it.remove();
7733                        }
7734                    }
7735                }
7736
7737                if (perms.isEmpty()) {
7738                    mGrantedUriPermissions.remove(targetUid);
7739                    N--;
7740                    i--;
7741                }
7742            }
7743        }
7744
7745        if (persistChanged) {
7746            schedulePersistUriGrants();
7747        }
7748    }
7749
7750    @Override
7751    public IBinder newUriPermissionOwner(String name) {
7752        enforceNotIsolatedCaller("newUriPermissionOwner");
7753        synchronized(this) {
7754            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7755            return owner.getExternalTokenLocked();
7756        }
7757    }
7758
7759    /**
7760     * @param uri This uri must NOT contain an embedded userId.
7761     * @param sourceUserId The userId in which the uri is to be resolved.
7762     * @param targetUserId The userId of the app that receives the grant.
7763     */
7764    @Override
7765    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7766            final int modeFlags, int sourceUserId, int targetUserId) {
7767        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7768                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7769        synchronized(this) {
7770            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7771            if (owner == null) {
7772                throw new IllegalArgumentException("Unknown owner: " + token);
7773            }
7774            if (fromUid != Binder.getCallingUid()) {
7775                if (Binder.getCallingUid() != Process.myUid()) {
7776                    // Only system code can grant URI permissions on behalf
7777                    // of other users.
7778                    throw new SecurityException("nice try");
7779                }
7780            }
7781            if (targetPkg == null) {
7782                throw new IllegalArgumentException("null target");
7783            }
7784            if (uri == null) {
7785                throw new IllegalArgumentException("null uri");
7786            }
7787
7788            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7789                    modeFlags, owner, targetUserId);
7790        }
7791    }
7792
7793    /**
7794     * @param uri This uri must NOT contain an embedded userId.
7795     * @param userId The userId in which the uri is to be resolved.
7796     */
7797    @Override
7798    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7799        synchronized(this) {
7800            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7801            if (owner == null) {
7802                throw new IllegalArgumentException("Unknown owner: " + token);
7803            }
7804
7805            if (uri == null) {
7806                owner.removeUriPermissionsLocked(mode);
7807            } else {
7808                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7809            }
7810        }
7811    }
7812
7813    private void schedulePersistUriGrants() {
7814        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7815            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7816                    10 * DateUtils.SECOND_IN_MILLIS);
7817        }
7818    }
7819
7820    private void writeGrantedUriPermissions() {
7821        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7822
7823        // Snapshot permissions so we can persist without lock
7824        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7825        synchronized (this) {
7826            final int size = mGrantedUriPermissions.size();
7827            for (int i = 0; i < size; i++) {
7828                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7829                for (UriPermission perm : perms.values()) {
7830                    if (perm.persistedModeFlags != 0) {
7831                        persist.add(perm.snapshot());
7832                    }
7833                }
7834            }
7835        }
7836
7837        FileOutputStream fos = null;
7838        try {
7839            fos = mGrantFile.startWrite();
7840
7841            XmlSerializer out = new FastXmlSerializer();
7842            out.setOutput(fos, "utf-8");
7843            out.startDocument(null, true);
7844            out.startTag(null, TAG_URI_GRANTS);
7845            for (UriPermission.Snapshot perm : persist) {
7846                out.startTag(null, TAG_URI_GRANT);
7847                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7848                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7849                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7850                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7851                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7852                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7853                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7854                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7855                out.endTag(null, TAG_URI_GRANT);
7856            }
7857            out.endTag(null, TAG_URI_GRANTS);
7858            out.endDocument();
7859
7860            mGrantFile.finishWrite(fos);
7861        } catch (IOException e) {
7862            if (fos != null) {
7863                mGrantFile.failWrite(fos);
7864            }
7865        }
7866    }
7867
7868    private void readGrantedUriPermissionsLocked() {
7869        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7870
7871        final long now = System.currentTimeMillis();
7872
7873        FileInputStream fis = null;
7874        try {
7875            fis = mGrantFile.openRead();
7876            final XmlPullParser in = Xml.newPullParser();
7877            in.setInput(fis, null);
7878
7879            int type;
7880            while ((type = in.next()) != END_DOCUMENT) {
7881                final String tag = in.getName();
7882                if (type == START_TAG) {
7883                    if (TAG_URI_GRANT.equals(tag)) {
7884                        final int sourceUserId;
7885                        final int targetUserId;
7886                        final int userHandle = readIntAttribute(in,
7887                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7888                        if (userHandle != UserHandle.USER_NULL) {
7889                            // For backwards compatibility.
7890                            sourceUserId = userHandle;
7891                            targetUserId = userHandle;
7892                        } else {
7893                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7894                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7895                        }
7896                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7897                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7898                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7899                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7900                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7901                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7902
7903                        // Sanity check that provider still belongs to source package
7904                        final ProviderInfo pi = getProviderInfoLocked(
7905                                uri.getAuthority(), sourceUserId);
7906                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7907                            int targetUid = -1;
7908                            try {
7909                                targetUid = AppGlobals.getPackageManager()
7910                                        .getPackageUid(targetPkg, targetUserId);
7911                            } catch (RemoteException e) {
7912                            }
7913                            if (targetUid != -1) {
7914                                final UriPermission perm = findOrCreateUriPermissionLocked(
7915                                        sourcePkg, targetPkg, targetUid,
7916                                        new GrantUri(sourceUserId, uri, prefix));
7917                                perm.initPersistedModes(modeFlags, createdTime);
7918                            }
7919                        } else {
7920                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7921                                    + " but instead found " + pi);
7922                        }
7923                    }
7924                }
7925            }
7926        } catch (FileNotFoundException e) {
7927            // Missing grants is okay
7928        } catch (IOException e) {
7929            Slog.wtf(TAG, "Failed reading Uri grants", e);
7930        } catch (XmlPullParserException e) {
7931            Slog.wtf(TAG, "Failed reading Uri grants", e);
7932        } finally {
7933            IoUtils.closeQuietly(fis);
7934        }
7935    }
7936
7937    /**
7938     * @param uri This uri must NOT contain an embedded userId.
7939     * @param userId The userId in which the uri is to be resolved.
7940     */
7941    @Override
7942    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7943        enforceNotIsolatedCaller("takePersistableUriPermission");
7944
7945        Preconditions.checkFlagsArgument(modeFlags,
7946                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7947
7948        synchronized (this) {
7949            final int callingUid = Binder.getCallingUid();
7950            boolean persistChanged = false;
7951            GrantUri grantUri = new GrantUri(userId, uri, false);
7952
7953            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7954                    new GrantUri(userId, uri, false));
7955            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7956                    new GrantUri(userId, uri, true));
7957
7958            final boolean exactValid = (exactPerm != null)
7959                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7960            final boolean prefixValid = (prefixPerm != null)
7961                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7962
7963            if (!(exactValid || prefixValid)) {
7964                throw new SecurityException("No persistable permission grants found for UID "
7965                        + callingUid + " and Uri " + grantUri.toSafeString());
7966            }
7967
7968            if (exactValid) {
7969                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7970            }
7971            if (prefixValid) {
7972                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7973            }
7974
7975            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7976
7977            if (persistChanged) {
7978                schedulePersistUriGrants();
7979            }
7980        }
7981    }
7982
7983    /**
7984     * @param uri This uri must NOT contain an embedded userId.
7985     * @param userId The userId in which the uri is to be resolved.
7986     */
7987    @Override
7988    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7989        enforceNotIsolatedCaller("releasePersistableUriPermission");
7990
7991        Preconditions.checkFlagsArgument(modeFlags,
7992                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7993
7994        synchronized (this) {
7995            final int callingUid = Binder.getCallingUid();
7996            boolean persistChanged = false;
7997
7998            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7999                    new GrantUri(userId, uri, false));
8000            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8001                    new GrantUri(userId, uri, true));
8002            if (exactPerm == null && prefixPerm == null) {
8003                throw new SecurityException("No permission grants found for UID " + callingUid
8004                        + " and Uri " + uri.toSafeString());
8005            }
8006
8007            if (exactPerm != null) {
8008                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8009                removeUriPermissionIfNeededLocked(exactPerm);
8010            }
8011            if (prefixPerm != null) {
8012                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8013                removeUriPermissionIfNeededLocked(prefixPerm);
8014            }
8015
8016            if (persistChanged) {
8017                schedulePersistUriGrants();
8018            }
8019        }
8020    }
8021
8022    /**
8023     * Prune any older {@link UriPermission} for the given UID until outstanding
8024     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8025     *
8026     * @return if any mutations occured that require persisting.
8027     */
8028    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8029        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8030        if (perms == null) return false;
8031        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8032
8033        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8034        for (UriPermission perm : perms.values()) {
8035            if (perm.persistedModeFlags != 0) {
8036                persisted.add(perm);
8037            }
8038        }
8039
8040        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8041        if (trimCount <= 0) return false;
8042
8043        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8044        for (int i = 0; i < trimCount; i++) {
8045            final UriPermission perm = persisted.get(i);
8046
8047            if (DEBUG_URI_PERMISSION) {
8048                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
8049            }
8050
8051            perm.releasePersistableModes(~0);
8052            removeUriPermissionIfNeededLocked(perm);
8053        }
8054
8055        return true;
8056    }
8057
8058    @Override
8059    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8060            String packageName, boolean incoming) {
8061        enforceNotIsolatedCaller("getPersistedUriPermissions");
8062        Preconditions.checkNotNull(packageName, "packageName");
8063
8064        final int callingUid = Binder.getCallingUid();
8065        final IPackageManager pm = AppGlobals.getPackageManager();
8066        try {
8067            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8068            if (packageUid != callingUid) {
8069                throw new SecurityException(
8070                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8071            }
8072        } catch (RemoteException e) {
8073            throw new SecurityException("Failed to verify package name ownership");
8074        }
8075
8076        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8077        synchronized (this) {
8078            if (incoming) {
8079                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8080                        callingUid);
8081                if (perms == null) {
8082                    Slog.w(TAG, "No permission grants found for " + packageName);
8083                } else {
8084                    for (UriPermission perm : perms.values()) {
8085                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8086                            result.add(perm.buildPersistedPublicApiObject());
8087                        }
8088                    }
8089                }
8090            } else {
8091                final int size = mGrantedUriPermissions.size();
8092                for (int i = 0; i < size; i++) {
8093                    final ArrayMap<GrantUri, UriPermission> perms =
8094                            mGrantedUriPermissions.valueAt(i);
8095                    for (UriPermission perm : perms.values()) {
8096                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8097                            result.add(perm.buildPersistedPublicApiObject());
8098                        }
8099                    }
8100                }
8101            }
8102        }
8103        return new ParceledListSlice<android.content.UriPermission>(result);
8104    }
8105
8106    @Override
8107    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8108        synchronized (this) {
8109            ProcessRecord app =
8110                who != null ? getRecordForAppLocked(who) : null;
8111            if (app == null) return;
8112
8113            Message msg = Message.obtain();
8114            msg.what = WAIT_FOR_DEBUGGER_MSG;
8115            msg.obj = app;
8116            msg.arg1 = waiting ? 1 : 0;
8117            mHandler.sendMessage(msg);
8118        }
8119    }
8120
8121    @Override
8122    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8123        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8124        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8125        outInfo.availMem = Process.getFreeMemory();
8126        outInfo.totalMem = Process.getTotalMemory();
8127        outInfo.threshold = homeAppMem;
8128        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8129        outInfo.hiddenAppThreshold = cachedAppMem;
8130        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8131                ProcessList.SERVICE_ADJ);
8132        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8133                ProcessList.VISIBLE_APP_ADJ);
8134        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8135                ProcessList.FOREGROUND_APP_ADJ);
8136    }
8137
8138    // =========================================================
8139    // TASK MANAGEMENT
8140    // =========================================================
8141
8142    @Override
8143    public List<IAppTask> getAppTasks(String callingPackage) {
8144        int callingUid = Binder.getCallingUid();
8145        long ident = Binder.clearCallingIdentity();
8146
8147        synchronized(this) {
8148            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8149            try {
8150                if (localLOGV) Slog.v(TAG, "getAppTasks");
8151
8152                final int N = mRecentTasks.size();
8153                for (int i = 0; i < N; i++) {
8154                    TaskRecord tr = mRecentTasks.get(i);
8155                    // Skip tasks that do not match the caller.  We don't need to verify
8156                    // callingPackage, because we are also limiting to callingUid and know
8157                    // that will limit to the correct security sandbox.
8158                    if (tr.effectiveUid != callingUid) {
8159                        continue;
8160                    }
8161                    Intent intent = tr.getBaseIntent();
8162                    if (intent == null ||
8163                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8164                        continue;
8165                    }
8166                    ActivityManager.RecentTaskInfo taskInfo =
8167                            createRecentTaskInfoFromTaskRecord(tr);
8168                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8169                    list.add(taskImpl);
8170                }
8171            } finally {
8172                Binder.restoreCallingIdentity(ident);
8173            }
8174            return list;
8175        }
8176    }
8177
8178    @Override
8179    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8180        final int callingUid = Binder.getCallingUid();
8181        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8182
8183        synchronized(this) {
8184            if (localLOGV) Slog.v(
8185                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8186
8187            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8188                    callingUid);
8189
8190            // TODO: Improve with MRU list from all ActivityStacks.
8191            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8192        }
8193
8194        return list;
8195    }
8196
8197    TaskRecord getMostRecentTask() {
8198        return mRecentTasks.get(0);
8199    }
8200
8201    /**
8202     * Creates a new RecentTaskInfo from a TaskRecord.
8203     */
8204    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8205        // Update the task description to reflect any changes in the task stack
8206        tr.updateTaskDescription();
8207
8208        // Compose the recent task info
8209        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8210        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8211        rti.persistentId = tr.taskId;
8212        rti.baseIntent = new Intent(tr.getBaseIntent());
8213        rti.origActivity = tr.origActivity;
8214        rti.description = tr.lastDescription;
8215        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8216        rti.userId = tr.userId;
8217        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8218        rti.firstActiveTime = tr.firstActiveTime;
8219        rti.lastActiveTime = tr.lastActiveTime;
8220        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8221        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8222        return rti;
8223    }
8224
8225    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8226        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8227                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8228        if (!allowed) {
8229            if (checkPermission(android.Manifest.permission.GET_TASKS,
8230                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8231                // Temporary compatibility: some existing apps on the system image may
8232                // still be requesting the old permission and not switched to the new
8233                // one; if so, we'll still allow them full access.  This means we need
8234                // to see if they are holding the old permission and are a system app.
8235                try {
8236                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8237                        allowed = true;
8238                        Slog.w(TAG, caller + ": caller " + callingUid
8239                                + " is using old GET_TASKS but privileged; allowing");
8240                    }
8241                } catch (RemoteException e) {
8242                }
8243            }
8244        }
8245        if (!allowed) {
8246            Slog.w(TAG, caller + ": caller " + callingUid
8247                    + " does not hold GET_TASKS; limiting output");
8248        }
8249        return allowed;
8250    }
8251
8252    @Override
8253    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8254        final int callingUid = Binder.getCallingUid();
8255        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8256                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8257
8258        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8259        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8260        synchronized (this) {
8261            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8262                    callingUid);
8263            final boolean detailed = checkCallingPermission(
8264                    android.Manifest.permission.GET_DETAILED_TASKS)
8265                    == PackageManager.PERMISSION_GRANTED;
8266
8267            final int N = mRecentTasks.size();
8268            ArrayList<ActivityManager.RecentTaskInfo> res
8269                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8270                            maxNum < N ? maxNum : N);
8271
8272            final Set<Integer> includedUsers;
8273            if (includeProfiles) {
8274                includedUsers = getProfileIdsLocked(userId);
8275            } else {
8276                includedUsers = new HashSet<Integer>();
8277            }
8278            includedUsers.add(Integer.valueOf(userId));
8279
8280            for (int i=0; i<N && maxNum > 0; i++) {
8281                TaskRecord tr = mRecentTasks.get(i);
8282                // Only add calling user or related users recent tasks
8283                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8284                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8285                    continue;
8286                }
8287
8288                // Return the entry if desired by the caller.  We always return
8289                // the first entry, because callers always expect this to be the
8290                // foreground app.  We may filter others if the caller has
8291                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8292                // we should exclude the entry.
8293
8294                if (i == 0
8295                        || withExcluded
8296                        || (tr.intent == null)
8297                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8298                                == 0)) {
8299                    if (!allowed) {
8300                        // If the caller doesn't have the GET_TASKS permission, then only
8301                        // allow them to see a small subset of tasks -- their own and home.
8302                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8303                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8304                            continue;
8305                        }
8306                    }
8307                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8308                        if (tr.stack != null && tr.stack.isHomeStack()) {
8309                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8310                            continue;
8311                        }
8312                    }
8313                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8314                        // Don't include auto remove tasks that are finished or finishing.
8315                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8316                                + tr);
8317                        continue;
8318                    }
8319                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8320                            && !tr.isAvailable) {
8321                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8322                        continue;
8323                    }
8324
8325                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8326                    if (!detailed) {
8327                        rti.baseIntent.replaceExtras((Bundle)null);
8328                    }
8329
8330                    res.add(rti);
8331                    maxNum--;
8332                }
8333            }
8334            return res;
8335        }
8336    }
8337
8338    private TaskRecord recentTaskForIdLocked(int id) {
8339        final int N = mRecentTasks.size();
8340            for (int i=0; i<N; i++) {
8341                TaskRecord tr = mRecentTasks.get(i);
8342                if (tr.taskId == id) {
8343                    return tr;
8344                }
8345            }
8346            return null;
8347    }
8348
8349    @Override
8350    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8351        synchronized (this) {
8352            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8353                    "getTaskThumbnail()");
8354            TaskRecord tr = recentTaskForIdLocked(id);
8355            if (tr != null) {
8356                return tr.getTaskThumbnailLocked();
8357            }
8358        }
8359        return null;
8360    }
8361
8362    @Override
8363    public int addAppTask(IBinder activityToken, Intent intent,
8364            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8365        final int callingUid = Binder.getCallingUid();
8366        final long callingIdent = Binder.clearCallingIdentity();
8367
8368        try {
8369            synchronized (this) {
8370                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8371                if (r == null) {
8372                    throw new IllegalArgumentException("Activity does not exist; token="
8373                            + activityToken);
8374                }
8375                ComponentName comp = intent.getComponent();
8376                if (comp == null) {
8377                    throw new IllegalArgumentException("Intent " + intent
8378                            + " must specify explicit component");
8379                }
8380                if (thumbnail.getWidth() != mThumbnailWidth
8381                        || thumbnail.getHeight() != mThumbnailHeight) {
8382                    throw new IllegalArgumentException("Bad thumbnail size: got "
8383                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8384                            + mThumbnailWidth + "x" + mThumbnailHeight);
8385                }
8386                if (intent.getSelector() != null) {
8387                    intent.setSelector(null);
8388                }
8389                if (intent.getSourceBounds() != null) {
8390                    intent.setSourceBounds(null);
8391                }
8392                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8393                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8394                        // The caller has added this as an auto-remove task...  that makes no
8395                        // sense, so turn off auto-remove.
8396                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8397                    }
8398                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8399                    // Must be a new task.
8400                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8401                }
8402                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8403                    mLastAddedTaskActivity = null;
8404                }
8405                ActivityInfo ainfo = mLastAddedTaskActivity;
8406                if (ainfo == null) {
8407                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8408                            comp, 0, UserHandle.getUserId(callingUid));
8409                    if (ainfo.applicationInfo.uid != callingUid) {
8410                        throw new SecurityException(
8411                                "Can't add task for another application: target uid="
8412                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8413                    }
8414                }
8415
8416                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8417                        intent, description);
8418
8419                int trimIdx = trimRecentsForTask(task, false);
8420                if (trimIdx >= 0) {
8421                    // If this would have caused a trim, then we'll abort because that
8422                    // means it would be added at the end of the list but then just removed.
8423                    return -1;
8424                }
8425
8426                final int N = mRecentTasks.size();
8427                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8428                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8429                    tr.removedFromRecents(mTaskPersister);
8430                }
8431
8432                task.inRecents = true;
8433                mRecentTasks.add(task);
8434                r.task.stack.addTask(task, false, false);
8435
8436                task.setLastThumbnail(thumbnail);
8437                task.freeLastThumbnail();
8438
8439                return task.taskId;
8440            }
8441        } finally {
8442            Binder.restoreCallingIdentity(callingIdent);
8443        }
8444    }
8445
8446    @Override
8447    public Point getAppTaskThumbnailSize() {
8448        synchronized (this) {
8449            return new Point(mThumbnailWidth,  mThumbnailHeight);
8450        }
8451    }
8452
8453    @Override
8454    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8455        synchronized (this) {
8456            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8457            if (r != null) {
8458                r.setTaskDescription(td);
8459                r.task.updateTaskDescription();
8460            }
8461        }
8462    }
8463
8464    @Override
8465    public Bitmap getTaskDescriptionIcon(String filename) {
8466        if (!FileUtils.isValidExtFilename(filename)
8467                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8468            throw new IllegalArgumentException("Bad filename: " + filename);
8469        }
8470        return mTaskPersister.getTaskDescriptionIcon(filename);
8471    }
8472
8473    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8474        mRecentTasks.remove(tr);
8475        tr.removedFromRecents(mTaskPersister);
8476        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8477        Intent baseIntent = new Intent(
8478                tr.intent != null ? tr.intent : tr.affinityIntent);
8479        ComponentName component = baseIntent.getComponent();
8480        if (component == null) {
8481            Slog.w(TAG, "Now component for base intent of task: " + tr);
8482            return;
8483        }
8484
8485        // Find any running services associated with this app.
8486        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8487
8488        if (killProcesses) {
8489            // Find any running processes associated with this app.
8490            final String pkg = component.getPackageName();
8491            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8492            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8493            for (int i=0; i<pmap.size(); i++) {
8494                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8495                for (int j=0; j<uids.size(); j++) {
8496                    ProcessRecord proc = uids.valueAt(j);
8497                    if (proc.userId != tr.userId) {
8498                        continue;
8499                    }
8500                    if (!proc.pkgList.containsKey(pkg)) {
8501                        continue;
8502                    }
8503                    procs.add(proc);
8504                }
8505            }
8506
8507            // Kill the running processes.
8508            for (int i=0; i<procs.size(); i++) {
8509                ProcessRecord pr = procs.get(i);
8510                if (pr == mHomeProcess) {
8511                    // Don't kill the home process along with tasks from the same package.
8512                    continue;
8513                }
8514                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8515                    pr.kill("remove task", true);
8516                } else {
8517                    pr.waitingToKill = "remove task";
8518                }
8519            }
8520        }
8521    }
8522
8523    /**
8524     * Removes the task with the specified task id.
8525     *
8526     * @param taskId Identifier of the task to be removed.
8527     * @param flags Additional operational flags.  May be 0 or
8528     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8529     * @return Returns true if the given task was found and removed.
8530     */
8531    private boolean removeTaskByIdLocked(int taskId, int flags) {
8532        TaskRecord tr = recentTaskForIdLocked(taskId);
8533        if (tr != null) {
8534            tr.removeTaskActivitiesLocked();
8535            cleanUpRemovedTaskLocked(tr, flags);
8536            if (tr.isPersistable) {
8537                notifyTaskPersisterLocked(null, true);
8538            }
8539            return true;
8540        }
8541        return false;
8542    }
8543
8544    @Override
8545    public boolean removeTask(int taskId, int flags) {
8546        synchronized (this) {
8547            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8548                    "removeTask()");
8549            long ident = Binder.clearCallingIdentity();
8550            try {
8551                return removeTaskByIdLocked(taskId, flags);
8552            } finally {
8553                Binder.restoreCallingIdentity(ident);
8554            }
8555        }
8556    }
8557
8558    /**
8559     * TODO: Add mController hook
8560     */
8561    @Override
8562    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8563        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8564                "moveTaskToFront()");
8565
8566        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8567        synchronized(this) {
8568            moveTaskToFrontLocked(taskId, flags, options);
8569        }
8570    }
8571
8572    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8573        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8574                Binder.getCallingUid(), -1, -1, "Task to front")) {
8575            ActivityOptions.abort(options);
8576            return;
8577        }
8578        final long origId = Binder.clearCallingIdentity();
8579        try {
8580            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8581            if (task == null) {
8582                return;
8583            }
8584            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8585                mStackSupervisor.showLockTaskToast();
8586                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8587                return;
8588            }
8589            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8590            if (prev != null && prev.isRecentsActivity()) {
8591                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8592            }
8593            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8594        } finally {
8595            Binder.restoreCallingIdentity(origId);
8596        }
8597        ActivityOptions.abort(options);
8598    }
8599
8600    @Override
8601    public void moveTaskToBack(int taskId) {
8602        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8603                "moveTaskToBack()");
8604
8605        synchronized(this) {
8606            TaskRecord tr = recentTaskForIdLocked(taskId);
8607            if (tr != null) {
8608                if (tr == mStackSupervisor.mLockTaskModeTask) {
8609                    mStackSupervisor.showLockTaskToast();
8610                    return;
8611                }
8612                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8613                ActivityStack stack = tr.stack;
8614                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8615                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8616                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8617                        return;
8618                    }
8619                }
8620                final long origId = Binder.clearCallingIdentity();
8621                try {
8622                    stack.moveTaskToBackLocked(taskId, null);
8623                } finally {
8624                    Binder.restoreCallingIdentity(origId);
8625                }
8626            }
8627        }
8628    }
8629
8630    /**
8631     * Moves an activity, and all of the other activities within the same task, to the bottom
8632     * of the history stack.  The activity's order within the task is unchanged.
8633     *
8634     * @param token A reference to the activity we wish to move
8635     * @param nonRoot If false then this only works if the activity is the root
8636     *                of a task; if true it will work for any activity in a task.
8637     * @return Returns true if the move completed, false if not.
8638     */
8639    @Override
8640    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8641        enforceNotIsolatedCaller("moveActivityTaskToBack");
8642        synchronized(this) {
8643            final long origId = Binder.clearCallingIdentity();
8644            try {
8645                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8646                if (taskId >= 0) {
8647                    if ((mStackSupervisor.mLockTaskModeTask != null)
8648                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8649                        mStackSupervisor.showLockTaskToast();
8650                        return false;
8651                    }
8652                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8653                }
8654            } finally {
8655                Binder.restoreCallingIdentity(origId);
8656            }
8657        }
8658        return false;
8659    }
8660
8661    @Override
8662    public void moveTaskBackwards(int task) {
8663        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8664                "moveTaskBackwards()");
8665
8666        synchronized(this) {
8667            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8668                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8669                return;
8670            }
8671            final long origId = Binder.clearCallingIdentity();
8672            moveTaskBackwardsLocked(task);
8673            Binder.restoreCallingIdentity(origId);
8674        }
8675    }
8676
8677    private final void moveTaskBackwardsLocked(int task) {
8678        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8679    }
8680
8681    @Override
8682    public IBinder getHomeActivityToken() throws RemoteException {
8683        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8684                "getHomeActivityToken()");
8685        synchronized (this) {
8686            return mStackSupervisor.getHomeActivityToken();
8687        }
8688    }
8689
8690    @Override
8691    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8692            IActivityContainerCallback callback) throws RemoteException {
8693        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8694                "createActivityContainer()");
8695        synchronized (this) {
8696            if (parentActivityToken == null) {
8697                throw new IllegalArgumentException("parent token must not be null");
8698            }
8699            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8700            if (r == null) {
8701                return null;
8702            }
8703            if (callback == null) {
8704                throw new IllegalArgumentException("callback must not be null");
8705            }
8706            return mStackSupervisor.createActivityContainer(r, callback);
8707        }
8708    }
8709
8710    @Override
8711    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8712        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8713                "deleteActivityContainer()");
8714        synchronized (this) {
8715            mStackSupervisor.deleteActivityContainer(container);
8716        }
8717    }
8718
8719    @Override
8720    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8721            throws RemoteException {
8722        synchronized (this) {
8723            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8724            if (stack != null) {
8725                return stack.mActivityContainer;
8726            }
8727            return null;
8728        }
8729    }
8730
8731    @Override
8732    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8733        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8734                "moveTaskToStack()");
8735        if (stackId == HOME_STACK_ID) {
8736            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8737                    new RuntimeException("here").fillInStackTrace());
8738        }
8739        synchronized (this) {
8740            long ident = Binder.clearCallingIdentity();
8741            try {
8742                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8743                        + stackId + " toTop=" + toTop);
8744                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8745            } finally {
8746                Binder.restoreCallingIdentity(ident);
8747            }
8748        }
8749    }
8750
8751    @Override
8752    public void resizeStack(int stackBoxId, Rect bounds) {
8753        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8754                "resizeStackBox()");
8755        long ident = Binder.clearCallingIdentity();
8756        try {
8757            mWindowManager.resizeStack(stackBoxId, bounds);
8758        } finally {
8759            Binder.restoreCallingIdentity(ident);
8760        }
8761    }
8762
8763    @Override
8764    public List<StackInfo> getAllStackInfos() {
8765        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8766                "getAllStackInfos()");
8767        long ident = Binder.clearCallingIdentity();
8768        try {
8769            synchronized (this) {
8770                return mStackSupervisor.getAllStackInfosLocked();
8771            }
8772        } finally {
8773            Binder.restoreCallingIdentity(ident);
8774        }
8775    }
8776
8777    @Override
8778    public StackInfo getStackInfo(int stackId) {
8779        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8780                "getStackInfo()");
8781        long ident = Binder.clearCallingIdentity();
8782        try {
8783            synchronized (this) {
8784                return mStackSupervisor.getStackInfoLocked(stackId);
8785            }
8786        } finally {
8787            Binder.restoreCallingIdentity(ident);
8788        }
8789    }
8790
8791    @Override
8792    public boolean isInHomeStack(int taskId) {
8793        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8794                "getStackInfo()");
8795        long ident = Binder.clearCallingIdentity();
8796        try {
8797            synchronized (this) {
8798                TaskRecord tr = recentTaskForIdLocked(taskId);
8799                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8800            }
8801        } finally {
8802            Binder.restoreCallingIdentity(ident);
8803        }
8804    }
8805
8806    @Override
8807    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8808        synchronized(this) {
8809            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8810        }
8811    }
8812
8813    private boolean isLockTaskAuthorized(String pkg) {
8814        final DevicePolicyManager dpm = (DevicePolicyManager)
8815                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8816        try {
8817            int uid = mContext.getPackageManager().getPackageUid(pkg,
8818                    Binder.getCallingUserHandle().getIdentifier());
8819            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8820        } catch (NameNotFoundException e) {
8821            return false;
8822        }
8823    }
8824
8825    void startLockTaskMode(TaskRecord task) {
8826        final String pkg;
8827        synchronized (this) {
8828            pkg = task.intent.getComponent().getPackageName();
8829        }
8830        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8831        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8832            final TaskRecord taskRecord = task;
8833            mHandler.post(new Runnable() {
8834                @Override
8835                public void run() {
8836                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8837                }
8838            });
8839            return;
8840        }
8841        long ident = Binder.clearCallingIdentity();
8842        try {
8843            synchronized (this) {
8844                // Since we lost lock on task, make sure it is still there.
8845                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8846                if (task != null) {
8847                    if (!isSystemInitiated
8848                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8849                        throw new IllegalArgumentException("Invalid task, not in foreground");
8850                    }
8851                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8852                }
8853            }
8854        } finally {
8855            Binder.restoreCallingIdentity(ident);
8856        }
8857    }
8858
8859    @Override
8860    public void startLockTaskMode(int taskId) {
8861        final TaskRecord task;
8862        long ident = Binder.clearCallingIdentity();
8863        try {
8864            synchronized (this) {
8865                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8866            }
8867        } finally {
8868            Binder.restoreCallingIdentity(ident);
8869        }
8870        if (task != null) {
8871            startLockTaskMode(task);
8872        }
8873    }
8874
8875    @Override
8876    public void startLockTaskMode(IBinder token) {
8877        final TaskRecord task;
8878        long ident = Binder.clearCallingIdentity();
8879        try {
8880            synchronized (this) {
8881                final ActivityRecord r = ActivityRecord.forToken(token);
8882                if (r == null) {
8883                    return;
8884                }
8885                task = r.task;
8886            }
8887        } finally {
8888            Binder.restoreCallingIdentity(ident);
8889        }
8890        if (task != null) {
8891            startLockTaskMode(task);
8892        }
8893    }
8894
8895    @Override
8896    public void startLockTaskModeOnCurrent() throws RemoteException {
8897        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8898                "startLockTaskModeOnCurrent");
8899        ActivityRecord r = null;
8900        synchronized (this) {
8901            r = mStackSupervisor.topRunningActivityLocked();
8902        }
8903        startLockTaskMode(r.task);
8904    }
8905
8906    @Override
8907    public void stopLockTaskMode() {
8908        // Verify that the user matches the package of the intent for the TaskRecord
8909        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8910        // and stopLockTaskMode.
8911        final int callingUid = Binder.getCallingUid();
8912        if (callingUid != Process.SYSTEM_UID) {
8913            try {
8914                String pkg =
8915                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8916                int uid = mContext.getPackageManager().getPackageUid(pkg,
8917                        Binder.getCallingUserHandle().getIdentifier());
8918                if (uid != callingUid) {
8919                    throw new SecurityException("Invalid uid, expected " + uid);
8920                }
8921            } catch (NameNotFoundException e) {
8922                Log.d(TAG, "stopLockTaskMode " + e);
8923                return;
8924            }
8925        }
8926        long ident = Binder.clearCallingIdentity();
8927        try {
8928            Log.d(TAG, "stopLockTaskMode");
8929            // Stop lock task
8930            synchronized (this) {
8931                mStackSupervisor.setLockTaskModeLocked(null, false);
8932            }
8933        } finally {
8934            Binder.restoreCallingIdentity(ident);
8935        }
8936    }
8937
8938    @Override
8939    public void stopLockTaskModeOnCurrent() throws RemoteException {
8940        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8941                "stopLockTaskModeOnCurrent");
8942        long ident = Binder.clearCallingIdentity();
8943        try {
8944            stopLockTaskMode();
8945        } finally {
8946            Binder.restoreCallingIdentity(ident);
8947        }
8948    }
8949
8950    @Override
8951    public boolean isInLockTaskMode() {
8952        synchronized (this) {
8953            return mStackSupervisor.isInLockTaskMode();
8954        }
8955    }
8956
8957    // =========================================================
8958    // CONTENT PROVIDERS
8959    // =========================================================
8960
8961    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8962        List<ProviderInfo> providers = null;
8963        try {
8964            providers = AppGlobals.getPackageManager().
8965                queryContentProviders(app.processName, app.uid,
8966                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8967        } catch (RemoteException ex) {
8968        }
8969        if (DEBUG_MU)
8970            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8971        int userId = app.userId;
8972        if (providers != null) {
8973            int N = providers.size();
8974            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8975            for (int i=0; i<N; i++) {
8976                ProviderInfo cpi =
8977                    (ProviderInfo)providers.get(i);
8978                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8979                        cpi.name, cpi.flags);
8980                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8981                    // This is a singleton provider, but a user besides the
8982                    // default user is asking to initialize a process it runs
8983                    // in...  well, no, it doesn't actually run in this process,
8984                    // it runs in the process of the default user.  Get rid of it.
8985                    providers.remove(i);
8986                    N--;
8987                    i--;
8988                    continue;
8989                }
8990
8991                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8992                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8993                if (cpr == null) {
8994                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8995                    mProviderMap.putProviderByClass(comp, cpr);
8996                }
8997                if (DEBUG_MU)
8998                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8999                app.pubProviders.put(cpi.name, cpr);
9000                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9001                    // Don't add this if it is a platform component that is marked
9002                    // to run in multiple processes, because this is actually
9003                    // part of the framework so doesn't make sense to track as a
9004                    // separate apk in the process.
9005                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9006                            mProcessStats);
9007                }
9008                ensurePackageDexOpt(cpi.applicationInfo.packageName);
9009            }
9010        }
9011        return providers;
9012    }
9013
9014    /**
9015     * Check if {@link ProcessRecord} has a possible chance at accessing the
9016     * given {@link ProviderInfo}. Final permission checking is always done
9017     * in {@link ContentProvider}.
9018     */
9019    private final String checkContentProviderPermissionLocked(
9020            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9021        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9022        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9023        boolean checkedGrants = false;
9024        if (checkUser) {
9025            // Looking for cross-user grants before enforcing the typical cross-users permissions
9026            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
9027            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9028                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9029                    return null;
9030                }
9031                checkedGrants = true;
9032            }
9033            userId = handleIncomingUser(callingPid, callingUid, userId,
9034                    false, ALLOW_NON_FULL,
9035                    "checkContentProviderPermissionLocked " + cpi.authority, null);
9036            if (userId != tmpTargetUserId) {
9037                // When we actually went to determine the final targer user ID, this ended
9038                // up different than our initial check for the authority.  This is because
9039                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9040                // SELF.  So we need to re-check the grants again.
9041                checkedGrants = false;
9042            }
9043        }
9044        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9045                cpi.applicationInfo.uid, cpi.exported)
9046                == PackageManager.PERMISSION_GRANTED) {
9047            return null;
9048        }
9049        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9050                cpi.applicationInfo.uid, cpi.exported)
9051                == PackageManager.PERMISSION_GRANTED) {
9052            return null;
9053        }
9054
9055        PathPermission[] pps = cpi.pathPermissions;
9056        if (pps != null) {
9057            int i = pps.length;
9058            while (i > 0) {
9059                i--;
9060                PathPermission pp = pps[i];
9061                String pprperm = pp.getReadPermission();
9062                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9063                        cpi.applicationInfo.uid, cpi.exported)
9064                        == PackageManager.PERMISSION_GRANTED) {
9065                    return null;
9066                }
9067                String ppwperm = pp.getWritePermission();
9068                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9069                        cpi.applicationInfo.uid, cpi.exported)
9070                        == PackageManager.PERMISSION_GRANTED) {
9071                    return null;
9072                }
9073            }
9074        }
9075        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9076            return null;
9077        }
9078
9079        String msg;
9080        if (!cpi.exported) {
9081            msg = "Permission Denial: opening provider " + cpi.name
9082                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9083                    + ", uid=" + callingUid + ") that is not exported from uid "
9084                    + cpi.applicationInfo.uid;
9085        } else {
9086            msg = "Permission Denial: opening provider " + cpi.name
9087                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9088                    + ", uid=" + callingUid + ") requires "
9089                    + cpi.readPermission + " or " + cpi.writePermission;
9090        }
9091        Slog.w(TAG, msg);
9092        return msg;
9093    }
9094
9095    /**
9096     * Returns if the ContentProvider has granted a uri to callingUid
9097     */
9098    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9099        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9100        if (perms != null) {
9101            for (int i=perms.size()-1; i>=0; i--) {
9102                GrantUri grantUri = perms.keyAt(i);
9103                if (grantUri.sourceUserId == userId || !checkUser) {
9104                    if (matchesProvider(grantUri.uri, cpi)) {
9105                        return true;
9106                    }
9107                }
9108            }
9109        }
9110        return false;
9111    }
9112
9113    /**
9114     * Returns true if the uri authority is one of the authorities specified in the provider.
9115     */
9116    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9117        String uriAuth = uri.getAuthority();
9118        String cpiAuth = cpi.authority;
9119        if (cpiAuth.indexOf(';') == -1) {
9120            return cpiAuth.equals(uriAuth);
9121        }
9122        String[] cpiAuths = cpiAuth.split(";");
9123        int length = cpiAuths.length;
9124        for (int i = 0; i < length; i++) {
9125            if (cpiAuths[i].equals(uriAuth)) return true;
9126        }
9127        return false;
9128    }
9129
9130    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9131            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9132        if (r != null) {
9133            for (int i=0; i<r.conProviders.size(); i++) {
9134                ContentProviderConnection conn = r.conProviders.get(i);
9135                if (conn.provider == cpr) {
9136                    if (DEBUG_PROVIDER) Slog.v(TAG,
9137                            "Adding provider requested by "
9138                            + r.processName + " from process "
9139                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9140                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9141                    if (stable) {
9142                        conn.stableCount++;
9143                        conn.numStableIncs++;
9144                    } else {
9145                        conn.unstableCount++;
9146                        conn.numUnstableIncs++;
9147                    }
9148                    return conn;
9149                }
9150            }
9151            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9152            if (stable) {
9153                conn.stableCount = 1;
9154                conn.numStableIncs = 1;
9155            } else {
9156                conn.unstableCount = 1;
9157                conn.numUnstableIncs = 1;
9158            }
9159            cpr.connections.add(conn);
9160            r.conProviders.add(conn);
9161            return conn;
9162        }
9163        cpr.addExternalProcessHandleLocked(externalProcessToken);
9164        return null;
9165    }
9166
9167    boolean decProviderCountLocked(ContentProviderConnection conn,
9168            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9169        if (conn != null) {
9170            cpr = conn.provider;
9171            if (DEBUG_PROVIDER) Slog.v(TAG,
9172                    "Removing provider requested by "
9173                    + conn.client.processName + " from process "
9174                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9175                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9176            if (stable) {
9177                conn.stableCount--;
9178            } else {
9179                conn.unstableCount--;
9180            }
9181            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9182                cpr.connections.remove(conn);
9183                conn.client.conProviders.remove(conn);
9184                return true;
9185            }
9186            return false;
9187        }
9188        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9189        return false;
9190    }
9191
9192    private void checkTime(long startTime, String where) {
9193        long now = SystemClock.elapsedRealtime();
9194        if ((now-startTime) > 1000) {
9195            // If we are taking more than a second, log about it.
9196            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9197        }
9198    }
9199
9200    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9201            String name, IBinder token, boolean stable, int userId) {
9202        ContentProviderRecord cpr;
9203        ContentProviderConnection conn = null;
9204        ProviderInfo cpi = null;
9205
9206        synchronized(this) {
9207            long startTime = SystemClock.elapsedRealtime();
9208
9209            ProcessRecord r = null;
9210            if (caller != null) {
9211                r = getRecordForAppLocked(caller);
9212                if (r == null) {
9213                    throw new SecurityException(
9214                            "Unable to find app for caller " + caller
9215                          + " (pid=" + Binder.getCallingPid()
9216                          + ") when getting content provider " + name);
9217                }
9218            }
9219
9220            boolean checkCrossUser = true;
9221
9222            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9223
9224            // First check if this content provider has been published...
9225            cpr = mProviderMap.getProviderByName(name, userId);
9226            // If that didn't work, check if it exists for user 0 and then
9227            // verify that it's a singleton provider before using it.
9228            if (cpr == null && userId != UserHandle.USER_OWNER) {
9229                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9230                if (cpr != null) {
9231                    cpi = cpr.info;
9232                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9233                            cpi.name, cpi.flags)
9234                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9235                        userId = UserHandle.USER_OWNER;
9236                        checkCrossUser = false;
9237                    } else {
9238                        cpr = null;
9239                        cpi = null;
9240                    }
9241                }
9242            }
9243
9244            boolean providerRunning = cpr != null;
9245            if (providerRunning) {
9246                cpi = cpr.info;
9247                String msg;
9248                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9249                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9250                        != null) {
9251                    throw new SecurityException(msg);
9252                }
9253                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9254
9255                if (r != null && cpr.canRunHere(r)) {
9256                    // This provider has been published or is in the process
9257                    // of being published...  but it is also allowed to run
9258                    // in the caller's process, so don't make a connection
9259                    // and just let the caller instantiate its own instance.
9260                    ContentProviderHolder holder = cpr.newHolder(null);
9261                    // don't give caller the provider object, it needs
9262                    // to make its own.
9263                    holder.provider = null;
9264                    return holder;
9265                }
9266
9267                final long origId = Binder.clearCallingIdentity();
9268
9269                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9270
9271                // In this case the provider instance already exists, so we can
9272                // return it right away.
9273                conn = incProviderCountLocked(r, cpr, token, stable);
9274                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9275                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9276                        // If this is a perceptible app accessing the provider,
9277                        // make sure to count it as being accessed and thus
9278                        // back up on the LRU list.  This is good because
9279                        // content providers are often expensive to start.
9280                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9281                        updateLruProcessLocked(cpr.proc, false, null);
9282                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9283                    }
9284                }
9285
9286                if (cpr.proc != null) {
9287                    if (false) {
9288                        if (cpr.name.flattenToShortString().equals(
9289                                "com.android.providers.calendar/.CalendarProvider2")) {
9290                            Slog.v(TAG, "****************** KILLING "
9291                                + cpr.name.flattenToShortString());
9292                            Process.killProcess(cpr.proc.pid);
9293                        }
9294                    }
9295                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9296                    boolean success = updateOomAdjLocked(cpr.proc);
9297                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9298                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9299                    // NOTE: there is still a race here where a signal could be
9300                    // pending on the process even though we managed to update its
9301                    // adj level.  Not sure what to do about this, but at least
9302                    // the race is now smaller.
9303                    if (!success) {
9304                        // Uh oh...  it looks like the provider's process
9305                        // has been killed on us.  We need to wait for a new
9306                        // process to be started, and make sure its death
9307                        // doesn't kill our process.
9308                        Slog.i(TAG,
9309                                "Existing provider " + cpr.name.flattenToShortString()
9310                                + " is crashing; detaching " + r);
9311                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9312                        checkTime(startTime, "getContentProviderImpl: before appDied");
9313                        appDiedLocked(cpr.proc);
9314                        checkTime(startTime, "getContentProviderImpl: after appDied");
9315                        if (!lastRef) {
9316                            // This wasn't the last ref our process had on
9317                            // the provider...  we have now been killed, bail.
9318                            return null;
9319                        }
9320                        providerRunning = false;
9321                        conn = null;
9322                    }
9323                }
9324
9325                Binder.restoreCallingIdentity(origId);
9326            }
9327
9328            boolean singleton;
9329            if (!providerRunning) {
9330                try {
9331                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9332                    cpi = AppGlobals.getPackageManager().
9333                        resolveContentProvider(name,
9334                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9335                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9336                } catch (RemoteException ex) {
9337                }
9338                if (cpi == null) {
9339                    return null;
9340                }
9341                // If the provider is a singleton AND
9342                // (it's a call within the same user || the provider is a
9343                // privileged app)
9344                // Then allow connecting to the singleton provider
9345                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9346                        cpi.name, cpi.flags)
9347                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9348                if (singleton) {
9349                    userId = UserHandle.USER_OWNER;
9350                }
9351                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9352                checkTime(startTime, "getContentProviderImpl: got app info for user");
9353
9354                String msg;
9355                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9356                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9357                        != null) {
9358                    throw new SecurityException(msg);
9359                }
9360                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9361
9362                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9363                        && !cpi.processName.equals("system")) {
9364                    // If this content provider does not run in the system
9365                    // process, and the system is not yet ready to run other
9366                    // processes, then fail fast instead of hanging.
9367                    throw new IllegalArgumentException(
9368                            "Attempt to launch content provider before system ready");
9369                }
9370
9371                // Make sure that the user who owns this provider is started.  If not,
9372                // we don't want to allow it to run.
9373                if (mStartedUsers.get(userId) == null) {
9374                    Slog.w(TAG, "Unable to launch app "
9375                            + cpi.applicationInfo.packageName + "/"
9376                            + cpi.applicationInfo.uid + " for provider "
9377                            + name + ": user " + userId + " is stopped");
9378                    return null;
9379                }
9380
9381                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9382                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9383                cpr = mProviderMap.getProviderByClass(comp, userId);
9384                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9385                final boolean firstClass = cpr == null;
9386                if (firstClass) {
9387                    final long ident = Binder.clearCallingIdentity();
9388                    try {
9389                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9390                        ApplicationInfo ai =
9391                            AppGlobals.getPackageManager().
9392                                getApplicationInfo(
9393                                        cpi.applicationInfo.packageName,
9394                                        STOCK_PM_FLAGS, userId);
9395                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9396                        if (ai == null) {
9397                            Slog.w(TAG, "No package info for content provider "
9398                                    + cpi.name);
9399                            return null;
9400                        }
9401                        ai = getAppInfoForUser(ai, userId);
9402                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9403                    } catch (RemoteException ex) {
9404                        // pm is in same process, this will never happen.
9405                    } finally {
9406                        Binder.restoreCallingIdentity(ident);
9407                    }
9408                }
9409
9410                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9411
9412                if (r != null && cpr.canRunHere(r)) {
9413                    // If this is a multiprocess provider, then just return its
9414                    // info and allow the caller to instantiate it.  Only do
9415                    // this if the provider is the same user as the caller's
9416                    // process, or can run as root (so can be in any process).
9417                    return cpr.newHolder(null);
9418                }
9419
9420                if (DEBUG_PROVIDER) {
9421                    RuntimeException e = new RuntimeException("here");
9422                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9423                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9424                }
9425
9426                // This is single process, and our app is now connecting to it.
9427                // See if we are already in the process of launching this
9428                // provider.
9429                final int N = mLaunchingProviders.size();
9430                int i;
9431                for (i=0; i<N; i++) {
9432                    if (mLaunchingProviders.get(i) == cpr) {
9433                        break;
9434                    }
9435                }
9436
9437                // If the provider is not already being launched, then get it
9438                // started.
9439                if (i >= N) {
9440                    final long origId = Binder.clearCallingIdentity();
9441
9442                    try {
9443                        // Content provider is now in use, its package can't be stopped.
9444                        try {
9445                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9446                            AppGlobals.getPackageManager().setPackageStoppedState(
9447                                    cpr.appInfo.packageName, false, userId);
9448                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9449                        } catch (RemoteException e) {
9450                        } catch (IllegalArgumentException e) {
9451                            Slog.w(TAG, "Failed trying to unstop package "
9452                                    + cpr.appInfo.packageName + ": " + e);
9453                        }
9454
9455                        // Use existing process if already started
9456                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9457                        ProcessRecord proc = getProcessRecordLocked(
9458                                cpi.processName, cpr.appInfo.uid, false);
9459                        if (proc != null && proc.thread != null) {
9460                            if (DEBUG_PROVIDER) {
9461                                Slog.d(TAG, "Installing in existing process " + proc);
9462                            }
9463                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9464                            proc.pubProviders.put(cpi.name, cpr);
9465                            try {
9466                                proc.thread.scheduleInstallProvider(cpi);
9467                            } catch (RemoteException e) {
9468                            }
9469                        } else {
9470                            checkTime(startTime, "getContentProviderImpl: before start process");
9471                            proc = startProcessLocked(cpi.processName,
9472                                    cpr.appInfo, false, 0, "content provider",
9473                                    new ComponentName(cpi.applicationInfo.packageName,
9474                                            cpi.name), false, false, false);
9475                            checkTime(startTime, "getContentProviderImpl: after start process");
9476                            if (proc == null) {
9477                                Slog.w(TAG, "Unable to launch app "
9478                                        + cpi.applicationInfo.packageName + "/"
9479                                        + cpi.applicationInfo.uid + " for provider "
9480                                        + name + ": process is bad");
9481                                return null;
9482                            }
9483                        }
9484                        cpr.launchingApp = proc;
9485                        mLaunchingProviders.add(cpr);
9486                    } finally {
9487                        Binder.restoreCallingIdentity(origId);
9488                    }
9489                }
9490
9491                checkTime(startTime, "getContentProviderImpl: updating data structures");
9492
9493                // Make sure the provider is published (the same provider class
9494                // may be published under multiple names).
9495                if (firstClass) {
9496                    mProviderMap.putProviderByClass(comp, cpr);
9497                }
9498
9499                mProviderMap.putProviderByName(name, cpr);
9500                conn = incProviderCountLocked(r, cpr, token, stable);
9501                if (conn != null) {
9502                    conn.waiting = true;
9503                }
9504            }
9505            checkTime(startTime, "getContentProviderImpl: done!");
9506        }
9507
9508        // Wait for the provider to be published...
9509        synchronized (cpr) {
9510            while (cpr.provider == null) {
9511                if (cpr.launchingApp == null) {
9512                    Slog.w(TAG, "Unable to launch app "
9513                            + cpi.applicationInfo.packageName + "/"
9514                            + cpi.applicationInfo.uid + " for provider "
9515                            + name + ": launching app became null");
9516                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9517                            UserHandle.getUserId(cpi.applicationInfo.uid),
9518                            cpi.applicationInfo.packageName,
9519                            cpi.applicationInfo.uid, name);
9520                    return null;
9521                }
9522                try {
9523                    if (DEBUG_MU) {
9524                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9525                                + cpr.launchingApp);
9526                    }
9527                    if (conn != null) {
9528                        conn.waiting = true;
9529                    }
9530                    cpr.wait();
9531                } catch (InterruptedException ex) {
9532                } finally {
9533                    if (conn != null) {
9534                        conn.waiting = false;
9535                    }
9536                }
9537            }
9538        }
9539        return cpr != null ? cpr.newHolder(conn) : null;
9540    }
9541
9542    @Override
9543    public final ContentProviderHolder getContentProvider(
9544            IApplicationThread caller, String name, int userId, boolean stable) {
9545        enforceNotIsolatedCaller("getContentProvider");
9546        if (caller == null) {
9547            String msg = "null IApplicationThread when getting content provider "
9548                    + name;
9549            Slog.w(TAG, msg);
9550            throw new SecurityException(msg);
9551        }
9552        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9553        // with cross-user grant.
9554        return getContentProviderImpl(caller, name, null, stable, userId);
9555    }
9556
9557    public ContentProviderHolder getContentProviderExternal(
9558            String name, int userId, IBinder token) {
9559        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9560            "Do not have permission in call getContentProviderExternal()");
9561        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9562                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9563        return getContentProviderExternalUnchecked(name, token, userId);
9564    }
9565
9566    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9567            IBinder token, int userId) {
9568        return getContentProviderImpl(null, name, token, true, userId);
9569    }
9570
9571    /**
9572     * Drop a content provider from a ProcessRecord's bookkeeping
9573     */
9574    public void removeContentProvider(IBinder connection, boolean stable) {
9575        enforceNotIsolatedCaller("removeContentProvider");
9576        long ident = Binder.clearCallingIdentity();
9577        try {
9578            synchronized (this) {
9579                ContentProviderConnection conn;
9580                try {
9581                    conn = (ContentProviderConnection)connection;
9582                } catch (ClassCastException e) {
9583                    String msg ="removeContentProvider: " + connection
9584                            + " not a ContentProviderConnection";
9585                    Slog.w(TAG, msg);
9586                    throw new IllegalArgumentException(msg);
9587                }
9588                if (conn == null) {
9589                    throw new NullPointerException("connection is null");
9590                }
9591                if (decProviderCountLocked(conn, null, null, stable)) {
9592                    updateOomAdjLocked();
9593                }
9594            }
9595        } finally {
9596            Binder.restoreCallingIdentity(ident);
9597        }
9598    }
9599
9600    public void removeContentProviderExternal(String name, IBinder token) {
9601        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9602            "Do not have permission in call removeContentProviderExternal()");
9603        int userId = UserHandle.getCallingUserId();
9604        long ident = Binder.clearCallingIdentity();
9605        try {
9606            removeContentProviderExternalUnchecked(name, token, userId);
9607        } finally {
9608            Binder.restoreCallingIdentity(ident);
9609        }
9610    }
9611
9612    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9613        synchronized (this) {
9614            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9615            if(cpr == null) {
9616                //remove from mProvidersByClass
9617                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9618                return;
9619            }
9620
9621            //update content provider record entry info
9622            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9623            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9624            if (localCpr.hasExternalProcessHandles()) {
9625                if (localCpr.removeExternalProcessHandleLocked(token)) {
9626                    updateOomAdjLocked();
9627                } else {
9628                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9629                            + " with no external reference for token: "
9630                            + token + ".");
9631                }
9632            } else {
9633                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9634                        + " with no external references.");
9635            }
9636        }
9637    }
9638
9639    public final void publishContentProviders(IApplicationThread caller,
9640            List<ContentProviderHolder> providers) {
9641        if (providers == null) {
9642            return;
9643        }
9644
9645        enforceNotIsolatedCaller("publishContentProviders");
9646        synchronized (this) {
9647            final ProcessRecord r = getRecordForAppLocked(caller);
9648            if (DEBUG_MU)
9649                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9650            if (r == null) {
9651                throw new SecurityException(
9652                        "Unable to find app for caller " + caller
9653                      + " (pid=" + Binder.getCallingPid()
9654                      + ") when publishing content providers");
9655            }
9656
9657            final long origId = Binder.clearCallingIdentity();
9658
9659            final int N = providers.size();
9660            for (int i=0; i<N; i++) {
9661                ContentProviderHolder src = providers.get(i);
9662                if (src == null || src.info == null || src.provider == null) {
9663                    continue;
9664                }
9665                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9666                if (DEBUG_MU)
9667                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9668                if (dst != null) {
9669                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9670                    mProviderMap.putProviderByClass(comp, dst);
9671                    String names[] = dst.info.authority.split(";");
9672                    for (int j = 0; j < names.length; j++) {
9673                        mProviderMap.putProviderByName(names[j], dst);
9674                    }
9675
9676                    int NL = mLaunchingProviders.size();
9677                    int j;
9678                    for (j=0; j<NL; j++) {
9679                        if (mLaunchingProviders.get(j) == dst) {
9680                            mLaunchingProviders.remove(j);
9681                            j--;
9682                            NL--;
9683                        }
9684                    }
9685                    synchronized (dst) {
9686                        dst.provider = src.provider;
9687                        dst.proc = r;
9688                        dst.notifyAll();
9689                    }
9690                    updateOomAdjLocked(r);
9691                }
9692            }
9693
9694            Binder.restoreCallingIdentity(origId);
9695        }
9696    }
9697
9698    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9699        ContentProviderConnection conn;
9700        try {
9701            conn = (ContentProviderConnection)connection;
9702        } catch (ClassCastException e) {
9703            String msg ="refContentProvider: " + connection
9704                    + " not a ContentProviderConnection";
9705            Slog.w(TAG, msg);
9706            throw new IllegalArgumentException(msg);
9707        }
9708        if (conn == null) {
9709            throw new NullPointerException("connection is null");
9710        }
9711
9712        synchronized (this) {
9713            if (stable > 0) {
9714                conn.numStableIncs += stable;
9715            }
9716            stable = conn.stableCount + stable;
9717            if (stable < 0) {
9718                throw new IllegalStateException("stableCount < 0: " + stable);
9719            }
9720
9721            if (unstable > 0) {
9722                conn.numUnstableIncs += unstable;
9723            }
9724            unstable = conn.unstableCount + unstable;
9725            if (unstable < 0) {
9726                throw new IllegalStateException("unstableCount < 0: " + unstable);
9727            }
9728
9729            if ((stable+unstable) <= 0) {
9730                throw new IllegalStateException("ref counts can't go to zero here: stable="
9731                        + stable + " unstable=" + unstable);
9732            }
9733            conn.stableCount = stable;
9734            conn.unstableCount = unstable;
9735            return !conn.dead;
9736        }
9737    }
9738
9739    public void unstableProviderDied(IBinder connection) {
9740        ContentProviderConnection conn;
9741        try {
9742            conn = (ContentProviderConnection)connection;
9743        } catch (ClassCastException e) {
9744            String msg ="refContentProvider: " + connection
9745                    + " not a ContentProviderConnection";
9746            Slog.w(TAG, msg);
9747            throw new IllegalArgumentException(msg);
9748        }
9749        if (conn == null) {
9750            throw new NullPointerException("connection is null");
9751        }
9752
9753        // Safely retrieve the content provider associated with the connection.
9754        IContentProvider provider;
9755        synchronized (this) {
9756            provider = conn.provider.provider;
9757        }
9758
9759        if (provider == null) {
9760            // Um, yeah, we're way ahead of you.
9761            return;
9762        }
9763
9764        // Make sure the caller is being honest with us.
9765        if (provider.asBinder().pingBinder()) {
9766            // Er, no, still looks good to us.
9767            synchronized (this) {
9768                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9769                        + " says " + conn + " died, but we don't agree");
9770                return;
9771            }
9772        }
9773
9774        // Well look at that!  It's dead!
9775        synchronized (this) {
9776            if (conn.provider.provider != provider) {
9777                // But something changed...  good enough.
9778                return;
9779            }
9780
9781            ProcessRecord proc = conn.provider.proc;
9782            if (proc == null || proc.thread == null) {
9783                // Seems like the process is already cleaned up.
9784                return;
9785            }
9786
9787            // As far as we're concerned, this is just like receiving a
9788            // death notification...  just a bit prematurely.
9789            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9790                    + ") early provider death");
9791            final long ident = Binder.clearCallingIdentity();
9792            try {
9793                appDiedLocked(proc);
9794            } finally {
9795                Binder.restoreCallingIdentity(ident);
9796            }
9797        }
9798    }
9799
9800    @Override
9801    public void appNotRespondingViaProvider(IBinder connection) {
9802        enforceCallingPermission(
9803                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9804
9805        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9806        if (conn == null) {
9807            Slog.w(TAG, "ContentProviderConnection is null");
9808            return;
9809        }
9810
9811        final ProcessRecord host = conn.provider.proc;
9812        if (host == null) {
9813            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9814            return;
9815        }
9816
9817        final long token = Binder.clearCallingIdentity();
9818        try {
9819            appNotResponding(host, null, null, false, "ContentProvider not responding");
9820        } finally {
9821            Binder.restoreCallingIdentity(token);
9822        }
9823    }
9824
9825    public final void installSystemProviders() {
9826        List<ProviderInfo> providers;
9827        synchronized (this) {
9828            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9829            providers = generateApplicationProvidersLocked(app);
9830            if (providers != null) {
9831                for (int i=providers.size()-1; i>=0; i--) {
9832                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9833                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9834                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9835                                + ": not system .apk");
9836                        providers.remove(i);
9837                    }
9838                }
9839            }
9840        }
9841        if (providers != null) {
9842            mSystemThread.installSystemProviders(providers);
9843        }
9844
9845        mCoreSettingsObserver = new CoreSettingsObserver(this);
9846
9847        //mUsageStatsService.monitorPackages();
9848    }
9849
9850    /**
9851     * Allows apps to retrieve the MIME type of a URI.
9852     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9853     * users, then it does not need permission to access the ContentProvider.
9854     * Either, it needs cross-user uri grants.
9855     *
9856     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9857     *
9858     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9859     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9860     */
9861    public String getProviderMimeType(Uri uri, int userId) {
9862        enforceNotIsolatedCaller("getProviderMimeType");
9863        final String name = uri.getAuthority();
9864        int callingUid = Binder.getCallingUid();
9865        int callingPid = Binder.getCallingPid();
9866        long ident = 0;
9867        boolean clearedIdentity = false;
9868        userId = unsafeConvertIncomingUser(userId);
9869        if (canClearIdentity(callingPid, callingUid, userId)) {
9870            clearedIdentity = true;
9871            ident = Binder.clearCallingIdentity();
9872        }
9873        ContentProviderHolder holder = null;
9874        try {
9875            holder = getContentProviderExternalUnchecked(name, null, userId);
9876            if (holder != null) {
9877                return holder.provider.getType(uri);
9878            }
9879        } catch (RemoteException e) {
9880            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9881            return null;
9882        } finally {
9883            // We need to clear the identity to call removeContentProviderExternalUnchecked
9884            if (!clearedIdentity) {
9885                ident = Binder.clearCallingIdentity();
9886            }
9887            try {
9888                if (holder != null) {
9889                    removeContentProviderExternalUnchecked(name, null, userId);
9890                }
9891            } finally {
9892                Binder.restoreCallingIdentity(ident);
9893            }
9894        }
9895
9896        return null;
9897    }
9898
9899    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9900        if (UserHandle.getUserId(callingUid) == userId) {
9901            return true;
9902        }
9903        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9904                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9905                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9906                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9907                return true;
9908        }
9909        return false;
9910    }
9911
9912    // =========================================================
9913    // GLOBAL MANAGEMENT
9914    // =========================================================
9915
9916    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9917            boolean isolated, int isolatedUid) {
9918        String proc = customProcess != null ? customProcess : info.processName;
9919        BatteryStatsImpl.Uid.Proc ps = null;
9920        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9921        int uid = info.uid;
9922        if (isolated) {
9923            if (isolatedUid == 0) {
9924                int userId = UserHandle.getUserId(uid);
9925                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9926                while (true) {
9927                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9928                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9929                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9930                    }
9931                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9932                    mNextIsolatedProcessUid++;
9933                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9934                        // No process for this uid, use it.
9935                        break;
9936                    }
9937                    stepsLeft--;
9938                    if (stepsLeft <= 0) {
9939                        return null;
9940                    }
9941                }
9942            } else {
9943                // Special case for startIsolatedProcess (internal only), where
9944                // the uid of the isolated process is specified by the caller.
9945                uid = isolatedUid;
9946            }
9947        }
9948        return new ProcessRecord(stats, info, proc, uid);
9949    }
9950
9951    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9952            String abiOverride) {
9953        ProcessRecord app;
9954        if (!isolated) {
9955            app = getProcessRecordLocked(info.processName, info.uid, true);
9956        } else {
9957            app = null;
9958        }
9959
9960        if (app == null) {
9961            app = newProcessRecordLocked(info, null, isolated, 0);
9962            mProcessNames.put(info.processName, app.uid, app);
9963            if (isolated) {
9964                mIsolatedProcesses.put(app.uid, app);
9965            }
9966            updateLruProcessLocked(app, false, null);
9967            updateOomAdjLocked();
9968        }
9969
9970        // This package really, really can not be stopped.
9971        try {
9972            AppGlobals.getPackageManager().setPackageStoppedState(
9973                    info.packageName, false, UserHandle.getUserId(app.uid));
9974        } catch (RemoteException e) {
9975        } catch (IllegalArgumentException e) {
9976            Slog.w(TAG, "Failed trying to unstop package "
9977                    + info.packageName + ": " + e);
9978        }
9979
9980        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9981                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9982            app.persistent = true;
9983            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9984        }
9985        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9986            mPersistentStartingProcesses.add(app);
9987            startProcessLocked(app, "added application", app.processName, abiOverride,
9988                    null /* entryPoint */, null /* entryPointArgs */);
9989        }
9990
9991        return app;
9992    }
9993
9994    public void unhandledBack() {
9995        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9996                "unhandledBack()");
9997
9998        synchronized(this) {
9999            final long origId = Binder.clearCallingIdentity();
10000            try {
10001                getFocusedStack().unhandledBackLocked();
10002            } finally {
10003                Binder.restoreCallingIdentity(origId);
10004            }
10005        }
10006    }
10007
10008    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10009        enforceNotIsolatedCaller("openContentUri");
10010        final int userId = UserHandle.getCallingUserId();
10011        String name = uri.getAuthority();
10012        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10013        ParcelFileDescriptor pfd = null;
10014        if (cph != null) {
10015            // We record the binder invoker's uid in thread-local storage before
10016            // going to the content provider to open the file.  Later, in the code
10017            // that handles all permissions checks, we look for this uid and use
10018            // that rather than the Activity Manager's own uid.  The effect is that
10019            // we do the check against the caller's permissions even though it looks
10020            // to the content provider like the Activity Manager itself is making
10021            // the request.
10022            sCallerIdentity.set(new Identity(
10023                    Binder.getCallingPid(), Binder.getCallingUid()));
10024            try {
10025                pfd = cph.provider.openFile(null, uri, "r", null);
10026            } catch (FileNotFoundException e) {
10027                // do nothing; pfd will be returned null
10028            } finally {
10029                // Ensure that whatever happens, we clean up the identity state
10030                sCallerIdentity.remove();
10031            }
10032
10033            // We've got the fd now, so we're done with the provider.
10034            removeContentProviderExternalUnchecked(name, null, userId);
10035        } else {
10036            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10037        }
10038        return pfd;
10039    }
10040
10041    // Actually is sleeping or shutting down or whatever else in the future
10042    // is an inactive state.
10043    public boolean isSleepingOrShuttingDown() {
10044        return isSleeping() || mShuttingDown;
10045    }
10046
10047    public boolean isSleeping() {
10048        return mSleeping;
10049    }
10050
10051    void goingToSleep() {
10052        synchronized(this) {
10053            mWentToSleep = true;
10054            goToSleepIfNeededLocked();
10055        }
10056    }
10057
10058    void finishRunningVoiceLocked() {
10059        if (mRunningVoice) {
10060            mRunningVoice = false;
10061            goToSleepIfNeededLocked();
10062        }
10063    }
10064
10065    void goToSleepIfNeededLocked() {
10066        if (mWentToSleep && !mRunningVoice) {
10067            if (!mSleeping) {
10068                mSleeping = true;
10069                mStackSupervisor.goingToSleepLocked();
10070
10071                // Initialize the wake times of all processes.
10072                checkExcessivePowerUsageLocked(false);
10073                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10074                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10075                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10076            }
10077        }
10078    }
10079
10080    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10081        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10082            // Never persist the home stack.
10083            return;
10084        }
10085        mTaskPersister.wakeup(task, flush);
10086    }
10087
10088    @Override
10089    public boolean shutdown(int timeout) {
10090        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10091                != PackageManager.PERMISSION_GRANTED) {
10092            throw new SecurityException("Requires permission "
10093                    + android.Manifest.permission.SHUTDOWN);
10094        }
10095
10096        boolean timedout = false;
10097
10098        synchronized(this) {
10099            mShuttingDown = true;
10100            updateEventDispatchingLocked();
10101            timedout = mStackSupervisor.shutdownLocked(timeout);
10102        }
10103
10104        mAppOpsService.shutdown();
10105        if (mUsageStatsService != null) {
10106            mUsageStatsService.prepareShutdown();
10107        }
10108        mBatteryStatsService.shutdown();
10109        synchronized (this) {
10110            mProcessStats.shutdownLocked();
10111        }
10112        notifyTaskPersisterLocked(null, true);
10113
10114        return timedout;
10115    }
10116
10117    public final void activitySlept(IBinder token) {
10118        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10119
10120        final long origId = Binder.clearCallingIdentity();
10121
10122        synchronized (this) {
10123            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10124            if (r != null) {
10125                mStackSupervisor.activitySleptLocked(r);
10126            }
10127        }
10128
10129        Binder.restoreCallingIdentity(origId);
10130    }
10131
10132    void logLockScreen(String msg) {
10133        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
10134                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
10135                mWentToSleep + " mSleeping=" + mSleeping);
10136    }
10137
10138    private void comeOutOfSleepIfNeededLocked() {
10139        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
10140            if (mSleeping) {
10141                mSleeping = false;
10142                mStackSupervisor.comeOutOfSleepIfNeededLocked();
10143            }
10144        }
10145    }
10146
10147    void wakingUp() {
10148        synchronized(this) {
10149            mWentToSleep = false;
10150            comeOutOfSleepIfNeededLocked();
10151        }
10152    }
10153
10154    void startRunningVoiceLocked() {
10155        if (!mRunningVoice) {
10156            mRunningVoice = true;
10157            comeOutOfSleepIfNeededLocked();
10158        }
10159    }
10160
10161    private void updateEventDispatchingLocked() {
10162        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10163    }
10164
10165    public void setLockScreenShown(boolean shown) {
10166        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10167                != PackageManager.PERMISSION_GRANTED) {
10168            throw new SecurityException("Requires permission "
10169                    + android.Manifest.permission.DEVICE_POWER);
10170        }
10171
10172        synchronized(this) {
10173            long ident = Binder.clearCallingIdentity();
10174            try {
10175                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10176                mLockScreenShown = shown;
10177                comeOutOfSleepIfNeededLocked();
10178            } finally {
10179                Binder.restoreCallingIdentity(ident);
10180            }
10181        }
10182    }
10183
10184    @Override
10185    public void stopAppSwitches() {
10186        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10187                != PackageManager.PERMISSION_GRANTED) {
10188            throw new SecurityException("Requires permission "
10189                    + android.Manifest.permission.STOP_APP_SWITCHES);
10190        }
10191
10192        synchronized(this) {
10193            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10194                    + APP_SWITCH_DELAY_TIME;
10195            mDidAppSwitch = false;
10196            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10197            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10198            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10199        }
10200    }
10201
10202    public void resumeAppSwitches() {
10203        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10204                != PackageManager.PERMISSION_GRANTED) {
10205            throw new SecurityException("Requires permission "
10206                    + android.Manifest.permission.STOP_APP_SWITCHES);
10207        }
10208
10209        synchronized(this) {
10210            // Note that we don't execute any pending app switches... we will
10211            // let those wait until either the timeout, or the next start
10212            // activity request.
10213            mAppSwitchesAllowedTime = 0;
10214        }
10215    }
10216
10217    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10218            int callingPid, int callingUid, String name) {
10219        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10220            return true;
10221        }
10222
10223        int perm = checkComponentPermission(
10224                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10225                sourceUid, -1, true);
10226        if (perm == PackageManager.PERMISSION_GRANTED) {
10227            return true;
10228        }
10229
10230        // If the actual IPC caller is different from the logical source, then
10231        // also see if they are allowed to control app switches.
10232        if (callingUid != -1 && callingUid != sourceUid) {
10233            perm = checkComponentPermission(
10234                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10235                    callingUid, -1, true);
10236            if (perm == PackageManager.PERMISSION_GRANTED) {
10237                return true;
10238            }
10239        }
10240
10241        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10242        return false;
10243    }
10244
10245    public void setDebugApp(String packageName, boolean waitForDebugger,
10246            boolean persistent) {
10247        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10248                "setDebugApp()");
10249
10250        long ident = Binder.clearCallingIdentity();
10251        try {
10252            // Note that this is not really thread safe if there are multiple
10253            // callers into it at the same time, but that's not a situation we
10254            // care about.
10255            if (persistent) {
10256                final ContentResolver resolver = mContext.getContentResolver();
10257                Settings.Global.putString(
10258                    resolver, Settings.Global.DEBUG_APP,
10259                    packageName);
10260                Settings.Global.putInt(
10261                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10262                    waitForDebugger ? 1 : 0);
10263            }
10264
10265            synchronized (this) {
10266                if (!persistent) {
10267                    mOrigDebugApp = mDebugApp;
10268                    mOrigWaitForDebugger = mWaitForDebugger;
10269                }
10270                mDebugApp = packageName;
10271                mWaitForDebugger = waitForDebugger;
10272                mDebugTransient = !persistent;
10273                if (packageName != null) {
10274                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10275                            false, UserHandle.USER_ALL, "set debug app");
10276                }
10277            }
10278        } finally {
10279            Binder.restoreCallingIdentity(ident);
10280        }
10281    }
10282
10283    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10284        synchronized (this) {
10285            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10286            if (!isDebuggable) {
10287                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10288                    throw new SecurityException("Process not debuggable: " + app.packageName);
10289                }
10290            }
10291
10292            mOpenGlTraceApp = processName;
10293        }
10294    }
10295
10296    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10297        synchronized (this) {
10298            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10299            if (!isDebuggable) {
10300                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10301                    throw new SecurityException("Process not debuggable: " + app.packageName);
10302                }
10303            }
10304            mProfileApp = processName;
10305            mProfileFile = profilerInfo.profileFile;
10306            if (mProfileFd != null) {
10307                try {
10308                    mProfileFd.close();
10309                } catch (IOException e) {
10310                }
10311                mProfileFd = null;
10312            }
10313            mProfileFd = profilerInfo.profileFd;
10314            mSamplingInterval = profilerInfo.samplingInterval;
10315            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10316            mProfileType = 0;
10317        }
10318    }
10319
10320    @Override
10321    public void setAlwaysFinish(boolean enabled) {
10322        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10323                "setAlwaysFinish()");
10324
10325        Settings.Global.putInt(
10326                mContext.getContentResolver(),
10327                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10328
10329        synchronized (this) {
10330            mAlwaysFinishActivities = enabled;
10331        }
10332    }
10333
10334    @Override
10335    public void setActivityController(IActivityController controller) {
10336        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10337                "setActivityController()");
10338        synchronized (this) {
10339            mController = controller;
10340            Watchdog.getInstance().setActivityController(controller);
10341        }
10342    }
10343
10344    @Override
10345    public void setUserIsMonkey(boolean userIsMonkey) {
10346        synchronized (this) {
10347            synchronized (mPidsSelfLocked) {
10348                final int callingPid = Binder.getCallingPid();
10349                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10350                if (precessRecord == null) {
10351                    throw new SecurityException("Unknown process: " + callingPid);
10352                }
10353                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10354                    throw new SecurityException("Only an instrumentation process "
10355                            + "with a UiAutomation can call setUserIsMonkey");
10356                }
10357            }
10358            mUserIsMonkey = userIsMonkey;
10359        }
10360    }
10361
10362    @Override
10363    public boolean isUserAMonkey() {
10364        synchronized (this) {
10365            // If there is a controller also implies the user is a monkey.
10366            return (mUserIsMonkey || mController != null);
10367        }
10368    }
10369
10370    public void requestBugReport() {
10371        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10372        SystemProperties.set("ctl.start", "bugreport");
10373    }
10374
10375    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10376        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10377    }
10378
10379    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10380        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10381            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10382        }
10383        return KEY_DISPATCHING_TIMEOUT;
10384    }
10385
10386    @Override
10387    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10388        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10389                != PackageManager.PERMISSION_GRANTED) {
10390            throw new SecurityException("Requires permission "
10391                    + android.Manifest.permission.FILTER_EVENTS);
10392        }
10393        ProcessRecord proc;
10394        long timeout;
10395        synchronized (this) {
10396            synchronized (mPidsSelfLocked) {
10397                proc = mPidsSelfLocked.get(pid);
10398            }
10399            timeout = getInputDispatchingTimeoutLocked(proc);
10400        }
10401
10402        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10403            return -1;
10404        }
10405
10406        return timeout;
10407    }
10408
10409    /**
10410     * Handle input dispatching timeouts.
10411     * Returns whether input dispatching should be aborted or not.
10412     */
10413    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10414            final ActivityRecord activity, final ActivityRecord parent,
10415            final boolean aboveSystem, String reason) {
10416        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10417                != PackageManager.PERMISSION_GRANTED) {
10418            throw new SecurityException("Requires permission "
10419                    + android.Manifest.permission.FILTER_EVENTS);
10420        }
10421
10422        final String annotation;
10423        if (reason == null) {
10424            annotation = "Input dispatching timed out";
10425        } else {
10426            annotation = "Input dispatching timed out (" + reason + ")";
10427        }
10428
10429        if (proc != null) {
10430            synchronized (this) {
10431                if (proc.debugging) {
10432                    return false;
10433                }
10434
10435                if (mDidDexOpt) {
10436                    // Give more time since we were dexopting.
10437                    mDidDexOpt = false;
10438                    return false;
10439                }
10440
10441                if (proc.instrumentationClass != null) {
10442                    Bundle info = new Bundle();
10443                    info.putString("shortMsg", "keyDispatchingTimedOut");
10444                    info.putString("longMsg", annotation);
10445                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10446                    return true;
10447                }
10448            }
10449            mHandler.post(new Runnable() {
10450                @Override
10451                public void run() {
10452                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10453                }
10454            });
10455        }
10456
10457        return true;
10458    }
10459
10460    public Bundle getAssistContextExtras(int requestType) {
10461        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10462                UserHandle.getCallingUserId());
10463        if (pae == null) {
10464            return null;
10465        }
10466        synchronized (pae) {
10467            while (!pae.haveResult) {
10468                try {
10469                    pae.wait();
10470                } catch (InterruptedException e) {
10471                }
10472            }
10473            if (pae.result != null) {
10474                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10475            }
10476        }
10477        synchronized (this) {
10478            mPendingAssistExtras.remove(pae);
10479            mHandler.removeCallbacks(pae);
10480        }
10481        return pae.extras;
10482    }
10483
10484    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10485            int userHandle) {
10486        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10487                "getAssistContextExtras()");
10488        PendingAssistExtras pae;
10489        Bundle extras = new Bundle();
10490        synchronized (this) {
10491            ActivityRecord activity = getFocusedStack().mResumedActivity;
10492            if (activity == null) {
10493                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10494                return null;
10495            }
10496            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10497            if (activity.app == null || activity.app.thread == null) {
10498                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10499                return null;
10500            }
10501            if (activity.app.pid == Binder.getCallingPid()) {
10502                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10503                return null;
10504            }
10505            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10506            try {
10507                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10508                        requestType);
10509                mPendingAssistExtras.add(pae);
10510                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10511            } catch (RemoteException e) {
10512                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10513                return null;
10514            }
10515            return pae;
10516        }
10517    }
10518
10519    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10520        PendingAssistExtras pae = (PendingAssistExtras)token;
10521        synchronized (pae) {
10522            pae.result = extras;
10523            pae.haveResult = true;
10524            pae.notifyAll();
10525            if (pae.intent == null) {
10526                // Caller is just waiting for the result.
10527                return;
10528            }
10529        }
10530
10531        // We are now ready to launch the assist activity.
10532        synchronized (this) {
10533            boolean exists = mPendingAssistExtras.remove(pae);
10534            mHandler.removeCallbacks(pae);
10535            if (!exists) {
10536                // Timed out.
10537                return;
10538            }
10539        }
10540        pae.intent.replaceExtras(extras);
10541        if (pae.hint != null) {
10542            pae.intent.putExtra(pae.hint, true);
10543        }
10544        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10545                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10546                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10547        closeSystemDialogs("assist");
10548        try {
10549            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10550        } catch (ActivityNotFoundException e) {
10551            Slog.w(TAG, "No activity to handle assist action.", e);
10552        }
10553    }
10554
10555    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10556        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10557    }
10558
10559    public void registerProcessObserver(IProcessObserver observer) {
10560        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10561                "registerProcessObserver()");
10562        synchronized (this) {
10563            mProcessObservers.register(observer);
10564        }
10565    }
10566
10567    @Override
10568    public void unregisterProcessObserver(IProcessObserver observer) {
10569        synchronized (this) {
10570            mProcessObservers.unregister(observer);
10571        }
10572    }
10573
10574    @Override
10575    public boolean convertFromTranslucent(IBinder token) {
10576        final long origId = Binder.clearCallingIdentity();
10577        try {
10578            synchronized (this) {
10579                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10580                if (r == null) {
10581                    return false;
10582                }
10583                final boolean translucentChanged = r.changeWindowTranslucency(true);
10584                if (translucentChanged) {
10585                    r.task.stack.releaseBackgroundResources();
10586                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10587                }
10588                mWindowManager.setAppFullscreen(token, true);
10589                return translucentChanged;
10590            }
10591        } finally {
10592            Binder.restoreCallingIdentity(origId);
10593        }
10594    }
10595
10596    @Override
10597    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10598        final long origId = Binder.clearCallingIdentity();
10599        try {
10600            synchronized (this) {
10601                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10602                if (r == null) {
10603                    return false;
10604                }
10605                int index = r.task.mActivities.lastIndexOf(r);
10606                if (index > 0) {
10607                    ActivityRecord under = r.task.mActivities.get(index - 1);
10608                    under.returningOptions = options;
10609                }
10610                final boolean translucentChanged = r.changeWindowTranslucency(false);
10611                if (translucentChanged) {
10612                    r.task.stack.convertToTranslucent(r);
10613                }
10614                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10615                mWindowManager.setAppFullscreen(token, false);
10616                return translucentChanged;
10617            }
10618        } finally {
10619            Binder.restoreCallingIdentity(origId);
10620        }
10621    }
10622
10623    @Override
10624    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10625        final long origId = Binder.clearCallingIdentity();
10626        try {
10627            synchronized (this) {
10628                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10629                if (r != null) {
10630                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10631                }
10632            }
10633            return false;
10634        } finally {
10635            Binder.restoreCallingIdentity(origId);
10636        }
10637    }
10638
10639    @Override
10640    public boolean isBackgroundVisibleBehind(IBinder token) {
10641        final long origId = Binder.clearCallingIdentity();
10642        try {
10643            synchronized (this) {
10644                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10645                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10646                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10647                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10648                return visible;
10649            }
10650        } finally {
10651            Binder.restoreCallingIdentity(origId);
10652        }
10653    }
10654
10655    @Override
10656    public ActivityOptions getActivityOptions(IBinder token) {
10657        final long origId = Binder.clearCallingIdentity();
10658        try {
10659            synchronized (this) {
10660                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10661                if (r != null) {
10662                    final ActivityOptions activityOptions = r.pendingOptions;
10663                    r.pendingOptions = null;
10664                    return activityOptions;
10665                }
10666                return null;
10667            }
10668        } finally {
10669            Binder.restoreCallingIdentity(origId);
10670        }
10671    }
10672
10673    @Override
10674    public void setImmersive(IBinder token, boolean immersive) {
10675        synchronized(this) {
10676            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10677            if (r == null) {
10678                throw new IllegalArgumentException();
10679            }
10680            r.immersive = immersive;
10681
10682            // update associated state if we're frontmost
10683            if (r == mFocusedActivity) {
10684                if (DEBUG_IMMERSIVE) {
10685                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10686                }
10687                applyUpdateLockStateLocked(r);
10688            }
10689        }
10690    }
10691
10692    @Override
10693    public boolean isImmersive(IBinder token) {
10694        synchronized (this) {
10695            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10696            if (r == null) {
10697                throw new IllegalArgumentException();
10698            }
10699            return r.immersive;
10700        }
10701    }
10702
10703    public boolean isTopActivityImmersive() {
10704        enforceNotIsolatedCaller("startActivity");
10705        synchronized (this) {
10706            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10707            return (r != null) ? r.immersive : false;
10708        }
10709    }
10710
10711    @Override
10712    public boolean isTopOfTask(IBinder token) {
10713        synchronized (this) {
10714            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10715            if (r == null) {
10716                throw new IllegalArgumentException();
10717            }
10718            return r.task.getTopActivity() == r;
10719        }
10720    }
10721
10722    public final void enterSafeMode() {
10723        synchronized(this) {
10724            // It only makes sense to do this before the system is ready
10725            // and started launching other packages.
10726            if (!mSystemReady) {
10727                try {
10728                    AppGlobals.getPackageManager().enterSafeMode();
10729                } catch (RemoteException e) {
10730                }
10731            }
10732
10733            mSafeMode = true;
10734        }
10735    }
10736
10737    public final void showSafeModeOverlay() {
10738        View v = LayoutInflater.from(mContext).inflate(
10739                com.android.internal.R.layout.safe_mode, null);
10740        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10741        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10742        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10743        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10744        lp.gravity = Gravity.BOTTOM | Gravity.START;
10745        lp.format = v.getBackground().getOpacity();
10746        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10747                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10748        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10749        ((WindowManager)mContext.getSystemService(
10750                Context.WINDOW_SERVICE)).addView(v, lp);
10751    }
10752
10753    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10754        if (!(sender instanceof PendingIntentRecord)) {
10755            return;
10756        }
10757        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10758        synchronized (stats) {
10759            if (mBatteryStatsService.isOnBattery()) {
10760                mBatteryStatsService.enforceCallingPermission();
10761                PendingIntentRecord rec = (PendingIntentRecord)sender;
10762                int MY_UID = Binder.getCallingUid();
10763                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10764                BatteryStatsImpl.Uid.Pkg pkg =
10765                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10766                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10767                pkg.incWakeupsLocked();
10768            }
10769        }
10770    }
10771
10772    public boolean killPids(int[] pids, String pReason, boolean secure) {
10773        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10774            throw new SecurityException("killPids only available to the system");
10775        }
10776        String reason = (pReason == null) ? "Unknown" : pReason;
10777        // XXX Note: don't acquire main activity lock here, because the window
10778        // manager calls in with its locks held.
10779
10780        boolean killed = false;
10781        synchronized (mPidsSelfLocked) {
10782            int[] types = new int[pids.length];
10783            int worstType = 0;
10784            for (int i=0; i<pids.length; i++) {
10785                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10786                if (proc != null) {
10787                    int type = proc.setAdj;
10788                    types[i] = type;
10789                    if (type > worstType) {
10790                        worstType = type;
10791                    }
10792                }
10793            }
10794
10795            // If the worst oom_adj is somewhere in the cached proc LRU range,
10796            // then constrain it so we will kill all cached procs.
10797            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10798                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10799                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10800            }
10801
10802            // If this is not a secure call, don't let it kill processes that
10803            // are important.
10804            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10805                worstType = ProcessList.SERVICE_ADJ;
10806            }
10807
10808            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10809            for (int i=0; i<pids.length; i++) {
10810                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10811                if (proc == null) {
10812                    continue;
10813                }
10814                int adj = proc.setAdj;
10815                if (adj >= worstType && !proc.killedByAm) {
10816                    proc.kill(reason, true);
10817                    killed = true;
10818                }
10819            }
10820        }
10821        return killed;
10822    }
10823
10824    @Override
10825    public void killUid(int uid, String reason) {
10826        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10827            throw new SecurityException("killUid only available to the system");
10828        }
10829        synchronized (this) {
10830            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10831                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10832                    reason != null ? reason : "kill uid");
10833        }
10834    }
10835
10836    @Override
10837    public boolean killProcessesBelowForeground(String reason) {
10838        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10839            throw new SecurityException("killProcessesBelowForeground() only available to system");
10840        }
10841
10842        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10843    }
10844
10845    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10846        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10847            throw new SecurityException("killProcessesBelowAdj() only available to system");
10848        }
10849
10850        boolean killed = false;
10851        synchronized (mPidsSelfLocked) {
10852            final int size = mPidsSelfLocked.size();
10853            for (int i = 0; i < size; i++) {
10854                final int pid = mPidsSelfLocked.keyAt(i);
10855                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10856                if (proc == null) continue;
10857
10858                final int adj = proc.setAdj;
10859                if (adj > belowAdj && !proc.killedByAm) {
10860                    proc.kill(reason, true);
10861                    killed = true;
10862                }
10863            }
10864        }
10865        return killed;
10866    }
10867
10868    @Override
10869    public void hang(final IBinder who, boolean allowRestart) {
10870        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10871                != PackageManager.PERMISSION_GRANTED) {
10872            throw new SecurityException("Requires permission "
10873                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10874        }
10875
10876        final IBinder.DeathRecipient death = new DeathRecipient() {
10877            @Override
10878            public void binderDied() {
10879                synchronized (this) {
10880                    notifyAll();
10881                }
10882            }
10883        };
10884
10885        try {
10886            who.linkToDeath(death, 0);
10887        } catch (RemoteException e) {
10888            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10889            return;
10890        }
10891
10892        synchronized (this) {
10893            Watchdog.getInstance().setAllowRestart(allowRestart);
10894            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10895            synchronized (death) {
10896                while (who.isBinderAlive()) {
10897                    try {
10898                        death.wait();
10899                    } catch (InterruptedException e) {
10900                    }
10901                }
10902            }
10903            Watchdog.getInstance().setAllowRestart(true);
10904        }
10905    }
10906
10907    @Override
10908    public void restart() {
10909        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10910                != PackageManager.PERMISSION_GRANTED) {
10911            throw new SecurityException("Requires permission "
10912                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10913        }
10914
10915        Log.i(TAG, "Sending shutdown broadcast...");
10916
10917        BroadcastReceiver br = new BroadcastReceiver() {
10918            @Override public void onReceive(Context context, Intent intent) {
10919                // Now the broadcast is done, finish up the low-level shutdown.
10920                Log.i(TAG, "Shutting down activity manager...");
10921                shutdown(10000);
10922                Log.i(TAG, "Shutdown complete, restarting!");
10923                Process.killProcess(Process.myPid());
10924                System.exit(10);
10925            }
10926        };
10927
10928        // First send the high-level shut down broadcast.
10929        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10930        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10931        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10932        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10933        mContext.sendOrderedBroadcastAsUser(intent,
10934                UserHandle.ALL, null, br, mHandler, 0, null, null);
10935        */
10936        br.onReceive(mContext, intent);
10937    }
10938
10939    private long getLowRamTimeSinceIdle(long now) {
10940        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10941    }
10942
10943    @Override
10944    public void performIdleMaintenance() {
10945        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10946                != PackageManager.PERMISSION_GRANTED) {
10947            throw new SecurityException("Requires permission "
10948                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10949        }
10950
10951        synchronized (this) {
10952            final long now = SystemClock.uptimeMillis();
10953            final long timeSinceLastIdle = now - mLastIdleTime;
10954            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10955            mLastIdleTime = now;
10956            mLowRamTimeSinceLastIdle = 0;
10957            if (mLowRamStartTime != 0) {
10958                mLowRamStartTime = now;
10959            }
10960
10961            StringBuilder sb = new StringBuilder(128);
10962            sb.append("Idle maintenance over ");
10963            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10964            sb.append(" low RAM for ");
10965            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10966            Slog.i(TAG, sb.toString());
10967
10968            // If at least 1/3 of our time since the last idle period has been spent
10969            // with RAM low, then we want to kill processes.
10970            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10971
10972            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10973                ProcessRecord proc = mLruProcesses.get(i);
10974                if (proc.notCachedSinceIdle) {
10975                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10976                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10977                        if (doKilling && proc.initialIdlePss != 0
10978                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10979                            proc.kill("idle maint (pss " + proc.lastPss
10980                                    + " from " + proc.initialIdlePss + ")", true);
10981                        }
10982                    }
10983                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10984                    proc.notCachedSinceIdle = true;
10985                    proc.initialIdlePss = 0;
10986                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10987                            isSleeping(), now);
10988                }
10989            }
10990
10991            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10992            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10993        }
10994    }
10995
10996    private void retrieveSettings() {
10997        final ContentResolver resolver = mContext.getContentResolver();
10998        String debugApp = Settings.Global.getString(
10999            resolver, Settings.Global.DEBUG_APP);
11000        boolean waitForDebugger = Settings.Global.getInt(
11001            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11002        boolean alwaysFinishActivities = Settings.Global.getInt(
11003            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11004        boolean forceRtl = Settings.Global.getInt(
11005                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11006        // Transfer any global setting for forcing RTL layout, into a System Property
11007        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11008
11009        Configuration configuration = new Configuration();
11010        Settings.System.getConfiguration(resolver, configuration);
11011        if (forceRtl) {
11012            // This will take care of setting the correct layout direction flags
11013            configuration.setLayoutDirection(configuration.locale);
11014        }
11015
11016        synchronized (this) {
11017            mDebugApp = mOrigDebugApp = debugApp;
11018            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11019            mAlwaysFinishActivities = alwaysFinishActivities;
11020            // This happens before any activities are started, so we can
11021            // change mConfiguration in-place.
11022            updateConfigurationLocked(configuration, null, false, true);
11023            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
11024        }
11025    }
11026
11027    /** Loads resources after the current configuration has been set. */
11028    private void loadResourcesOnSystemReady() {
11029        final Resources res = mContext.getResources();
11030        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11031        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11032        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11033    }
11034
11035    public boolean testIsSystemReady() {
11036        // no need to synchronize(this) just to read & return the value
11037        return mSystemReady;
11038    }
11039
11040    private static File getCalledPreBootReceiversFile() {
11041        File dataDir = Environment.getDataDirectory();
11042        File systemDir = new File(dataDir, "system");
11043        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11044        return fname;
11045    }
11046
11047    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11048        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11049        File file = getCalledPreBootReceiversFile();
11050        FileInputStream fis = null;
11051        try {
11052            fis = new FileInputStream(file);
11053            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11054            int fvers = dis.readInt();
11055            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11056                String vers = dis.readUTF();
11057                String codename = dis.readUTF();
11058                String build = dis.readUTF();
11059                if (android.os.Build.VERSION.RELEASE.equals(vers)
11060                        && android.os.Build.VERSION.CODENAME.equals(codename)
11061                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11062                    int num = dis.readInt();
11063                    while (num > 0) {
11064                        num--;
11065                        String pkg = dis.readUTF();
11066                        String cls = dis.readUTF();
11067                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11068                    }
11069                }
11070            }
11071        } catch (FileNotFoundException e) {
11072        } catch (IOException e) {
11073            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11074        } finally {
11075            if (fis != null) {
11076                try {
11077                    fis.close();
11078                } catch (IOException e) {
11079                }
11080            }
11081        }
11082        return lastDoneReceivers;
11083    }
11084
11085    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11086        File file = getCalledPreBootReceiversFile();
11087        FileOutputStream fos = null;
11088        DataOutputStream dos = null;
11089        try {
11090            fos = new FileOutputStream(file);
11091            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11092            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11093            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11094            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11095            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11096            dos.writeInt(list.size());
11097            for (int i=0; i<list.size(); i++) {
11098                dos.writeUTF(list.get(i).getPackageName());
11099                dos.writeUTF(list.get(i).getClassName());
11100            }
11101        } catch (IOException e) {
11102            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11103            file.delete();
11104        } finally {
11105            FileUtils.sync(fos);
11106            if (dos != null) {
11107                try {
11108                    dos.close();
11109                } catch (IOException e) {
11110                    // TODO Auto-generated catch block
11111                    e.printStackTrace();
11112                }
11113            }
11114        }
11115    }
11116
11117    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11118            ArrayList<ComponentName> doneReceivers, int userId) {
11119        boolean waitingUpdate = false;
11120        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11121        List<ResolveInfo> ris = null;
11122        try {
11123            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11124                    intent, null, 0, userId);
11125        } catch (RemoteException e) {
11126        }
11127        if (ris != null) {
11128            for (int i=ris.size()-1; i>=0; i--) {
11129                if ((ris.get(i).activityInfo.applicationInfo.flags
11130                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11131                    ris.remove(i);
11132                }
11133            }
11134            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11135
11136            // For User 0, load the version number. When delivering to a new user, deliver
11137            // to all receivers.
11138            if (userId == UserHandle.USER_OWNER) {
11139                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11140                for (int i=0; i<ris.size(); i++) {
11141                    ActivityInfo ai = ris.get(i).activityInfo;
11142                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11143                    if (lastDoneReceivers.contains(comp)) {
11144                        // We already did the pre boot receiver for this app with the current
11145                        // platform version, so don't do it again...
11146                        ris.remove(i);
11147                        i--;
11148                        // ...however, do keep it as one that has been done, so we don't
11149                        // forget about it when rewriting the file of last done receivers.
11150                        doneReceivers.add(comp);
11151                    }
11152                }
11153            }
11154
11155            // If primary user, send broadcast to all available users, else just to userId
11156            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11157                    : new int[] { userId };
11158            for (int i = 0; i < ris.size(); i++) {
11159                ActivityInfo ai = ris.get(i).activityInfo;
11160                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11161                doneReceivers.add(comp);
11162                intent.setComponent(comp);
11163                for (int j=0; j<users.length; j++) {
11164                    IIntentReceiver finisher = null;
11165                    // On last receiver and user, set up a completion callback
11166                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11167                        finisher = new IIntentReceiver.Stub() {
11168                            public void performReceive(Intent intent, int resultCode,
11169                                    String data, Bundle extras, boolean ordered,
11170                                    boolean sticky, int sendingUser) {
11171                                // The raw IIntentReceiver interface is called
11172                                // with the AM lock held, so redispatch to
11173                                // execute our code without the lock.
11174                                mHandler.post(onFinishCallback);
11175                            }
11176                        };
11177                    }
11178                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11179                            + " for user " + users[j]);
11180                    broadcastIntentLocked(null, null, intent, null, finisher,
11181                            0, null, null, null, AppOpsManager.OP_NONE,
11182                            true, false, MY_PID, Process.SYSTEM_UID,
11183                            users[j]);
11184                    if (finisher != null) {
11185                        waitingUpdate = true;
11186                    }
11187                }
11188            }
11189        }
11190
11191        return waitingUpdate;
11192    }
11193
11194    public void systemReady(final Runnable goingCallback) {
11195        synchronized(this) {
11196            if (mSystemReady) {
11197                // If we're done calling all the receivers, run the next "boot phase" passed in
11198                // by the SystemServer
11199                if (goingCallback != null) {
11200                    goingCallback.run();
11201                }
11202                return;
11203            }
11204
11205            // Make sure we have the current profile info, since it is needed for
11206            // security checks.
11207            updateCurrentProfileIdsLocked();
11208
11209            if (mRecentTasks == null) {
11210                mRecentTasks = mTaskPersister.restoreTasksLocked();
11211                if (!mRecentTasks.isEmpty()) {
11212                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11213                }
11214                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11215                mTaskPersister.startPersisting();
11216            }
11217
11218            // Check to see if there are any update receivers to run.
11219            if (!mDidUpdate) {
11220                if (mWaitingUpdate) {
11221                    return;
11222                }
11223                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11224                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11225                    public void run() {
11226                        synchronized (ActivityManagerService.this) {
11227                            mDidUpdate = true;
11228                        }
11229                        writeLastDonePreBootReceivers(doneReceivers);
11230                        showBootMessage(mContext.getText(
11231                                R.string.android_upgrading_complete),
11232                                false);
11233                        systemReady(goingCallback);
11234                    }
11235                }, doneReceivers, UserHandle.USER_OWNER);
11236
11237                if (mWaitingUpdate) {
11238                    return;
11239                }
11240                mDidUpdate = true;
11241            }
11242
11243            mAppOpsService.systemReady();
11244            mSystemReady = true;
11245        }
11246
11247        ArrayList<ProcessRecord> procsToKill = null;
11248        synchronized(mPidsSelfLocked) {
11249            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11250                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11251                if (!isAllowedWhileBooting(proc.info)){
11252                    if (procsToKill == null) {
11253                        procsToKill = new ArrayList<ProcessRecord>();
11254                    }
11255                    procsToKill.add(proc);
11256                }
11257            }
11258        }
11259
11260        synchronized(this) {
11261            if (procsToKill != null) {
11262                for (int i=procsToKill.size()-1; i>=0; i--) {
11263                    ProcessRecord proc = procsToKill.get(i);
11264                    Slog.i(TAG, "Removing system update proc: " + proc);
11265                    removeProcessLocked(proc, true, false, "system update done");
11266                }
11267            }
11268
11269            // Now that we have cleaned up any update processes, we
11270            // are ready to start launching real processes and know that
11271            // we won't trample on them any more.
11272            mProcessesReady = true;
11273        }
11274
11275        Slog.i(TAG, "System now ready");
11276        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11277            SystemClock.uptimeMillis());
11278
11279        synchronized(this) {
11280            // Make sure we have no pre-ready processes sitting around.
11281
11282            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11283                ResolveInfo ri = mContext.getPackageManager()
11284                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11285                                STOCK_PM_FLAGS);
11286                CharSequence errorMsg = null;
11287                if (ri != null) {
11288                    ActivityInfo ai = ri.activityInfo;
11289                    ApplicationInfo app = ai.applicationInfo;
11290                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11291                        mTopAction = Intent.ACTION_FACTORY_TEST;
11292                        mTopData = null;
11293                        mTopComponent = new ComponentName(app.packageName,
11294                                ai.name);
11295                    } else {
11296                        errorMsg = mContext.getResources().getText(
11297                                com.android.internal.R.string.factorytest_not_system);
11298                    }
11299                } else {
11300                    errorMsg = mContext.getResources().getText(
11301                            com.android.internal.R.string.factorytest_no_action);
11302                }
11303                if (errorMsg != null) {
11304                    mTopAction = null;
11305                    mTopData = null;
11306                    mTopComponent = null;
11307                    Message msg = Message.obtain();
11308                    msg.what = SHOW_FACTORY_ERROR_MSG;
11309                    msg.getData().putCharSequence("msg", errorMsg);
11310                    mHandler.sendMessage(msg);
11311                }
11312            }
11313        }
11314
11315        retrieveSettings();
11316        loadResourcesOnSystemReady();
11317
11318        synchronized (this) {
11319            readGrantedUriPermissionsLocked();
11320        }
11321
11322        if (goingCallback != null) goingCallback.run();
11323
11324        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11325                Integer.toString(mCurrentUserId), mCurrentUserId);
11326        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11327                Integer.toString(mCurrentUserId), mCurrentUserId);
11328        mSystemServiceManager.startUser(mCurrentUserId);
11329
11330        synchronized (this) {
11331            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11332                try {
11333                    List apps = AppGlobals.getPackageManager().
11334                        getPersistentApplications(STOCK_PM_FLAGS);
11335                    if (apps != null) {
11336                        int N = apps.size();
11337                        int i;
11338                        for (i=0; i<N; i++) {
11339                            ApplicationInfo info
11340                                = (ApplicationInfo)apps.get(i);
11341                            if (info != null &&
11342                                    !info.packageName.equals("android")) {
11343                                addAppLocked(info, false, null /* ABI override */);
11344                            }
11345                        }
11346                    }
11347                } catch (RemoteException ex) {
11348                    // pm is in same process, this will never happen.
11349                }
11350            }
11351
11352            // Start up initial activity.
11353            mBooting = true;
11354            startHomeActivityLocked(mCurrentUserId);
11355
11356            try {
11357                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11358                    Message msg = Message.obtain();
11359                    msg.what = SHOW_UID_ERROR_MSG;
11360                    mHandler.sendMessage(msg);
11361                }
11362            } catch (RemoteException e) {
11363            }
11364
11365            long ident = Binder.clearCallingIdentity();
11366            try {
11367                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11368                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11369                        | Intent.FLAG_RECEIVER_FOREGROUND);
11370                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11371                broadcastIntentLocked(null, null, intent,
11372                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11373                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11374                intent = new Intent(Intent.ACTION_USER_STARTING);
11375                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11376                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11377                broadcastIntentLocked(null, null, intent,
11378                        null, new IIntentReceiver.Stub() {
11379                            @Override
11380                            public void performReceive(Intent intent, int resultCode, String data,
11381                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11382                                    throws RemoteException {
11383                            }
11384                        }, 0, null, null,
11385                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11386                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11387            } catch (Throwable t) {
11388                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11389            } finally {
11390                Binder.restoreCallingIdentity(ident);
11391            }
11392            mStackSupervisor.resumeTopActivitiesLocked();
11393            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11394        }
11395    }
11396
11397    private boolean makeAppCrashingLocked(ProcessRecord app,
11398            String shortMsg, String longMsg, String stackTrace) {
11399        app.crashing = true;
11400        app.crashingReport = generateProcessError(app,
11401                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11402        startAppProblemLocked(app);
11403        app.stopFreezingAllLocked();
11404        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11405    }
11406
11407    private void makeAppNotRespondingLocked(ProcessRecord app,
11408            String activity, String shortMsg, String longMsg) {
11409        app.notResponding = true;
11410        app.notRespondingReport = generateProcessError(app,
11411                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11412                activity, shortMsg, longMsg, null);
11413        startAppProblemLocked(app);
11414        app.stopFreezingAllLocked();
11415    }
11416
11417    /**
11418     * Generate a process error record, suitable for attachment to a ProcessRecord.
11419     *
11420     * @param app The ProcessRecord in which the error occurred.
11421     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11422     *                      ActivityManager.AppErrorStateInfo
11423     * @param activity The activity associated with the crash, if known.
11424     * @param shortMsg Short message describing the crash.
11425     * @param longMsg Long message describing the crash.
11426     * @param stackTrace Full crash stack trace, may be null.
11427     *
11428     * @return Returns a fully-formed AppErrorStateInfo record.
11429     */
11430    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11431            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11432        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11433
11434        report.condition = condition;
11435        report.processName = app.processName;
11436        report.pid = app.pid;
11437        report.uid = app.info.uid;
11438        report.tag = activity;
11439        report.shortMsg = shortMsg;
11440        report.longMsg = longMsg;
11441        report.stackTrace = stackTrace;
11442
11443        return report;
11444    }
11445
11446    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11447        synchronized (this) {
11448            app.crashing = false;
11449            app.crashingReport = null;
11450            app.notResponding = false;
11451            app.notRespondingReport = null;
11452            if (app.anrDialog == fromDialog) {
11453                app.anrDialog = null;
11454            }
11455            if (app.waitDialog == fromDialog) {
11456                app.waitDialog = null;
11457            }
11458            if (app.pid > 0 && app.pid != MY_PID) {
11459                handleAppCrashLocked(app, null, null, null);
11460                app.kill("user request after error", true);
11461            }
11462        }
11463    }
11464
11465    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11466            String stackTrace) {
11467        long now = SystemClock.uptimeMillis();
11468
11469        Long crashTime;
11470        if (!app.isolated) {
11471            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11472        } else {
11473            crashTime = null;
11474        }
11475        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11476            // This process loses!
11477            Slog.w(TAG, "Process " + app.info.processName
11478                    + " has crashed too many times: killing!");
11479            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11480                    app.userId, app.info.processName, app.uid);
11481            mStackSupervisor.handleAppCrashLocked(app);
11482            if (!app.persistent) {
11483                // We don't want to start this process again until the user
11484                // explicitly does so...  but for persistent process, we really
11485                // need to keep it running.  If a persistent process is actually
11486                // repeatedly crashing, then badness for everyone.
11487                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11488                        app.info.processName);
11489                if (!app.isolated) {
11490                    // XXX We don't have a way to mark isolated processes
11491                    // as bad, since they don't have a peristent identity.
11492                    mBadProcesses.put(app.info.processName, app.uid,
11493                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11494                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11495                }
11496                app.bad = true;
11497                app.removed = true;
11498                // Don't let services in this process be restarted and potentially
11499                // annoy the user repeatedly.  Unless it is persistent, since those
11500                // processes run critical code.
11501                removeProcessLocked(app, false, false, "crash");
11502                mStackSupervisor.resumeTopActivitiesLocked();
11503                return false;
11504            }
11505            mStackSupervisor.resumeTopActivitiesLocked();
11506        } else {
11507            mStackSupervisor.finishTopRunningActivityLocked(app);
11508        }
11509
11510        // Bump up the crash count of any services currently running in the proc.
11511        for (int i=app.services.size()-1; i>=0; i--) {
11512            // Any services running in the application need to be placed
11513            // back in the pending list.
11514            ServiceRecord sr = app.services.valueAt(i);
11515            sr.crashCount++;
11516        }
11517
11518        // If the crashing process is what we consider to be the "home process" and it has been
11519        // replaced by a third-party app, clear the package preferred activities from packages
11520        // with a home activity running in the process to prevent a repeatedly crashing app
11521        // from blocking the user to manually clear the list.
11522        final ArrayList<ActivityRecord> activities = app.activities;
11523        if (app == mHomeProcess && activities.size() > 0
11524                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11525            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11526                final ActivityRecord r = activities.get(activityNdx);
11527                if (r.isHomeActivity()) {
11528                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11529                    try {
11530                        ActivityThread.getPackageManager()
11531                                .clearPackagePreferredActivities(r.packageName);
11532                    } catch (RemoteException c) {
11533                        // pm is in same process, this will never happen.
11534                    }
11535                }
11536            }
11537        }
11538
11539        if (!app.isolated) {
11540            // XXX Can't keep track of crash times for isolated processes,
11541            // because they don't have a perisistent identity.
11542            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11543        }
11544
11545        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11546        return true;
11547    }
11548
11549    void startAppProblemLocked(ProcessRecord app) {
11550        // If this app is not running under the current user, then we
11551        // can't give it a report button because that would require
11552        // launching the report UI under a different user.
11553        app.errorReportReceiver = null;
11554
11555        for (int userId : mCurrentProfileIds) {
11556            if (app.userId == userId) {
11557                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11558                        mContext, app.info.packageName, app.info.flags);
11559            }
11560        }
11561        skipCurrentReceiverLocked(app);
11562    }
11563
11564    void skipCurrentReceiverLocked(ProcessRecord app) {
11565        for (BroadcastQueue queue : mBroadcastQueues) {
11566            queue.skipCurrentReceiverLocked(app);
11567        }
11568    }
11569
11570    /**
11571     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11572     * The application process will exit immediately after this call returns.
11573     * @param app object of the crashing app, null for the system server
11574     * @param crashInfo describing the exception
11575     */
11576    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11577        ProcessRecord r = findAppProcess(app, "Crash");
11578        final String processName = app == null ? "system_server"
11579                : (r == null ? "unknown" : r.processName);
11580
11581        handleApplicationCrashInner("crash", r, processName, crashInfo);
11582    }
11583
11584    /* Native crash reporting uses this inner version because it needs to be somewhat
11585     * decoupled from the AM-managed cleanup lifecycle
11586     */
11587    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11588            ApplicationErrorReport.CrashInfo crashInfo) {
11589        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11590                UserHandle.getUserId(Binder.getCallingUid()), processName,
11591                r == null ? -1 : r.info.flags,
11592                crashInfo.exceptionClassName,
11593                crashInfo.exceptionMessage,
11594                crashInfo.throwFileName,
11595                crashInfo.throwLineNumber);
11596
11597        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11598
11599        crashApplication(r, crashInfo);
11600    }
11601
11602    public void handleApplicationStrictModeViolation(
11603            IBinder app,
11604            int violationMask,
11605            StrictMode.ViolationInfo info) {
11606        ProcessRecord r = findAppProcess(app, "StrictMode");
11607        if (r == null) {
11608            return;
11609        }
11610
11611        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11612            Integer stackFingerprint = info.hashCode();
11613            boolean logIt = true;
11614            synchronized (mAlreadyLoggedViolatedStacks) {
11615                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11616                    logIt = false;
11617                    // TODO: sub-sample into EventLog for these, with
11618                    // the info.durationMillis?  Then we'd get
11619                    // the relative pain numbers, without logging all
11620                    // the stack traces repeatedly.  We'd want to do
11621                    // likewise in the client code, which also does
11622                    // dup suppression, before the Binder call.
11623                } else {
11624                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11625                        mAlreadyLoggedViolatedStacks.clear();
11626                    }
11627                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11628                }
11629            }
11630            if (logIt) {
11631                logStrictModeViolationToDropBox(r, info);
11632            }
11633        }
11634
11635        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11636            AppErrorResult result = new AppErrorResult();
11637            synchronized (this) {
11638                final long origId = Binder.clearCallingIdentity();
11639
11640                Message msg = Message.obtain();
11641                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11642                HashMap<String, Object> data = new HashMap<String, Object>();
11643                data.put("result", result);
11644                data.put("app", r);
11645                data.put("violationMask", violationMask);
11646                data.put("info", info);
11647                msg.obj = data;
11648                mHandler.sendMessage(msg);
11649
11650                Binder.restoreCallingIdentity(origId);
11651            }
11652            int res = result.get();
11653            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11654        }
11655    }
11656
11657    // Depending on the policy in effect, there could be a bunch of
11658    // these in quick succession so we try to batch these together to
11659    // minimize disk writes, number of dropbox entries, and maximize
11660    // compression, by having more fewer, larger records.
11661    private void logStrictModeViolationToDropBox(
11662            ProcessRecord process,
11663            StrictMode.ViolationInfo info) {
11664        if (info == null) {
11665            return;
11666        }
11667        final boolean isSystemApp = process == null ||
11668                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11669                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11670        final String processName = process == null ? "unknown" : process.processName;
11671        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11672        final DropBoxManager dbox = (DropBoxManager)
11673                mContext.getSystemService(Context.DROPBOX_SERVICE);
11674
11675        // Exit early if the dropbox isn't configured to accept this report type.
11676        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11677
11678        boolean bufferWasEmpty;
11679        boolean needsFlush;
11680        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11681        synchronized (sb) {
11682            bufferWasEmpty = sb.length() == 0;
11683            appendDropBoxProcessHeaders(process, processName, sb);
11684            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11685            sb.append("System-App: ").append(isSystemApp).append("\n");
11686            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11687            if (info.violationNumThisLoop != 0) {
11688                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11689            }
11690            if (info.numAnimationsRunning != 0) {
11691                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11692            }
11693            if (info.broadcastIntentAction != null) {
11694                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11695            }
11696            if (info.durationMillis != -1) {
11697                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11698            }
11699            if (info.numInstances != -1) {
11700                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11701            }
11702            if (info.tags != null) {
11703                for (String tag : info.tags) {
11704                    sb.append("Span-Tag: ").append(tag).append("\n");
11705                }
11706            }
11707            sb.append("\n");
11708            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11709                sb.append(info.crashInfo.stackTrace);
11710            }
11711            sb.append("\n");
11712
11713            // Only buffer up to ~64k.  Various logging bits truncate
11714            // things at 128k.
11715            needsFlush = (sb.length() > 64 * 1024);
11716        }
11717
11718        // Flush immediately if the buffer's grown too large, or this
11719        // is a non-system app.  Non-system apps are isolated with a
11720        // different tag & policy and not batched.
11721        //
11722        // Batching is useful during internal testing with
11723        // StrictMode settings turned up high.  Without batching,
11724        // thousands of separate files could be created on boot.
11725        if (!isSystemApp || needsFlush) {
11726            new Thread("Error dump: " + dropboxTag) {
11727                @Override
11728                public void run() {
11729                    String report;
11730                    synchronized (sb) {
11731                        report = sb.toString();
11732                        sb.delete(0, sb.length());
11733                        sb.trimToSize();
11734                    }
11735                    if (report.length() != 0) {
11736                        dbox.addText(dropboxTag, report);
11737                    }
11738                }
11739            }.start();
11740            return;
11741        }
11742
11743        // System app batching:
11744        if (!bufferWasEmpty) {
11745            // An existing dropbox-writing thread is outstanding, so
11746            // we don't need to start it up.  The existing thread will
11747            // catch the buffer appends we just did.
11748            return;
11749        }
11750
11751        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11752        // (After this point, we shouldn't access AMS internal data structures.)
11753        new Thread("Error dump: " + dropboxTag) {
11754            @Override
11755            public void run() {
11756                // 5 second sleep to let stacks arrive and be batched together
11757                try {
11758                    Thread.sleep(5000);  // 5 seconds
11759                } catch (InterruptedException e) {}
11760
11761                String errorReport;
11762                synchronized (mStrictModeBuffer) {
11763                    errorReport = mStrictModeBuffer.toString();
11764                    if (errorReport.length() == 0) {
11765                        return;
11766                    }
11767                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11768                    mStrictModeBuffer.trimToSize();
11769                }
11770                dbox.addText(dropboxTag, errorReport);
11771            }
11772        }.start();
11773    }
11774
11775    /**
11776     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11777     * @param app object of the crashing app, null for the system server
11778     * @param tag reported by the caller
11779     * @param system whether this wtf is coming from the system
11780     * @param crashInfo describing the context of the error
11781     * @return true if the process should exit immediately (WTF is fatal)
11782     */
11783    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11784            final ApplicationErrorReport.CrashInfo crashInfo) {
11785        final int callingUid = Binder.getCallingUid();
11786        final int callingPid = Binder.getCallingPid();
11787
11788        if (system) {
11789            // If this is coming from the system, we could very well have low-level
11790            // system locks held, so we want to do this all asynchronously.  And we
11791            // never want this to become fatal, so there is that too.
11792            mHandler.post(new Runnable() {
11793                @Override public void run() {
11794                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11795                }
11796            });
11797            return false;
11798        }
11799
11800        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11801                crashInfo);
11802
11803        if (r != null && r.pid != Process.myPid() &&
11804                Settings.Global.getInt(mContext.getContentResolver(),
11805                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11806            crashApplication(r, crashInfo);
11807            return true;
11808        } else {
11809            return false;
11810        }
11811    }
11812
11813    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11814            final ApplicationErrorReport.CrashInfo crashInfo) {
11815        final ProcessRecord r = findAppProcess(app, "WTF");
11816        final String processName = app == null ? "system_server"
11817                : (r == null ? "unknown" : r.processName);
11818
11819        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11820                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11821
11822        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11823
11824        return r;
11825    }
11826
11827    /**
11828     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11829     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11830     */
11831    private ProcessRecord findAppProcess(IBinder app, String reason) {
11832        if (app == null) {
11833            return null;
11834        }
11835
11836        synchronized (this) {
11837            final int NP = mProcessNames.getMap().size();
11838            for (int ip=0; ip<NP; ip++) {
11839                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11840                final int NA = apps.size();
11841                for (int ia=0; ia<NA; ia++) {
11842                    ProcessRecord p = apps.valueAt(ia);
11843                    if (p.thread != null && p.thread.asBinder() == app) {
11844                        return p;
11845                    }
11846                }
11847            }
11848
11849            Slog.w(TAG, "Can't find mystery application for " + reason
11850                    + " from pid=" + Binder.getCallingPid()
11851                    + " uid=" + Binder.getCallingUid() + ": " + app);
11852            return null;
11853        }
11854    }
11855
11856    /**
11857     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11858     * to append various headers to the dropbox log text.
11859     */
11860    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11861            StringBuilder sb) {
11862        // Watchdog thread ends up invoking this function (with
11863        // a null ProcessRecord) to add the stack file to dropbox.
11864        // Do not acquire a lock on this (am) in such cases, as it
11865        // could cause a potential deadlock, if and when watchdog
11866        // is invoked due to unavailability of lock on am and it
11867        // would prevent watchdog from killing system_server.
11868        if (process == null) {
11869            sb.append("Process: ").append(processName).append("\n");
11870            return;
11871        }
11872        // Note: ProcessRecord 'process' is guarded by the service
11873        // instance.  (notably process.pkgList, which could otherwise change
11874        // concurrently during execution of this method)
11875        synchronized (this) {
11876            sb.append("Process: ").append(processName).append("\n");
11877            int flags = process.info.flags;
11878            IPackageManager pm = AppGlobals.getPackageManager();
11879            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11880            for (int ip=0; ip<process.pkgList.size(); ip++) {
11881                String pkg = process.pkgList.keyAt(ip);
11882                sb.append("Package: ").append(pkg);
11883                try {
11884                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11885                    if (pi != null) {
11886                        sb.append(" v").append(pi.versionCode);
11887                        if (pi.versionName != null) {
11888                            sb.append(" (").append(pi.versionName).append(")");
11889                        }
11890                    }
11891                } catch (RemoteException e) {
11892                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11893                }
11894                sb.append("\n");
11895            }
11896        }
11897    }
11898
11899    private static String processClass(ProcessRecord process) {
11900        if (process == null || process.pid == MY_PID) {
11901            return "system_server";
11902        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11903            return "system_app";
11904        } else {
11905            return "data_app";
11906        }
11907    }
11908
11909    /**
11910     * Write a description of an error (crash, WTF, ANR) to the drop box.
11911     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11912     * @param process which caused the error, null means the system server
11913     * @param activity which triggered the error, null if unknown
11914     * @param parent activity related to the error, null if unknown
11915     * @param subject line related to the error, null if absent
11916     * @param report in long form describing the error, null if absent
11917     * @param logFile to include in the report, null if none
11918     * @param crashInfo giving an application stack trace, null if absent
11919     */
11920    public void addErrorToDropBox(String eventType,
11921            ProcessRecord process, String processName, ActivityRecord activity,
11922            ActivityRecord parent, String subject,
11923            final String report, final File logFile,
11924            final ApplicationErrorReport.CrashInfo crashInfo) {
11925        // NOTE -- this must never acquire the ActivityManagerService lock,
11926        // otherwise the watchdog may be prevented from resetting the system.
11927
11928        final String dropboxTag = processClass(process) + "_" + eventType;
11929        final DropBoxManager dbox = (DropBoxManager)
11930                mContext.getSystemService(Context.DROPBOX_SERVICE);
11931
11932        // Exit early if the dropbox isn't configured to accept this report type.
11933        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11934
11935        final StringBuilder sb = new StringBuilder(1024);
11936        appendDropBoxProcessHeaders(process, processName, sb);
11937        if (activity != null) {
11938            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11939        }
11940        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11941            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11942        }
11943        if (parent != null && parent != activity) {
11944            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11945        }
11946        if (subject != null) {
11947            sb.append("Subject: ").append(subject).append("\n");
11948        }
11949        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11950        if (Debug.isDebuggerConnected()) {
11951            sb.append("Debugger: Connected\n");
11952        }
11953        sb.append("\n");
11954
11955        // Do the rest in a worker thread to avoid blocking the caller on I/O
11956        // (After this point, we shouldn't access AMS internal data structures.)
11957        Thread worker = new Thread("Error dump: " + dropboxTag) {
11958            @Override
11959            public void run() {
11960                if (report != null) {
11961                    sb.append(report);
11962                }
11963                if (logFile != null) {
11964                    try {
11965                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11966                                    "\n\n[[TRUNCATED]]"));
11967                    } catch (IOException e) {
11968                        Slog.e(TAG, "Error reading " + logFile, e);
11969                    }
11970                }
11971                if (crashInfo != null && crashInfo.stackTrace != null) {
11972                    sb.append(crashInfo.stackTrace);
11973                }
11974
11975                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11976                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11977                if (lines > 0) {
11978                    sb.append("\n");
11979
11980                    // Merge several logcat streams, and take the last N lines
11981                    InputStreamReader input = null;
11982                    try {
11983                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11984                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11985                                "-b", "crash",
11986                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11987
11988                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11989                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11990                        input = new InputStreamReader(logcat.getInputStream());
11991
11992                        int num;
11993                        char[] buf = new char[8192];
11994                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11995                    } catch (IOException e) {
11996                        Slog.e(TAG, "Error running logcat", e);
11997                    } finally {
11998                        if (input != null) try { input.close(); } catch (IOException e) {}
11999                    }
12000                }
12001
12002                dbox.addText(dropboxTag, sb.toString());
12003            }
12004        };
12005
12006        if (process == null) {
12007            // If process is null, we are being called from some internal code
12008            // and may be about to die -- run this synchronously.
12009            worker.run();
12010        } else {
12011            worker.start();
12012        }
12013    }
12014
12015    /**
12016     * Bring up the "unexpected error" dialog box for a crashing app.
12017     * Deal with edge cases (intercepts from instrumented applications,
12018     * ActivityController, error intent receivers, that sort of thing).
12019     * @param r the application crashing
12020     * @param crashInfo describing the failure
12021     */
12022    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12023        long timeMillis = System.currentTimeMillis();
12024        String shortMsg = crashInfo.exceptionClassName;
12025        String longMsg = crashInfo.exceptionMessage;
12026        String stackTrace = crashInfo.stackTrace;
12027        if (shortMsg != null && longMsg != null) {
12028            longMsg = shortMsg + ": " + longMsg;
12029        } else if (shortMsg != null) {
12030            longMsg = shortMsg;
12031        }
12032
12033        AppErrorResult result = new AppErrorResult();
12034        synchronized (this) {
12035            if (mController != null) {
12036                try {
12037                    String name = r != null ? r.processName : null;
12038                    int pid = r != null ? r.pid : Binder.getCallingPid();
12039                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
12040                    if (!mController.appCrashed(name, pid,
12041                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12042                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12043                                && "Native crash".equals(crashInfo.exceptionClassName)) {
12044                            Slog.w(TAG, "Skip killing native crashed app " + name
12045                                    + "(" + pid + ") during testing");
12046                        } else {
12047                            Slog.w(TAG, "Force-killing crashed app " + name
12048                                    + " at watcher's request");
12049                            if (r != null) {
12050                                r.kill("crash", true);
12051                            } else {
12052                                // Huh.
12053                                Process.killProcess(pid);
12054                                Process.killProcessGroup(uid, pid);
12055                            }
12056                        }
12057                        return;
12058                    }
12059                } catch (RemoteException e) {
12060                    mController = null;
12061                    Watchdog.getInstance().setActivityController(null);
12062                }
12063            }
12064
12065            final long origId = Binder.clearCallingIdentity();
12066
12067            // If this process is running instrumentation, finish it.
12068            if (r != null && r.instrumentationClass != null) {
12069                Slog.w(TAG, "Error in app " + r.processName
12070                      + " running instrumentation " + r.instrumentationClass + ":");
12071                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12072                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12073                Bundle info = new Bundle();
12074                info.putString("shortMsg", shortMsg);
12075                info.putString("longMsg", longMsg);
12076                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12077                Binder.restoreCallingIdentity(origId);
12078                return;
12079            }
12080
12081            // If we can't identify the process or it's already exceeded its crash quota,
12082            // quit right away without showing a crash dialog.
12083            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12084                Binder.restoreCallingIdentity(origId);
12085                return;
12086            }
12087
12088            Message msg = Message.obtain();
12089            msg.what = SHOW_ERROR_MSG;
12090            HashMap data = new HashMap();
12091            data.put("result", result);
12092            data.put("app", r);
12093            msg.obj = data;
12094            mHandler.sendMessage(msg);
12095
12096            Binder.restoreCallingIdentity(origId);
12097        }
12098
12099        int res = result.get();
12100
12101        Intent appErrorIntent = null;
12102        synchronized (this) {
12103            if (r != null && !r.isolated) {
12104                // XXX Can't keep track of crash time for isolated processes,
12105                // since they don't have a persistent identity.
12106                mProcessCrashTimes.put(r.info.processName, r.uid,
12107                        SystemClock.uptimeMillis());
12108            }
12109            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12110                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12111            }
12112        }
12113
12114        if (appErrorIntent != null) {
12115            try {
12116                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12117            } catch (ActivityNotFoundException e) {
12118                Slog.w(TAG, "bug report receiver dissappeared", e);
12119            }
12120        }
12121    }
12122
12123    Intent createAppErrorIntentLocked(ProcessRecord r,
12124            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12125        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12126        if (report == null) {
12127            return null;
12128        }
12129        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12130        result.setComponent(r.errorReportReceiver);
12131        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12132        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12133        return result;
12134    }
12135
12136    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12137            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12138        if (r.errorReportReceiver == null) {
12139            return null;
12140        }
12141
12142        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12143            return null;
12144        }
12145
12146        ApplicationErrorReport report = new ApplicationErrorReport();
12147        report.packageName = r.info.packageName;
12148        report.installerPackageName = r.errorReportReceiver.getPackageName();
12149        report.processName = r.processName;
12150        report.time = timeMillis;
12151        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12152
12153        if (r.crashing || r.forceCrashReport) {
12154            report.type = ApplicationErrorReport.TYPE_CRASH;
12155            report.crashInfo = crashInfo;
12156        } else if (r.notResponding) {
12157            report.type = ApplicationErrorReport.TYPE_ANR;
12158            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12159
12160            report.anrInfo.activity = r.notRespondingReport.tag;
12161            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12162            report.anrInfo.info = r.notRespondingReport.longMsg;
12163        }
12164
12165        return report;
12166    }
12167
12168    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12169        enforceNotIsolatedCaller("getProcessesInErrorState");
12170        // assume our apps are happy - lazy create the list
12171        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12172
12173        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12174                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12175        int userId = UserHandle.getUserId(Binder.getCallingUid());
12176
12177        synchronized (this) {
12178
12179            // iterate across all processes
12180            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12181                ProcessRecord app = mLruProcesses.get(i);
12182                if (!allUsers && app.userId != userId) {
12183                    continue;
12184                }
12185                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12186                    // This one's in trouble, so we'll generate a report for it
12187                    // crashes are higher priority (in case there's a crash *and* an anr)
12188                    ActivityManager.ProcessErrorStateInfo report = null;
12189                    if (app.crashing) {
12190                        report = app.crashingReport;
12191                    } else if (app.notResponding) {
12192                        report = app.notRespondingReport;
12193                    }
12194
12195                    if (report != null) {
12196                        if (errList == null) {
12197                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12198                        }
12199                        errList.add(report);
12200                    } else {
12201                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12202                                " crashing = " + app.crashing +
12203                                " notResponding = " + app.notResponding);
12204                    }
12205                }
12206            }
12207        }
12208
12209        return errList;
12210    }
12211
12212    static int procStateToImportance(int procState, int memAdj,
12213            ActivityManager.RunningAppProcessInfo currApp) {
12214        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12215        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12216            currApp.lru = memAdj;
12217        } else {
12218            currApp.lru = 0;
12219        }
12220        return imp;
12221    }
12222
12223    private void fillInProcMemInfo(ProcessRecord app,
12224            ActivityManager.RunningAppProcessInfo outInfo) {
12225        outInfo.pid = app.pid;
12226        outInfo.uid = app.info.uid;
12227        if (mHeavyWeightProcess == app) {
12228            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12229        }
12230        if (app.persistent) {
12231            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12232        }
12233        if (app.activities.size() > 0) {
12234            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12235        }
12236        outInfo.lastTrimLevel = app.trimMemoryLevel;
12237        int adj = app.curAdj;
12238        int procState = app.curProcState;
12239        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12240        outInfo.importanceReasonCode = app.adjTypeCode;
12241        outInfo.processState = app.curProcState;
12242    }
12243
12244    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12245        enforceNotIsolatedCaller("getRunningAppProcesses");
12246        // Lazy instantiation of list
12247        List<ActivityManager.RunningAppProcessInfo> runList = null;
12248        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12249                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12250        int userId = UserHandle.getUserId(Binder.getCallingUid());
12251        synchronized (this) {
12252            // Iterate across all processes
12253            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12254                ProcessRecord app = mLruProcesses.get(i);
12255                if (!allUsers && app.userId != userId) {
12256                    continue;
12257                }
12258                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12259                    // Generate process state info for running application
12260                    ActivityManager.RunningAppProcessInfo currApp =
12261                        new ActivityManager.RunningAppProcessInfo(app.processName,
12262                                app.pid, app.getPackageList());
12263                    fillInProcMemInfo(app, currApp);
12264                    if (app.adjSource instanceof ProcessRecord) {
12265                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12266                        currApp.importanceReasonImportance =
12267                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12268                                        app.adjSourceProcState);
12269                    } else if (app.adjSource instanceof ActivityRecord) {
12270                        ActivityRecord r = (ActivityRecord)app.adjSource;
12271                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12272                    }
12273                    if (app.adjTarget instanceof ComponentName) {
12274                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12275                    }
12276                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12277                    //        + " lru=" + currApp.lru);
12278                    if (runList == null) {
12279                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12280                    }
12281                    runList.add(currApp);
12282                }
12283            }
12284        }
12285        return runList;
12286    }
12287
12288    public List<ApplicationInfo> getRunningExternalApplications() {
12289        enforceNotIsolatedCaller("getRunningExternalApplications");
12290        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12291        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12292        if (runningApps != null && runningApps.size() > 0) {
12293            Set<String> extList = new HashSet<String>();
12294            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12295                if (app.pkgList != null) {
12296                    for (String pkg : app.pkgList) {
12297                        extList.add(pkg);
12298                    }
12299                }
12300            }
12301            IPackageManager pm = AppGlobals.getPackageManager();
12302            for (String pkg : extList) {
12303                try {
12304                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12305                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12306                        retList.add(info);
12307                    }
12308                } catch (RemoteException e) {
12309                }
12310            }
12311        }
12312        return retList;
12313    }
12314
12315    @Override
12316    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12317        enforceNotIsolatedCaller("getMyMemoryState");
12318        synchronized (this) {
12319            ProcessRecord proc;
12320            synchronized (mPidsSelfLocked) {
12321                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12322            }
12323            fillInProcMemInfo(proc, outInfo);
12324        }
12325    }
12326
12327    @Override
12328    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12329        if (checkCallingPermission(android.Manifest.permission.DUMP)
12330                != PackageManager.PERMISSION_GRANTED) {
12331            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12332                    + Binder.getCallingPid()
12333                    + ", uid=" + Binder.getCallingUid()
12334                    + " without permission "
12335                    + android.Manifest.permission.DUMP);
12336            return;
12337        }
12338
12339        boolean dumpAll = false;
12340        boolean dumpClient = false;
12341        String dumpPackage = null;
12342
12343        int opti = 0;
12344        while (opti < args.length) {
12345            String opt = args[opti];
12346            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12347                break;
12348            }
12349            opti++;
12350            if ("-a".equals(opt)) {
12351                dumpAll = true;
12352            } else if ("-c".equals(opt)) {
12353                dumpClient = true;
12354            } else if ("-h".equals(opt)) {
12355                pw.println("Activity manager dump options:");
12356                pw.println("  [-a] [-c] [-h] [cmd] ...");
12357                pw.println("  cmd may be one of:");
12358                pw.println("    a[ctivities]: activity stack state");
12359                pw.println("    r[recents]: recent activities state");
12360                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12361                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12362                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12363                pw.println("    o[om]: out of memory management");
12364                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12365                pw.println("    provider [COMP_SPEC]: provider client-side state");
12366                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12367                pw.println("    service [COMP_SPEC]: service client-side state");
12368                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12369                pw.println("    all: dump all activities");
12370                pw.println("    top: dump the top activity");
12371                pw.println("    write: write all pending state to storage");
12372                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12373                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12374                pw.println("    a partial substring in a component name, a");
12375                pw.println("    hex object identifier.");
12376                pw.println("  -a: include all available server state.");
12377                pw.println("  -c: include client state.");
12378                return;
12379            } else {
12380                pw.println("Unknown argument: " + opt + "; use -h for help");
12381            }
12382        }
12383
12384        long origId = Binder.clearCallingIdentity();
12385        boolean more = false;
12386        // Is the caller requesting to dump a particular piece of data?
12387        if (opti < args.length) {
12388            String cmd = args[opti];
12389            opti++;
12390            if ("activities".equals(cmd) || "a".equals(cmd)) {
12391                synchronized (this) {
12392                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12393                }
12394            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12395                synchronized (this) {
12396                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12397                }
12398            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12399                String[] newArgs;
12400                String name;
12401                if (opti >= args.length) {
12402                    name = null;
12403                    newArgs = EMPTY_STRING_ARRAY;
12404                } else {
12405                    name = args[opti];
12406                    opti++;
12407                    newArgs = new String[args.length - opti];
12408                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12409                            args.length - opti);
12410                }
12411                synchronized (this) {
12412                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12413                }
12414            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12415                String[] newArgs;
12416                String name;
12417                if (opti >= args.length) {
12418                    name = null;
12419                    newArgs = EMPTY_STRING_ARRAY;
12420                } else {
12421                    name = args[opti];
12422                    opti++;
12423                    newArgs = new String[args.length - opti];
12424                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12425                            args.length - opti);
12426                }
12427                synchronized (this) {
12428                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12429                }
12430            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12431                String[] newArgs;
12432                String name;
12433                if (opti >= args.length) {
12434                    name = null;
12435                    newArgs = EMPTY_STRING_ARRAY;
12436                } else {
12437                    name = args[opti];
12438                    opti++;
12439                    newArgs = new String[args.length - opti];
12440                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12441                            args.length - opti);
12442                }
12443                synchronized (this) {
12444                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12445                }
12446            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12447                synchronized (this) {
12448                    dumpOomLocked(fd, pw, args, opti, true);
12449                }
12450            } else if ("provider".equals(cmd)) {
12451                String[] newArgs;
12452                String name;
12453                if (opti >= args.length) {
12454                    name = null;
12455                    newArgs = EMPTY_STRING_ARRAY;
12456                } else {
12457                    name = args[opti];
12458                    opti++;
12459                    newArgs = new String[args.length - opti];
12460                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12461                }
12462                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12463                    pw.println("No providers match: " + name);
12464                    pw.println("Use -h for help.");
12465                }
12466            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12467                synchronized (this) {
12468                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12469                }
12470            } else if ("service".equals(cmd)) {
12471                String[] newArgs;
12472                String name;
12473                if (opti >= args.length) {
12474                    name = null;
12475                    newArgs = EMPTY_STRING_ARRAY;
12476                } else {
12477                    name = args[opti];
12478                    opti++;
12479                    newArgs = new String[args.length - opti];
12480                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12481                            args.length - opti);
12482                }
12483                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12484                    pw.println("No services match: " + name);
12485                    pw.println("Use -h for help.");
12486                }
12487            } else if ("package".equals(cmd)) {
12488                String[] newArgs;
12489                if (opti >= args.length) {
12490                    pw.println("package: no package name specified");
12491                    pw.println("Use -h for help.");
12492                } else {
12493                    dumpPackage = args[opti];
12494                    opti++;
12495                    newArgs = new String[args.length - opti];
12496                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12497                            args.length - opti);
12498                    args = newArgs;
12499                    opti = 0;
12500                    more = true;
12501                }
12502            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12503                synchronized (this) {
12504                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12505                }
12506            } else if ("write".equals(cmd)) {
12507                mTaskPersister.flush();
12508                pw.println("All tasks persisted.");
12509                return;
12510            } else {
12511                // Dumping a single activity?
12512                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12513                    pw.println("Bad activity command, or no activities match: " + cmd);
12514                    pw.println("Use -h for help.");
12515                }
12516            }
12517            if (!more) {
12518                Binder.restoreCallingIdentity(origId);
12519                return;
12520            }
12521        }
12522
12523        // No piece of data specified, dump everything.
12524        synchronized (this) {
12525            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12526            pw.println();
12527            if (dumpAll) {
12528                pw.println("-------------------------------------------------------------------------------");
12529            }
12530            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12531            pw.println();
12532            if (dumpAll) {
12533                pw.println("-------------------------------------------------------------------------------");
12534            }
12535            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12536            pw.println();
12537            if (dumpAll) {
12538                pw.println("-------------------------------------------------------------------------------");
12539            }
12540            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12541            pw.println();
12542            if (dumpAll) {
12543                pw.println("-------------------------------------------------------------------------------");
12544            }
12545            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12546            pw.println();
12547            if (dumpAll) {
12548                pw.println("-------------------------------------------------------------------------------");
12549            }
12550            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12551            pw.println();
12552            if (dumpAll) {
12553                pw.println("-------------------------------------------------------------------------------");
12554            }
12555            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12556        }
12557        Binder.restoreCallingIdentity(origId);
12558    }
12559
12560    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12561            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12562        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12563
12564        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12565                dumpPackage);
12566        boolean needSep = printedAnything;
12567
12568        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12569                dumpPackage, needSep, "  mFocusedActivity: ");
12570        if (printed) {
12571            printedAnything = true;
12572            needSep = false;
12573        }
12574
12575        if (dumpPackage == null) {
12576            if (needSep) {
12577                pw.println();
12578            }
12579            needSep = true;
12580            printedAnything = true;
12581            mStackSupervisor.dump(pw, "  ");
12582        }
12583
12584        if (!printedAnything) {
12585            pw.println("  (nothing)");
12586        }
12587    }
12588
12589    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12590            int opti, boolean dumpAll, String dumpPackage) {
12591        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12592
12593        boolean printedAnything = false;
12594
12595        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12596            boolean printedHeader = false;
12597
12598            final int N = mRecentTasks.size();
12599            for (int i=0; i<N; i++) {
12600                TaskRecord tr = mRecentTasks.get(i);
12601                if (dumpPackage != null) {
12602                    if (tr.realActivity == null ||
12603                            !dumpPackage.equals(tr.realActivity)) {
12604                        continue;
12605                    }
12606                }
12607                if (!printedHeader) {
12608                    pw.println("  Recent tasks:");
12609                    printedHeader = true;
12610                    printedAnything = true;
12611                }
12612                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12613                        pw.println(tr);
12614                if (dumpAll) {
12615                    mRecentTasks.get(i).dump(pw, "    ");
12616                }
12617            }
12618        }
12619
12620        if (!printedAnything) {
12621            pw.println("  (nothing)");
12622        }
12623    }
12624
12625    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12626            int opti, boolean dumpAll, String dumpPackage) {
12627        boolean needSep = false;
12628        boolean printedAnything = false;
12629        int numPers = 0;
12630
12631        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12632
12633        if (dumpAll) {
12634            final int NP = mProcessNames.getMap().size();
12635            for (int ip=0; ip<NP; ip++) {
12636                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12637                final int NA = procs.size();
12638                for (int ia=0; ia<NA; ia++) {
12639                    ProcessRecord r = procs.valueAt(ia);
12640                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12641                        continue;
12642                    }
12643                    if (!needSep) {
12644                        pw.println("  All known processes:");
12645                        needSep = true;
12646                        printedAnything = true;
12647                    }
12648                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12649                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12650                        pw.print(" "); pw.println(r);
12651                    r.dump(pw, "    ");
12652                    if (r.persistent) {
12653                        numPers++;
12654                    }
12655                }
12656            }
12657        }
12658
12659        if (mIsolatedProcesses.size() > 0) {
12660            boolean printed = false;
12661            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12662                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12663                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12664                    continue;
12665                }
12666                if (!printed) {
12667                    if (needSep) {
12668                        pw.println();
12669                    }
12670                    pw.println("  Isolated process list (sorted by uid):");
12671                    printedAnything = true;
12672                    printed = true;
12673                    needSep = true;
12674                }
12675                pw.println(String.format("%sIsolated #%2d: %s",
12676                        "    ", i, r.toString()));
12677            }
12678        }
12679
12680        if (mLruProcesses.size() > 0) {
12681            if (needSep) {
12682                pw.println();
12683            }
12684            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12685                    pw.print(" total, non-act at ");
12686                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12687                    pw.print(", non-svc at ");
12688                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12689                    pw.println("):");
12690            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12691            needSep = true;
12692            printedAnything = true;
12693        }
12694
12695        if (dumpAll || dumpPackage != null) {
12696            synchronized (mPidsSelfLocked) {
12697                boolean printed = false;
12698                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12699                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12700                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12701                        continue;
12702                    }
12703                    if (!printed) {
12704                        if (needSep) pw.println();
12705                        needSep = true;
12706                        pw.println("  PID mappings:");
12707                        printed = true;
12708                        printedAnything = true;
12709                    }
12710                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12711                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12712                }
12713            }
12714        }
12715
12716        if (mForegroundProcesses.size() > 0) {
12717            synchronized (mPidsSelfLocked) {
12718                boolean printed = false;
12719                for (int i=0; i<mForegroundProcesses.size(); i++) {
12720                    ProcessRecord r = mPidsSelfLocked.get(
12721                            mForegroundProcesses.valueAt(i).pid);
12722                    if (dumpPackage != null && (r == null
12723                            || !r.pkgList.containsKey(dumpPackage))) {
12724                        continue;
12725                    }
12726                    if (!printed) {
12727                        if (needSep) pw.println();
12728                        needSep = true;
12729                        pw.println("  Foreground Processes:");
12730                        printed = true;
12731                        printedAnything = true;
12732                    }
12733                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12734                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12735                }
12736            }
12737        }
12738
12739        if (mPersistentStartingProcesses.size() > 0) {
12740            if (needSep) pw.println();
12741            needSep = true;
12742            printedAnything = true;
12743            pw.println("  Persisent processes that are starting:");
12744            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12745                    "Starting Norm", "Restarting PERS", dumpPackage);
12746        }
12747
12748        if (mRemovedProcesses.size() > 0) {
12749            if (needSep) pw.println();
12750            needSep = true;
12751            printedAnything = true;
12752            pw.println("  Processes that are being removed:");
12753            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12754                    "Removed Norm", "Removed PERS", dumpPackage);
12755        }
12756
12757        if (mProcessesOnHold.size() > 0) {
12758            if (needSep) pw.println();
12759            needSep = true;
12760            printedAnything = true;
12761            pw.println("  Processes that are on old until the system is ready:");
12762            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12763                    "OnHold Norm", "OnHold PERS", dumpPackage);
12764        }
12765
12766        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12767
12768        if (mProcessCrashTimes.getMap().size() > 0) {
12769            boolean printed = false;
12770            long now = SystemClock.uptimeMillis();
12771            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12772            final int NP = pmap.size();
12773            for (int ip=0; ip<NP; ip++) {
12774                String pname = pmap.keyAt(ip);
12775                SparseArray<Long> uids = pmap.valueAt(ip);
12776                final int N = uids.size();
12777                for (int i=0; i<N; i++) {
12778                    int puid = uids.keyAt(i);
12779                    ProcessRecord r = mProcessNames.get(pname, puid);
12780                    if (dumpPackage != null && (r == null
12781                            || !r.pkgList.containsKey(dumpPackage))) {
12782                        continue;
12783                    }
12784                    if (!printed) {
12785                        if (needSep) pw.println();
12786                        needSep = true;
12787                        pw.println("  Time since processes crashed:");
12788                        printed = true;
12789                        printedAnything = true;
12790                    }
12791                    pw.print("    Process "); pw.print(pname);
12792                            pw.print(" uid "); pw.print(puid);
12793                            pw.print(": last crashed ");
12794                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12795                            pw.println(" ago");
12796                }
12797            }
12798        }
12799
12800        if (mBadProcesses.getMap().size() > 0) {
12801            boolean printed = false;
12802            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12803            final int NP = pmap.size();
12804            for (int ip=0; ip<NP; ip++) {
12805                String pname = pmap.keyAt(ip);
12806                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12807                final int N = uids.size();
12808                for (int i=0; i<N; i++) {
12809                    int puid = uids.keyAt(i);
12810                    ProcessRecord r = mProcessNames.get(pname, puid);
12811                    if (dumpPackage != null && (r == null
12812                            || !r.pkgList.containsKey(dumpPackage))) {
12813                        continue;
12814                    }
12815                    if (!printed) {
12816                        if (needSep) pw.println();
12817                        needSep = true;
12818                        pw.println("  Bad processes:");
12819                        printedAnything = true;
12820                    }
12821                    BadProcessInfo info = uids.valueAt(i);
12822                    pw.print("    Bad process "); pw.print(pname);
12823                            pw.print(" uid "); pw.print(puid);
12824                            pw.print(": crashed at time "); pw.println(info.time);
12825                    if (info.shortMsg != null) {
12826                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12827                    }
12828                    if (info.longMsg != null) {
12829                        pw.print("      Long msg: "); pw.println(info.longMsg);
12830                    }
12831                    if (info.stack != null) {
12832                        pw.println("      Stack:");
12833                        int lastPos = 0;
12834                        for (int pos=0; pos<info.stack.length(); pos++) {
12835                            if (info.stack.charAt(pos) == '\n') {
12836                                pw.print("        ");
12837                                pw.write(info.stack, lastPos, pos-lastPos);
12838                                pw.println();
12839                                lastPos = pos+1;
12840                            }
12841                        }
12842                        if (lastPos < info.stack.length()) {
12843                            pw.print("        ");
12844                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12845                            pw.println();
12846                        }
12847                    }
12848                }
12849            }
12850        }
12851
12852        if (dumpPackage == null) {
12853            pw.println();
12854            needSep = false;
12855            pw.println("  mStartedUsers:");
12856            for (int i=0; i<mStartedUsers.size(); i++) {
12857                UserStartedState uss = mStartedUsers.valueAt(i);
12858                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12859                        pw.print(": "); uss.dump("", pw);
12860            }
12861            pw.print("  mStartedUserArray: [");
12862            for (int i=0; i<mStartedUserArray.length; i++) {
12863                if (i > 0) pw.print(", ");
12864                pw.print(mStartedUserArray[i]);
12865            }
12866            pw.println("]");
12867            pw.print("  mUserLru: [");
12868            for (int i=0; i<mUserLru.size(); i++) {
12869                if (i > 0) pw.print(", ");
12870                pw.print(mUserLru.get(i));
12871            }
12872            pw.println("]");
12873            if (dumpAll) {
12874                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12875            }
12876            synchronized (mUserProfileGroupIdsSelfLocked) {
12877                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12878                    pw.println("  mUserProfileGroupIds:");
12879                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12880                        pw.print("    User #");
12881                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12882                        pw.print(" -> profile #");
12883                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12884                    }
12885                }
12886            }
12887        }
12888        if (mHomeProcess != null && (dumpPackage == null
12889                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12890            if (needSep) {
12891                pw.println();
12892                needSep = false;
12893            }
12894            pw.println("  mHomeProcess: " + mHomeProcess);
12895        }
12896        if (mPreviousProcess != null && (dumpPackage == null
12897                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12898            if (needSep) {
12899                pw.println();
12900                needSep = false;
12901            }
12902            pw.println("  mPreviousProcess: " + mPreviousProcess);
12903        }
12904        if (dumpAll) {
12905            StringBuilder sb = new StringBuilder(128);
12906            sb.append("  mPreviousProcessVisibleTime: ");
12907            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12908            pw.println(sb);
12909        }
12910        if (mHeavyWeightProcess != null && (dumpPackage == null
12911                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12912            if (needSep) {
12913                pw.println();
12914                needSep = false;
12915            }
12916            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12917        }
12918        if (dumpPackage == null) {
12919            pw.println("  mConfiguration: " + mConfiguration);
12920        }
12921        if (dumpAll) {
12922            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12923            if (mCompatModePackages.getPackages().size() > 0) {
12924                boolean printed = false;
12925                for (Map.Entry<String, Integer> entry
12926                        : mCompatModePackages.getPackages().entrySet()) {
12927                    String pkg = entry.getKey();
12928                    int mode = entry.getValue();
12929                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12930                        continue;
12931                    }
12932                    if (!printed) {
12933                        pw.println("  mScreenCompatPackages:");
12934                        printed = true;
12935                    }
12936                    pw.print("    "); pw.print(pkg); pw.print(": ");
12937                            pw.print(mode); pw.println();
12938                }
12939            }
12940        }
12941        if (dumpPackage == null) {
12942            if (mSleeping || mWentToSleep || mLockScreenShown) {
12943                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12944                        + " mLockScreenShown " + mLockScreenShown);
12945            }
12946            if (mShuttingDown || mRunningVoice) {
12947                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12948            }
12949        }
12950        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12951                || mOrigWaitForDebugger) {
12952            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12953                    || dumpPackage.equals(mOrigDebugApp)) {
12954                if (needSep) {
12955                    pw.println();
12956                    needSep = false;
12957                }
12958                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12959                        + " mDebugTransient=" + mDebugTransient
12960                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12961            }
12962        }
12963        if (mOpenGlTraceApp != null) {
12964            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12965                if (needSep) {
12966                    pw.println();
12967                    needSep = false;
12968                }
12969                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12970            }
12971        }
12972        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12973                || mProfileFd != null) {
12974            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12975                if (needSep) {
12976                    pw.println();
12977                    needSep = false;
12978                }
12979                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12980                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12981                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12982                        + mAutoStopProfiler);
12983                pw.println("  mProfileType=" + mProfileType);
12984            }
12985        }
12986        if (dumpPackage == null) {
12987            if (mAlwaysFinishActivities || mController != null) {
12988                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12989                        + " mController=" + mController);
12990            }
12991            if (dumpAll) {
12992                pw.println("  Total persistent processes: " + numPers);
12993                pw.println("  mProcessesReady=" + mProcessesReady
12994                        + " mSystemReady=" + mSystemReady
12995                        + " mBooted=" + mBooted
12996                        + " mFactoryTest=" + mFactoryTest);
12997                pw.println("  mBooting=" + mBooting
12998                        + " mCallFinishBooting=" + mCallFinishBooting
12999                        + " mBootAnimationComplete=" + mBootAnimationComplete);
13000                pw.print("  mLastPowerCheckRealtime=");
13001                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13002                        pw.println("");
13003                pw.print("  mLastPowerCheckUptime=");
13004                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13005                        pw.println("");
13006                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13007                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13008                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13009                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
13010                        + " (" + mLruProcesses.size() + " total)"
13011                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13012                        + " mNumServiceProcs=" + mNumServiceProcs
13013                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13014                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
13015                        + " mLastMemoryLevel" + mLastMemoryLevel
13016                        + " mLastNumProcesses" + mLastNumProcesses);
13017                long now = SystemClock.uptimeMillis();
13018                pw.print("  mLastIdleTime=");
13019                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
13020                        pw.print(" mLowRamSinceLastIdle=");
13021                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13022                        pw.println();
13023            }
13024        }
13025
13026        if (!printedAnything) {
13027            pw.println("  (nothing)");
13028        }
13029    }
13030
13031    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13032            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13033        if (mProcessesToGc.size() > 0) {
13034            boolean printed = false;
13035            long now = SystemClock.uptimeMillis();
13036            for (int i=0; i<mProcessesToGc.size(); i++) {
13037                ProcessRecord proc = mProcessesToGc.get(i);
13038                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13039                    continue;
13040                }
13041                if (!printed) {
13042                    if (needSep) pw.println();
13043                    needSep = true;
13044                    pw.println("  Processes that are waiting to GC:");
13045                    printed = true;
13046                }
13047                pw.print("    Process "); pw.println(proc);
13048                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13049                        pw.print(", last gced=");
13050                        pw.print(now-proc.lastRequestedGc);
13051                        pw.print(" ms ago, last lowMem=");
13052                        pw.print(now-proc.lastLowMemory);
13053                        pw.println(" ms ago");
13054
13055            }
13056        }
13057        return needSep;
13058    }
13059
13060    void printOomLevel(PrintWriter pw, String name, int adj) {
13061        pw.print("    ");
13062        if (adj >= 0) {
13063            pw.print(' ');
13064            if (adj < 10) pw.print(' ');
13065        } else {
13066            if (adj > -10) pw.print(' ');
13067        }
13068        pw.print(adj);
13069        pw.print(": ");
13070        pw.print(name);
13071        pw.print(" (");
13072        pw.print(mProcessList.getMemLevel(adj)/1024);
13073        pw.println(" kB)");
13074    }
13075
13076    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13077            int opti, boolean dumpAll) {
13078        boolean needSep = false;
13079
13080        if (mLruProcesses.size() > 0) {
13081            if (needSep) pw.println();
13082            needSep = true;
13083            pw.println("  OOM levels:");
13084            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13085            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13086            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13087            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13088            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13089            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13090            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13091            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13092            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13093            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13094            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13095            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13096            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13097            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13098
13099            if (needSep) pw.println();
13100            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13101                    pw.print(" total, non-act at ");
13102                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13103                    pw.print(", non-svc at ");
13104                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13105                    pw.println("):");
13106            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13107            needSep = true;
13108        }
13109
13110        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13111
13112        pw.println();
13113        pw.println("  mHomeProcess: " + mHomeProcess);
13114        pw.println("  mPreviousProcess: " + mPreviousProcess);
13115        if (mHeavyWeightProcess != null) {
13116            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13117        }
13118
13119        return true;
13120    }
13121
13122    /**
13123     * There are three ways to call this:
13124     *  - no provider specified: dump all the providers
13125     *  - a flattened component name that matched an existing provider was specified as the
13126     *    first arg: dump that one provider
13127     *  - the first arg isn't the flattened component name of an existing provider:
13128     *    dump all providers whose component contains the first arg as a substring
13129     */
13130    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13131            int opti, boolean dumpAll) {
13132        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13133    }
13134
13135    static class ItemMatcher {
13136        ArrayList<ComponentName> components;
13137        ArrayList<String> strings;
13138        ArrayList<Integer> objects;
13139        boolean all;
13140
13141        ItemMatcher() {
13142            all = true;
13143        }
13144
13145        void build(String name) {
13146            ComponentName componentName = ComponentName.unflattenFromString(name);
13147            if (componentName != null) {
13148                if (components == null) {
13149                    components = new ArrayList<ComponentName>();
13150                }
13151                components.add(componentName);
13152                all = false;
13153            } else {
13154                int objectId = 0;
13155                // Not a '/' separated full component name; maybe an object ID?
13156                try {
13157                    objectId = Integer.parseInt(name, 16);
13158                    if (objects == null) {
13159                        objects = new ArrayList<Integer>();
13160                    }
13161                    objects.add(objectId);
13162                    all = false;
13163                } catch (RuntimeException e) {
13164                    // Not an integer; just do string match.
13165                    if (strings == null) {
13166                        strings = new ArrayList<String>();
13167                    }
13168                    strings.add(name);
13169                    all = false;
13170                }
13171            }
13172        }
13173
13174        int build(String[] args, int opti) {
13175            for (; opti<args.length; opti++) {
13176                String name = args[opti];
13177                if ("--".equals(name)) {
13178                    return opti+1;
13179                }
13180                build(name);
13181            }
13182            return opti;
13183        }
13184
13185        boolean match(Object object, ComponentName comp) {
13186            if (all) {
13187                return true;
13188            }
13189            if (components != null) {
13190                for (int i=0; i<components.size(); i++) {
13191                    if (components.get(i).equals(comp)) {
13192                        return true;
13193                    }
13194                }
13195            }
13196            if (objects != null) {
13197                for (int i=0; i<objects.size(); i++) {
13198                    if (System.identityHashCode(object) == objects.get(i)) {
13199                        return true;
13200                    }
13201                }
13202            }
13203            if (strings != null) {
13204                String flat = comp.flattenToString();
13205                for (int i=0; i<strings.size(); i++) {
13206                    if (flat.contains(strings.get(i))) {
13207                        return true;
13208                    }
13209                }
13210            }
13211            return false;
13212        }
13213    }
13214
13215    /**
13216     * There are three things that cmd can be:
13217     *  - a flattened component name that matches an existing activity
13218     *  - the cmd arg isn't the flattened component name of an existing activity:
13219     *    dump all activity whose component contains the cmd as a substring
13220     *  - A hex number of the ActivityRecord object instance.
13221     */
13222    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13223            int opti, boolean dumpAll) {
13224        ArrayList<ActivityRecord> activities;
13225
13226        synchronized (this) {
13227            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13228        }
13229
13230        if (activities.size() <= 0) {
13231            return false;
13232        }
13233
13234        String[] newArgs = new String[args.length - opti];
13235        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13236
13237        TaskRecord lastTask = null;
13238        boolean needSep = false;
13239        for (int i=activities.size()-1; i>=0; i--) {
13240            ActivityRecord r = activities.get(i);
13241            if (needSep) {
13242                pw.println();
13243            }
13244            needSep = true;
13245            synchronized (this) {
13246                if (lastTask != r.task) {
13247                    lastTask = r.task;
13248                    pw.print("TASK "); pw.print(lastTask.affinity);
13249                            pw.print(" id="); pw.println(lastTask.taskId);
13250                    if (dumpAll) {
13251                        lastTask.dump(pw, "  ");
13252                    }
13253                }
13254            }
13255            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13256        }
13257        return true;
13258    }
13259
13260    /**
13261     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13262     * there is a thread associated with the activity.
13263     */
13264    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13265            final ActivityRecord r, String[] args, boolean dumpAll) {
13266        String innerPrefix = prefix + "  ";
13267        synchronized (this) {
13268            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13269                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13270                    pw.print(" pid=");
13271                    if (r.app != null) pw.println(r.app.pid);
13272                    else pw.println("(not running)");
13273            if (dumpAll) {
13274                r.dump(pw, innerPrefix);
13275            }
13276        }
13277        if (r.app != null && r.app.thread != null) {
13278            // flush anything that is already in the PrintWriter since the thread is going
13279            // to write to the file descriptor directly
13280            pw.flush();
13281            try {
13282                TransferPipe tp = new TransferPipe();
13283                try {
13284                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13285                            r.appToken, innerPrefix, args);
13286                    tp.go(fd);
13287                } finally {
13288                    tp.kill();
13289                }
13290            } catch (IOException e) {
13291                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13292            } catch (RemoteException e) {
13293                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13294            }
13295        }
13296    }
13297
13298    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13299            int opti, boolean dumpAll, String dumpPackage) {
13300        boolean needSep = false;
13301        boolean onlyHistory = false;
13302        boolean printedAnything = false;
13303
13304        if ("history".equals(dumpPackage)) {
13305            if (opti < args.length && "-s".equals(args[opti])) {
13306                dumpAll = false;
13307            }
13308            onlyHistory = true;
13309            dumpPackage = null;
13310        }
13311
13312        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13313        if (!onlyHistory && dumpAll) {
13314            if (mRegisteredReceivers.size() > 0) {
13315                boolean printed = false;
13316                Iterator it = mRegisteredReceivers.values().iterator();
13317                while (it.hasNext()) {
13318                    ReceiverList r = (ReceiverList)it.next();
13319                    if (dumpPackage != null && (r.app == null ||
13320                            !dumpPackage.equals(r.app.info.packageName))) {
13321                        continue;
13322                    }
13323                    if (!printed) {
13324                        pw.println("  Registered Receivers:");
13325                        needSep = true;
13326                        printed = true;
13327                        printedAnything = true;
13328                    }
13329                    pw.print("  * "); pw.println(r);
13330                    r.dump(pw, "    ");
13331                }
13332            }
13333
13334            if (mReceiverResolver.dump(pw, needSep ?
13335                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13336                    "    ", dumpPackage, false)) {
13337                needSep = true;
13338                printedAnything = true;
13339            }
13340        }
13341
13342        for (BroadcastQueue q : mBroadcastQueues) {
13343            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13344            printedAnything |= needSep;
13345        }
13346
13347        needSep = true;
13348
13349        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13350            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13351                if (needSep) {
13352                    pw.println();
13353                }
13354                needSep = true;
13355                printedAnything = true;
13356                pw.print("  Sticky broadcasts for user ");
13357                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13358                StringBuilder sb = new StringBuilder(128);
13359                for (Map.Entry<String, ArrayList<Intent>> ent
13360                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13361                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13362                    if (dumpAll) {
13363                        pw.println(":");
13364                        ArrayList<Intent> intents = ent.getValue();
13365                        final int N = intents.size();
13366                        for (int i=0; i<N; i++) {
13367                            sb.setLength(0);
13368                            sb.append("    Intent: ");
13369                            intents.get(i).toShortString(sb, false, true, false, false);
13370                            pw.println(sb.toString());
13371                            Bundle bundle = intents.get(i).getExtras();
13372                            if (bundle != null) {
13373                                pw.print("      ");
13374                                pw.println(bundle.toString());
13375                            }
13376                        }
13377                    } else {
13378                        pw.println("");
13379                    }
13380                }
13381            }
13382        }
13383
13384        if (!onlyHistory && dumpAll) {
13385            pw.println();
13386            for (BroadcastQueue queue : mBroadcastQueues) {
13387                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13388                        + queue.mBroadcastsScheduled);
13389            }
13390            pw.println("  mHandler:");
13391            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13392            needSep = true;
13393            printedAnything = true;
13394        }
13395
13396        if (!printedAnything) {
13397            pw.println("  (nothing)");
13398        }
13399    }
13400
13401    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13402            int opti, boolean dumpAll, String dumpPackage) {
13403        boolean needSep;
13404        boolean printedAnything = false;
13405
13406        ItemMatcher matcher = new ItemMatcher();
13407        matcher.build(args, opti);
13408
13409        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13410
13411        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13412        printedAnything |= needSep;
13413
13414        if (mLaunchingProviders.size() > 0) {
13415            boolean printed = false;
13416            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13417                ContentProviderRecord r = mLaunchingProviders.get(i);
13418                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13419                    continue;
13420                }
13421                if (!printed) {
13422                    if (needSep) pw.println();
13423                    needSep = true;
13424                    pw.println("  Launching content providers:");
13425                    printed = true;
13426                    printedAnything = true;
13427                }
13428                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13429                        pw.println(r);
13430            }
13431        }
13432
13433        if (mGrantedUriPermissions.size() > 0) {
13434            boolean printed = false;
13435            int dumpUid = -2;
13436            if (dumpPackage != null) {
13437                try {
13438                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13439                } catch (NameNotFoundException e) {
13440                    dumpUid = -1;
13441                }
13442            }
13443            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13444                int uid = mGrantedUriPermissions.keyAt(i);
13445                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13446                    continue;
13447                }
13448                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13449                if (!printed) {
13450                    if (needSep) pw.println();
13451                    needSep = true;
13452                    pw.println("  Granted Uri Permissions:");
13453                    printed = true;
13454                    printedAnything = true;
13455                }
13456                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13457                for (UriPermission perm : perms.values()) {
13458                    pw.print("    "); pw.println(perm);
13459                    if (dumpAll) {
13460                        perm.dump(pw, "      ");
13461                    }
13462                }
13463            }
13464        }
13465
13466        if (!printedAnything) {
13467            pw.println("  (nothing)");
13468        }
13469    }
13470
13471    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13472            int opti, boolean dumpAll, String dumpPackage) {
13473        boolean printed = false;
13474
13475        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13476
13477        if (mIntentSenderRecords.size() > 0) {
13478            Iterator<WeakReference<PendingIntentRecord>> it
13479                    = mIntentSenderRecords.values().iterator();
13480            while (it.hasNext()) {
13481                WeakReference<PendingIntentRecord> ref = it.next();
13482                PendingIntentRecord rec = ref != null ? ref.get(): null;
13483                if (dumpPackage != null && (rec == null
13484                        || !dumpPackage.equals(rec.key.packageName))) {
13485                    continue;
13486                }
13487                printed = true;
13488                if (rec != null) {
13489                    pw.print("  * "); pw.println(rec);
13490                    if (dumpAll) {
13491                        rec.dump(pw, "    ");
13492                    }
13493                } else {
13494                    pw.print("  * "); pw.println(ref);
13495                }
13496            }
13497        }
13498
13499        if (!printed) {
13500            pw.println("  (nothing)");
13501        }
13502    }
13503
13504    private static final int dumpProcessList(PrintWriter pw,
13505            ActivityManagerService service, List list,
13506            String prefix, String normalLabel, String persistentLabel,
13507            String dumpPackage) {
13508        int numPers = 0;
13509        final int N = list.size()-1;
13510        for (int i=N; i>=0; i--) {
13511            ProcessRecord r = (ProcessRecord)list.get(i);
13512            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13513                continue;
13514            }
13515            pw.println(String.format("%s%s #%2d: %s",
13516                    prefix, (r.persistent ? persistentLabel : normalLabel),
13517                    i, r.toString()));
13518            if (r.persistent) {
13519                numPers++;
13520            }
13521        }
13522        return numPers;
13523    }
13524
13525    private static final boolean dumpProcessOomList(PrintWriter pw,
13526            ActivityManagerService service, List<ProcessRecord> origList,
13527            String prefix, String normalLabel, String persistentLabel,
13528            boolean inclDetails, String dumpPackage) {
13529
13530        ArrayList<Pair<ProcessRecord, Integer>> list
13531                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13532        for (int i=0; i<origList.size(); i++) {
13533            ProcessRecord r = origList.get(i);
13534            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13535                continue;
13536            }
13537            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13538        }
13539
13540        if (list.size() <= 0) {
13541            return false;
13542        }
13543
13544        Comparator<Pair<ProcessRecord, Integer>> comparator
13545                = new Comparator<Pair<ProcessRecord, Integer>>() {
13546            @Override
13547            public int compare(Pair<ProcessRecord, Integer> object1,
13548                    Pair<ProcessRecord, Integer> object2) {
13549                if (object1.first.setAdj != object2.first.setAdj) {
13550                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13551                }
13552                if (object1.second.intValue() != object2.second.intValue()) {
13553                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13554                }
13555                return 0;
13556            }
13557        };
13558
13559        Collections.sort(list, comparator);
13560
13561        final long curRealtime = SystemClock.elapsedRealtime();
13562        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13563        final long curUptime = SystemClock.uptimeMillis();
13564        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13565
13566        for (int i=list.size()-1; i>=0; i--) {
13567            ProcessRecord r = list.get(i).first;
13568            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13569            char schedGroup;
13570            switch (r.setSchedGroup) {
13571                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13572                    schedGroup = 'B';
13573                    break;
13574                case Process.THREAD_GROUP_DEFAULT:
13575                    schedGroup = 'F';
13576                    break;
13577                default:
13578                    schedGroup = '?';
13579                    break;
13580            }
13581            char foreground;
13582            if (r.foregroundActivities) {
13583                foreground = 'A';
13584            } else if (r.foregroundServices) {
13585                foreground = 'S';
13586            } else {
13587                foreground = ' ';
13588            }
13589            String procState = ProcessList.makeProcStateString(r.curProcState);
13590            pw.print(prefix);
13591            pw.print(r.persistent ? persistentLabel : normalLabel);
13592            pw.print(" #");
13593            int num = (origList.size()-1)-list.get(i).second;
13594            if (num < 10) pw.print(' ');
13595            pw.print(num);
13596            pw.print(": ");
13597            pw.print(oomAdj);
13598            pw.print(' ');
13599            pw.print(schedGroup);
13600            pw.print('/');
13601            pw.print(foreground);
13602            pw.print('/');
13603            pw.print(procState);
13604            pw.print(" trm:");
13605            if (r.trimMemoryLevel < 10) pw.print(' ');
13606            pw.print(r.trimMemoryLevel);
13607            pw.print(' ');
13608            pw.print(r.toShortString());
13609            pw.print(" (");
13610            pw.print(r.adjType);
13611            pw.println(')');
13612            if (r.adjSource != null || r.adjTarget != null) {
13613                pw.print(prefix);
13614                pw.print("    ");
13615                if (r.adjTarget instanceof ComponentName) {
13616                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13617                } else if (r.adjTarget != null) {
13618                    pw.print(r.adjTarget.toString());
13619                } else {
13620                    pw.print("{null}");
13621                }
13622                pw.print("<=");
13623                if (r.adjSource instanceof ProcessRecord) {
13624                    pw.print("Proc{");
13625                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13626                    pw.println("}");
13627                } else if (r.adjSource != null) {
13628                    pw.println(r.adjSource.toString());
13629                } else {
13630                    pw.println("{null}");
13631                }
13632            }
13633            if (inclDetails) {
13634                pw.print(prefix);
13635                pw.print("    ");
13636                pw.print("oom: max="); pw.print(r.maxAdj);
13637                pw.print(" curRaw="); pw.print(r.curRawAdj);
13638                pw.print(" setRaw="); pw.print(r.setRawAdj);
13639                pw.print(" cur="); pw.print(r.curAdj);
13640                pw.print(" set="); pw.println(r.setAdj);
13641                pw.print(prefix);
13642                pw.print("    ");
13643                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13644                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13645                pw.print(" lastPss="); pw.print(r.lastPss);
13646                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13647                pw.print(prefix);
13648                pw.print("    ");
13649                pw.print("cached="); pw.print(r.cached);
13650                pw.print(" empty="); pw.print(r.empty);
13651                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13652
13653                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13654                    if (r.lastWakeTime != 0) {
13655                        long wtime;
13656                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13657                        synchronized (stats) {
13658                            wtime = stats.getProcessWakeTime(r.info.uid,
13659                                    r.pid, curRealtime);
13660                        }
13661                        long timeUsed = wtime - r.lastWakeTime;
13662                        pw.print(prefix);
13663                        pw.print("    ");
13664                        pw.print("keep awake over ");
13665                        TimeUtils.formatDuration(realtimeSince, pw);
13666                        pw.print(" used ");
13667                        TimeUtils.formatDuration(timeUsed, pw);
13668                        pw.print(" (");
13669                        pw.print((timeUsed*100)/realtimeSince);
13670                        pw.println("%)");
13671                    }
13672                    if (r.lastCpuTime != 0) {
13673                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13674                        pw.print(prefix);
13675                        pw.print("    ");
13676                        pw.print("run cpu over ");
13677                        TimeUtils.formatDuration(uptimeSince, pw);
13678                        pw.print(" used ");
13679                        TimeUtils.formatDuration(timeUsed, pw);
13680                        pw.print(" (");
13681                        pw.print((timeUsed*100)/uptimeSince);
13682                        pw.println("%)");
13683                    }
13684                }
13685            }
13686        }
13687        return true;
13688    }
13689
13690    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13691            String[] args) {
13692        ArrayList<ProcessRecord> procs;
13693        synchronized (this) {
13694            if (args != null && args.length > start
13695                    && args[start].charAt(0) != '-') {
13696                procs = new ArrayList<ProcessRecord>();
13697                int pid = -1;
13698                try {
13699                    pid = Integer.parseInt(args[start]);
13700                } catch (NumberFormatException e) {
13701                }
13702                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13703                    ProcessRecord proc = mLruProcesses.get(i);
13704                    if (proc.pid == pid) {
13705                        procs.add(proc);
13706                    } else if (allPkgs && proc.pkgList != null
13707                            && proc.pkgList.containsKey(args[start])) {
13708                        procs.add(proc);
13709                    } else if (proc.processName.equals(args[start])) {
13710                        procs.add(proc);
13711                    }
13712                }
13713                if (procs.size() <= 0) {
13714                    return null;
13715                }
13716            } else {
13717                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13718            }
13719        }
13720        return procs;
13721    }
13722
13723    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13724            PrintWriter pw, String[] args) {
13725        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13726        if (procs == null) {
13727            pw.println("No process found for: " + args[0]);
13728            return;
13729        }
13730
13731        long uptime = SystemClock.uptimeMillis();
13732        long realtime = SystemClock.elapsedRealtime();
13733        pw.println("Applications Graphics Acceleration Info:");
13734        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13735
13736        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13737            ProcessRecord r = procs.get(i);
13738            if (r.thread != null) {
13739                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13740                pw.flush();
13741                try {
13742                    TransferPipe tp = new TransferPipe();
13743                    try {
13744                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13745                        tp.go(fd);
13746                    } finally {
13747                        tp.kill();
13748                    }
13749                } catch (IOException e) {
13750                    pw.println("Failure while dumping the app: " + r);
13751                    pw.flush();
13752                } catch (RemoteException e) {
13753                    pw.println("Got a RemoteException while dumping the app " + r);
13754                    pw.flush();
13755                }
13756            }
13757        }
13758    }
13759
13760    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13761        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13762        if (procs == null) {
13763            pw.println("No process found for: " + args[0]);
13764            return;
13765        }
13766
13767        pw.println("Applications Database Info:");
13768
13769        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13770            ProcessRecord r = procs.get(i);
13771            if (r.thread != null) {
13772                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13773                pw.flush();
13774                try {
13775                    TransferPipe tp = new TransferPipe();
13776                    try {
13777                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13778                        tp.go(fd);
13779                    } finally {
13780                        tp.kill();
13781                    }
13782                } catch (IOException e) {
13783                    pw.println("Failure while dumping the app: " + r);
13784                    pw.flush();
13785                } catch (RemoteException e) {
13786                    pw.println("Got a RemoteException while dumping the app " + r);
13787                    pw.flush();
13788                }
13789            }
13790        }
13791    }
13792
13793    final static class MemItem {
13794        final boolean isProc;
13795        final String label;
13796        final String shortLabel;
13797        final long pss;
13798        final int id;
13799        final boolean hasActivities;
13800        ArrayList<MemItem> subitems;
13801
13802        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13803                boolean _hasActivities) {
13804            isProc = true;
13805            label = _label;
13806            shortLabel = _shortLabel;
13807            pss = _pss;
13808            id = _id;
13809            hasActivities = _hasActivities;
13810        }
13811
13812        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13813            isProc = false;
13814            label = _label;
13815            shortLabel = _shortLabel;
13816            pss = _pss;
13817            id = _id;
13818            hasActivities = false;
13819        }
13820    }
13821
13822    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13823            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13824        if (sort && !isCompact) {
13825            Collections.sort(items, new Comparator<MemItem>() {
13826                @Override
13827                public int compare(MemItem lhs, MemItem rhs) {
13828                    if (lhs.pss < rhs.pss) {
13829                        return 1;
13830                    } else if (lhs.pss > rhs.pss) {
13831                        return -1;
13832                    }
13833                    return 0;
13834                }
13835            });
13836        }
13837
13838        for (int i=0; i<items.size(); i++) {
13839            MemItem mi = items.get(i);
13840            if (!isCompact) {
13841                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13842            } else if (mi.isProc) {
13843                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13844                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13845                pw.println(mi.hasActivities ? ",a" : ",e");
13846            } else {
13847                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13848                pw.println(mi.pss);
13849            }
13850            if (mi.subitems != null) {
13851                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13852                        true, isCompact);
13853            }
13854        }
13855    }
13856
13857    // These are in KB.
13858    static final long[] DUMP_MEM_BUCKETS = new long[] {
13859        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13860        120*1024, 160*1024, 200*1024,
13861        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13862        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13863    };
13864
13865    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13866            boolean stackLike) {
13867        int start = label.lastIndexOf('.');
13868        if (start >= 0) start++;
13869        else start = 0;
13870        int end = label.length();
13871        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13872            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13873                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13874                out.append(bucket);
13875                out.append(stackLike ? "MB." : "MB ");
13876                out.append(label, start, end);
13877                return;
13878            }
13879        }
13880        out.append(memKB/1024);
13881        out.append(stackLike ? "MB." : "MB ");
13882        out.append(label, start, end);
13883    }
13884
13885    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13886            ProcessList.NATIVE_ADJ,
13887            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13888            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13889            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13890            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13891            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13892            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13893    };
13894    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13895            "Native",
13896            "System", "Persistent", "Persistent Service", "Foreground",
13897            "Visible", "Perceptible",
13898            "Heavy Weight", "Backup",
13899            "A Services", "Home",
13900            "Previous", "B Services", "Cached"
13901    };
13902    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13903            "native",
13904            "sys", "pers", "persvc", "fore",
13905            "vis", "percept",
13906            "heavy", "backup",
13907            "servicea", "home",
13908            "prev", "serviceb", "cached"
13909    };
13910
13911    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13912            long realtime, boolean isCheckinRequest, boolean isCompact) {
13913        if (isCheckinRequest || isCompact) {
13914            // short checkin version
13915            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13916        } else {
13917            pw.println("Applications Memory Usage (kB):");
13918            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13919        }
13920    }
13921
13922    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13923            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13924        boolean dumpDetails = false;
13925        boolean dumpFullDetails = false;
13926        boolean dumpDalvik = false;
13927        boolean oomOnly = false;
13928        boolean isCompact = false;
13929        boolean localOnly = false;
13930        boolean packages = false;
13931
13932        int opti = 0;
13933        while (opti < args.length) {
13934            String opt = args[opti];
13935            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13936                break;
13937            }
13938            opti++;
13939            if ("-a".equals(opt)) {
13940                dumpDetails = true;
13941                dumpFullDetails = true;
13942                dumpDalvik = true;
13943            } else if ("-d".equals(opt)) {
13944                dumpDalvik = true;
13945            } else if ("-c".equals(opt)) {
13946                isCompact = true;
13947            } else if ("--oom".equals(opt)) {
13948                oomOnly = true;
13949            } else if ("--local".equals(opt)) {
13950                localOnly = true;
13951            } else if ("--package".equals(opt)) {
13952                packages = true;
13953            } else if ("-h".equals(opt)) {
13954                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13955                pw.println("  -a: include all available information for each process.");
13956                pw.println("  -d: include dalvik details when dumping process details.");
13957                pw.println("  -c: dump in a compact machine-parseable representation.");
13958                pw.println("  --oom: only show processes organized by oom adj.");
13959                pw.println("  --local: only collect details locally, don't call process.");
13960                pw.println("  --package: interpret process arg as package, dumping all");
13961                pw.println("             processes that have loaded that package.");
13962                pw.println("If [process] is specified it can be the name or ");
13963                pw.println("pid of a specific process to dump.");
13964                return;
13965            } else {
13966                pw.println("Unknown argument: " + opt + "; use -h for help");
13967            }
13968        }
13969
13970        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13971        long uptime = SystemClock.uptimeMillis();
13972        long realtime = SystemClock.elapsedRealtime();
13973        final long[] tmpLong = new long[1];
13974
13975        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13976        if (procs == null) {
13977            // No Java processes.  Maybe they want to print a native process.
13978            if (args != null && args.length > opti
13979                    && args[opti].charAt(0) != '-') {
13980                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13981                        = new ArrayList<ProcessCpuTracker.Stats>();
13982                updateCpuStatsNow();
13983                int findPid = -1;
13984                try {
13985                    findPid = Integer.parseInt(args[opti]);
13986                } catch (NumberFormatException e) {
13987                }
13988                synchronized (mProcessCpuTracker) {
13989                    final int N = mProcessCpuTracker.countStats();
13990                    for (int i=0; i<N; i++) {
13991                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13992                        if (st.pid == findPid || (st.baseName != null
13993                                && st.baseName.equals(args[opti]))) {
13994                            nativeProcs.add(st);
13995                        }
13996                    }
13997                }
13998                if (nativeProcs.size() > 0) {
13999                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14000                            isCompact);
14001                    Debug.MemoryInfo mi = null;
14002                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14003                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14004                        final int pid = r.pid;
14005                        if (!isCheckinRequest && dumpDetails) {
14006                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14007                        }
14008                        if (mi == null) {
14009                            mi = new Debug.MemoryInfo();
14010                        }
14011                        if (dumpDetails || (!brief && !oomOnly)) {
14012                            Debug.getMemoryInfo(pid, mi);
14013                        } else {
14014                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
14015                            mi.dalvikPrivateDirty = (int)tmpLong[0];
14016                        }
14017                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14018                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14019                        if (isCheckinRequest) {
14020                            pw.println();
14021                        }
14022                    }
14023                    return;
14024                }
14025            }
14026            pw.println("No process found for: " + args[opti]);
14027            return;
14028        }
14029
14030        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14031            dumpDetails = true;
14032        }
14033
14034        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14035
14036        String[] innerArgs = new String[args.length-opti];
14037        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14038
14039        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14040        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14041        long nativePss=0, dalvikPss=0, otherPss=0;
14042        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14043
14044        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14045        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14046                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14047
14048        long totalPss = 0;
14049        long cachedPss = 0;
14050
14051        Debug.MemoryInfo mi = null;
14052        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14053            final ProcessRecord r = procs.get(i);
14054            final IApplicationThread thread;
14055            final int pid;
14056            final int oomAdj;
14057            final boolean hasActivities;
14058            synchronized (this) {
14059                thread = r.thread;
14060                pid = r.pid;
14061                oomAdj = r.getSetAdjWithServices();
14062                hasActivities = r.activities.size() > 0;
14063            }
14064            if (thread != null) {
14065                if (!isCheckinRequest && dumpDetails) {
14066                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14067                }
14068                if (mi == null) {
14069                    mi = new Debug.MemoryInfo();
14070                }
14071                if (dumpDetails || (!brief && !oomOnly)) {
14072                    Debug.getMemoryInfo(pid, mi);
14073                } else {
14074                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
14075                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14076                }
14077                if (dumpDetails) {
14078                    if (localOnly) {
14079                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14080                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14081                        if (isCheckinRequest) {
14082                            pw.println();
14083                        }
14084                    } else {
14085                        try {
14086                            pw.flush();
14087                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14088                                    dumpDalvik, innerArgs);
14089                        } catch (RemoteException e) {
14090                            if (!isCheckinRequest) {
14091                                pw.println("Got RemoteException!");
14092                                pw.flush();
14093                            }
14094                        }
14095                    }
14096                }
14097
14098                final long myTotalPss = mi.getTotalPss();
14099                final long myTotalUss = mi.getTotalUss();
14100
14101                synchronized (this) {
14102                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14103                        // Record this for posterity if the process has been stable.
14104                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14105                    }
14106                }
14107
14108                if (!isCheckinRequest && mi != null) {
14109                    totalPss += myTotalPss;
14110                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14111                            (hasActivities ? " / activities)" : ")"),
14112                            r.processName, myTotalPss, pid, hasActivities);
14113                    procMems.add(pssItem);
14114                    procMemsMap.put(pid, pssItem);
14115
14116                    nativePss += mi.nativePss;
14117                    dalvikPss += mi.dalvikPss;
14118                    otherPss += mi.otherPss;
14119                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14120                        long mem = mi.getOtherPss(j);
14121                        miscPss[j] += mem;
14122                        otherPss -= mem;
14123                    }
14124
14125                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14126                        cachedPss += myTotalPss;
14127                    }
14128
14129                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14130                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14131                                || oomIndex == (oomPss.length-1)) {
14132                            oomPss[oomIndex] += myTotalPss;
14133                            if (oomProcs[oomIndex] == null) {
14134                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14135                            }
14136                            oomProcs[oomIndex].add(pssItem);
14137                            break;
14138                        }
14139                    }
14140                }
14141            }
14142        }
14143
14144        long nativeProcTotalPss = 0;
14145
14146        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14147            // If we are showing aggregations, also look for native processes to
14148            // include so that our aggregations are more accurate.
14149            updateCpuStatsNow();
14150            synchronized (mProcessCpuTracker) {
14151                final int N = mProcessCpuTracker.countStats();
14152                for (int i=0; i<N; i++) {
14153                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14154                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14155                        if (mi == null) {
14156                            mi = new Debug.MemoryInfo();
14157                        }
14158                        if (!brief && !oomOnly) {
14159                            Debug.getMemoryInfo(st.pid, mi);
14160                        } else {
14161                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14162                            mi.nativePrivateDirty = (int)tmpLong[0];
14163                        }
14164
14165                        final long myTotalPss = mi.getTotalPss();
14166                        totalPss += myTotalPss;
14167                        nativeProcTotalPss += myTotalPss;
14168
14169                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14170                                st.name, myTotalPss, st.pid, false);
14171                        procMems.add(pssItem);
14172
14173                        nativePss += mi.nativePss;
14174                        dalvikPss += mi.dalvikPss;
14175                        otherPss += mi.otherPss;
14176                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14177                            long mem = mi.getOtherPss(j);
14178                            miscPss[j] += mem;
14179                            otherPss -= mem;
14180                        }
14181                        oomPss[0] += myTotalPss;
14182                        if (oomProcs[0] == null) {
14183                            oomProcs[0] = new ArrayList<MemItem>();
14184                        }
14185                        oomProcs[0].add(pssItem);
14186                    }
14187                }
14188            }
14189
14190            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14191
14192            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14193            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14194            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14195            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14196                String label = Debug.MemoryInfo.getOtherLabel(j);
14197                catMems.add(new MemItem(label, label, miscPss[j], j));
14198            }
14199
14200            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14201            for (int j=0; j<oomPss.length; j++) {
14202                if (oomPss[j] != 0) {
14203                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14204                            : DUMP_MEM_OOM_LABEL[j];
14205                    MemItem item = new MemItem(label, label, oomPss[j],
14206                            DUMP_MEM_OOM_ADJ[j]);
14207                    item.subitems = oomProcs[j];
14208                    oomMems.add(item);
14209                }
14210            }
14211
14212            if (!brief && !oomOnly && !isCompact) {
14213                pw.println();
14214                pw.println("Total PSS by process:");
14215                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14216                pw.println();
14217            }
14218            if (!isCompact) {
14219                pw.println("Total PSS by OOM adjustment:");
14220            }
14221            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14222            if (!brief && !oomOnly) {
14223                PrintWriter out = categoryPw != null ? categoryPw : pw;
14224                if (!isCompact) {
14225                    out.println();
14226                    out.println("Total PSS by category:");
14227                }
14228                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14229            }
14230            if (!isCompact) {
14231                pw.println();
14232            }
14233            MemInfoReader memInfo = new MemInfoReader();
14234            memInfo.readMemInfo();
14235            if (nativeProcTotalPss > 0) {
14236                synchronized (this) {
14237                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14238                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14239                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
14240                            nativeProcTotalPss);
14241                }
14242            }
14243            if (!brief) {
14244                if (!isCompact) {
14245                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14246                    pw.print(" kB (status ");
14247                    switch (mLastMemoryLevel) {
14248                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14249                            pw.println("normal)");
14250                            break;
14251                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14252                            pw.println("moderate)");
14253                            break;
14254                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14255                            pw.println("low)");
14256                            break;
14257                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14258                            pw.println("critical)");
14259                            break;
14260                        default:
14261                            pw.print(mLastMemoryLevel);
14262                            pw.println(")");
14263                            break;
14264                    }
14265                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14266                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14267                            pw.print(cachedPss); pw.print(" cached pss + ");
14268                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
14269                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14270                } else {
14271                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14272                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14273                            + memInfo.getFreeSizeKb()); pw.print(",");
14274                    pw.println(totalPss - cachedPss);
14275                }
14276            }
14277            if (!isCompact) {
14278                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14279                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
14280                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
14281                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14282                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
14283                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
14284                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
14285                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14286                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14287                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
14288                        - memInfo.getSlabSizeKb()); pw.println(" kB");
14289            }
14290            if (!brief) {
14291                if (memInfo.getZramTotalSizeKb() != 0) {
14292                    if (!isCompact) {
14293                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14294                                pw.print(" kB physical used for ");
14295                                pw.print(memInfo.getSwapTotalSizeKb()
14296                                        - memInfo.getSwapFreeSizeKb());
14297                                pw.print(" kB in swap (");
14298                                pw.print(memInfo.getSwapTotalSizeKb());
14299                                pw.println(" kB total swap)");
14300                    } else {
14301                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14302                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14303                                pw.println(memInfo.getSwapFreeSizeKb());
14304                    }
14305                }
14306                final int[] SINGLE_LONG_FORMAT = new int[] {
14307                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14308                };
14309                long[] longOut = new long[1];
14310                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14311                        SINGLE_LONG_FORMAT, null, longOut, null);
14312                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14313                longOut[0] = 0;
14314                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14315                        SINGLE_LONG_FORMAT, null, longOut, null);
14316                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14317                longOut[0] = 0;
14318                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14319                        SINGLE_LONG_FORMAT, null, longOut, null);
14320                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14321                longOut[0] = 0;
14322                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14323                        SINGLE_LONG_FORMAT, null, longOut, null);
14324                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14325                if (!isCompact) {
14326                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
14327                        pw.print("      KSM: "); pw.print(sharing);
14328                                pw.print(" kB saved from shared ");
14329                                pw.print(shared); pw.println(" kB");
14330                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
14331                                pw.print(voltile); pw.println(" kB volatile");
14332                    }
14333                    pw.print("   Tuning: ");
14334                    pw.print(ActivityManager.staticGetMemoryClass());
14335                    pw.print(" (large ");
14336                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14337                    pw.print("), oom ");
14338                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14339                    pw.print(" kB");
14340                    pw.print(", restore limit ");
14341                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14342                    pw.print(" kB");
14343                    if (ActivityManager.isLowRamDeviceStatic()) {
14344                        pw.print(" (low-ram)");
14345                    }
14346                    if (ActivityManager.isHighEndGfx()) {
14347                        pw.print(" (high-end-gfx)");
14348                    }
14349                    pw.println();
14350                } else {
14351                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
14352                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
14353                    pw.println(voltile);
14354                    pw.print("tuning,");
14355                    pw.print(ActivityManager.staticGetMemoryClass());
14356                    pw.print(',');
14357                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14358                    pw.print(',');
14359                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14360                    if (ActivityManager.isLowRamDeviceStatic()) {
14361                        pw.print(",low-ram");
14362                    }
14363                    if (ActivityManager.isHighEndGfx()) {
14364                        pw.print(",high-end-gfx");
14365                    }
14366                    pw.println();
14367                }
14368            }
14369        }
14370    }
14371
14372    /**
14373     * Searches array of arguments for the specified string
14374     * @param args array of argument strings
14375     * @param value value to search for
14376     * @return true if the value is contained in the array
14377     */
14378    private static boolean scanArgs(String[] args, String value) {
14379        if (args != null) {
14380            for (String arg : args) {
14381                if (value.equals(arg)) {
14382                    return true;
14383                }
14384            }
14385        }
14386        return false;
14387    }
14388
14389    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14390            ContentProviderRecord cpr, boolean always) {
14391        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14392
14393        if (!inLaunching || always) {
14394            synchronized (cpr) {
14395                cpr.launchingApp = null;
14396                cpr.notifyAll();
14397            }
14398            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14399            String names[] = cpr.info.authority.split(";");
14400            for (int j = 0; j < names.length; j++) {
14401                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14402            }
14403        }
14404
14405        for (int i=0; i<cpr.connections.size(); i++) {
14406            ContentProviderConnection conn = cpr.connections.get(i);
14407            if (conn.waiting) {
14408                // If this connection is waiting for the provider, then we don't
14409                // need to mess with its process unless we are always removing
14410                // or for some reason the provider is not currently launching.
14411                if (inLaunching && !always) {
14412                    continue;
14413                }
14414            }
14415            ProcessRecord capp = conn.client;
14416            conn.dead = true;
14417            if (conn.stableCount > 0) {
14418                if (!capp.persistent && capp.thread != null
14419                        && capp.pid != 0
14420                        && capp.pid != MY_PID) {
14421                    capp.kill("depends on provider "
14422                            + cpr.name.flattenToShortString()
14423                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14424                }
14425            } else if (capp.thread != null && conn.provider.provider != null) {
14426                try {
14427                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14428                } catch (RemoteException e) {
14429                }
14430                // In the protocol here, we don't expect the client to correctly
14431                // clean up this connection, we'll just remove it.
14432                cpr.connections.remove(i);
14433                conn.client.conProviders.remove(conn);
14434            }
14435        }
14436
14437        if (inLaunching && always) {
14438            mLaunchingProviders.remove(cpr);
14439        }
14440        return inLaunching;
14441    }
14442
14443    /**
14444     * Main code for cleaning up a process when it has gone away.  This is
14445     * called both as a result of the process dying, or directly when stopping
14446     * a process when running in single process mode.
14447     *
14448     * @return Returns true if the given process has been restarted, so the
14449     * app that was passed in must remain on the process lists.
14450     */
14451    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14452            boolean restarting, boolean allowRestart, int index) {
14453        if (index >= 0) {
14454            removeLruProcessLocked(app);
14455            ProcessList.remove(app.pid);
14456        }
14457
14458        mProcessesToGc.remove(app);
14459        mPendingPssProcesses.remove(app);
14460
14461        // Dismiss any open dialogs.
14462        if (app.crashDialog != null && !app.forceCrashReport) {
14463            app.crashDialog.dismiss();
14464            app.crashDialog = null;
14465        }
14466        if (app.anrDialog != null) {
14467            app.anrDialog.dismiss();
14468            app.anrDialog = null;
14469        }
14470        if (app.waitDialog != null) {
14471            app.waitDialog.dismiss();
14472            app.waitDialog = null;
14473        }
14474
14475        app.crashing = false;
14476        app.notResponding = false;
14477
14478        app.resetPackageList(mProcessStats);
14479        app.unlinkDeathRecipient();
14480        app.makeInactive(mProcessStats);
14481        app.waitingToKill = null;
14482        app.forcingToForeground = null;
14483        updateProcessForegroundLocked(app, false, false);
14484        app.foregroundActivities = false;
14485        app.hasShownUi = false;
14486        app.treatLikeActivity = false;
14487        app.hasAboveClient = false;
14488        app.hasClientActivities = false;
14489
14490        mServices.killServicesLocked(app, allowRestart);
14491
14492        boolean restart = false;
14493
14494        // Remove published content providers.
14495        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14496            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14497            final boolean always = app.bad || !allowRestart;
14498            if (removeDyingProviderLocked(app, cpr, always) || always) {
14499                // We left the provider in the launching list, need to
14500                // restart it.
14501                restart = true;
14502            }
14503
14504            cpr.provider = null;
14505            cpr.proc = null;
14506        }
14507        app.pubProviders.clear();
14508
14509        // Take care of any launching providers waiting for this process.
14510        if (checkAppInLaunchingProvidersLocked(app, false)) {
14511            restart = true;
14512        }
14513
14514        // Unregister from connected content providers.
14515        if (!app.conProviders.isEmpty()) {
14516            for (int i=0; i<app.conProviders.size(); i++) {
14517                ContentProviderConnection conn = app.conProviders.get(i);
14518                conn.provider.connections.remove(conn);
14519            }
14520            app.conProviders.clear();
14521        }
14522
14523        // At this point there may be remaining entries in mLaunchingProviders
14524        // where we were the only one waiting, so they are no longer of use.
14525        // Look for these and clean up if found.
14526        // XXX Commented out for now.  Trying to figure out a way to reproduce
14527        // the actual situation to identify what is actually going on.
14528        if (false) {
14529            for (int i=0; i<mLaunchingProviders.size(); i++) {
14530                ContentProviderRecord cpr = (ContentProviderRecord)
14531                        mLaunchingProviders.get(i);
14532                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14533                    synchronized (cpr) {
14534                        cpr.launchingApp = null;
14535                        cpr.notifyAll();
14536                    }
14537                }
14538            }
14539        }
14540
14541        skipCurrentReceiverLocked(app);
14542
14543        // Unregister any receivers.
14544        for (int i=app.receivers.size()-1; i>=0; i--) {
14545            removeReceiverLocked(app.receivers.valueAt(i));
14546        }
14547        app.receivers.clear();
14548
14549        // If the app is undergoing backup, tell the backup manager about it
14550        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14551            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14552                    + mBackupTarget.appInfo + " died during backup");
14553            try {
14554                IBackupManager bm = IBackupManager.Stub.asInterface(
14555                        ServiceManager.getService(Context.BACKUP_SERVICE));
14556                bm.agentDisconnected(app.info.packageName);
14557            } catch (RemoteException e) {
14558                // can't happen; backup manager is local
14559            }
14560        }
14561
14562        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14563            ProcessChangeItem item = mPendingProcessChanges.get(i);
14564            if (item.pid == app.pid) {
14565                mPendingProcessChanges.remove(i);
14566                mAvailProcessChanges.add(item);
14567            }
14568        }
14569        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14570
14571        // If the caller is restarting this app, then leave it in its
14572        // current lists and let the caller take care of it.
14573        if (restarting) {
14574            return false;
14575        }
14576
14577        if (!app.persistent || app.isolated) {
14578            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14579                    "Removing non-persistent process during cleanup: " + app);
14580            mProcessNames.remove(app.processName, app.uid);
14581            mIsolatedProcesses.remove(app.uid);
14582            if (mHeavyWeightProcess == app) {
14583                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14584                        mHeavyWeightProcess.userId, 0));
14585                mHeavyWeightProcess = null;
14586            }
14587        } else if (!app.removed) {
14588            // This app is persistent, so we need to keep its record around.
14589            // If it is not already on the pending app list, add it there
14590            // and start a new process for it.
14591            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14592                mPersistentStartingProcesses.add(app);
14593                restart = true;
14594            }
14595        }
14596        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14597                "Clean-up removing on hold: " + app);
14598        mProcessesOnHold.remove(app);
14599
14600        if (app == mHomeProcess) {
14601            mHomeProcess = null;
14602        }
14603        if (app == mPreviousProcess) {
14604            mPreviousProcess = null;
14605        }
14606
14607        if (restart && !app.isolated) {
14608            // We have components that still need to be running in the
14609            // process, so re-launch it.
14610            if (index < 0) {
14611                ProcessList.remove(app.pid);
14612            }
14613            mProcessNames.put(app.processName, app.uid, app);
14614            startProcessLocked(app, "restart", app.processName);
14615            return true;
14616        } else if (app.pid > 0 && app.pid != MY_PID) {
14617            // Goodbye!
14618            boolean removed;
14619            synchronized (mPidsSelfLocked) {
14620                mPidsSelfLocked.remove(app.pid);
14621                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14622            }
14623            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14624            if (app.isolated) {
14625                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14626            }
14627            app.setPid(0);
14628        }
14629        return false;
14630    }
14631
14632    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14633        // Look through the content providers we are waiting to have launched,
14634        // and if any run in this process then either schedule a restart of
14635        // the process or kill the client waiting for it if this process has
14636        // gone bad.
14637        int NL = mLaunchingProviders.size();
14638        boolean restart = false;
14639        for (int i=0; i<NL; i++) {
14640            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14641            if (cpr.launchingApp == app) {
14642                if (!alwaysBad && !app.bad) {
14643                    restart = true;
14644                } else {
14645                    removeDyingProviderLocked(app, cpr, true);
14646                    // cpr should have been removed from mLaunchingProviders
14647                    NL = mLaunchingProviders.size();
14648                    i--;
14649                }
14650            }
14651        }
14652        return restart;
14653    }
14654
14655    // =========================================================
14656    // SERVICES
14657    // =========================================================
14658
14659    @Override
14660    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14661            int flags) {
14662        enforceNotIsolatedCaller("getServices");
14663        synchronized (this) {
14664            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14665        }
14666    }
14667
14668    @Override
14669    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14670        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14671        synchronized (this) {
14672            return mServices.getRunningServiceControlPanelLocked(name);
14673        }
14674    }
14675
14676    @Override
14677    public ComponentName startService(IApplicationThread caller, Intent service,
14678            String resolvedType, int userId) {
14679        enforceNotIsolatedCaller("startService");
14680        // Refuse possible leaked file descriptors
14681        if (service != null && service.hasFileDescriptors() == true) {
14682            throw new IllegalArgumentException("File descriptors passed in Intent");
14683        }
14684
14685        if (DEBUG_SERVICE)
14686            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14687        synchronized(this) {
14688            final int callingPid = Binder.getCallingPid();
14689            final int callingUid = Binder.getCallingUid();
14690            final long origId = Binder.clearCallingIdentity();
14691            ComponentName res = mServices.startServiceLocked(caller, service,
14692                    resolvedType, callingPid, callingUid, userId);
14693            Binder.restoreCallingIdentity(origId);
14694            return res;
14695        }
14696    }
14697
14698    ComponentName startServiceInPackage(int uid,
14699            Intent service, String resolvedType, int userId) {
14700        synchronized(this) {
14701            if (DEBUG_SERVICE)
14702                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14703            final long origId = Binder.clearCallingIdentity();
14704            ComponentName res = mServices.startServiceLocked(null, service,
14705                    resolvedType, -1, uid, userId);
14706            Binder.restoreCallingIdentity(origId);
14707            return res;
14708        }
14709    }
14710
14711    @Override
14712    public int stopService(IApplicationThread caller, Intent service,
14713            String resolvedType, int userId) {
14714        enforceNotIsolatedCaller("stopService");
14715        // Refuse possible leaked file descriptors
14716        if (service != null && service.hasFileDescriptors() == true) {
14717            throw new IllegalArgumentException("File descriptors passed in Intent");
14718        }
14719
14720        synchronized(this) {
14721            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14722        }
14723    }
14724
14725    @Override
14726    public IBinder peekService(Intent service, String resolvedType) {
14727        enforceNotIsolatedCaller("peekService");
14728        // Refuse possible leaked file descriptors
14729        if (service != null && service.hasFileDescriptors() == true) {
14730            throw new IllegalArgumentException("File descriptors passed in Intent");
14731        }
14732        synchronized(this) {
14733            return mServices.peekServiceLocked(service, resolvedType);
14734        }
14735    }
14736
14737    @Override
14738    public boolean stopServiceToken(ComponentName className, IBinder token,
14739            int startId) {
14740        synchronized(this) {
14741            return mServices.stopServiceTokenLocked(className, token, startId);
14742        }
14743    }
14744
14745    @Override
14746    public void setServiceForeground(ComponentName className, IBinder token,
14747            int id, Notification notification, boolean removeNotification) {
14748        synchronized(this) {
14749            mServices.setServiceForegroundLocked(className, token, id, notification,
14750                    removeNotification);
14751        }
14752    }
14753
14754    @Override
14755    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14756            boolean requireFull, String name, String callerPackage) {
14757        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14758                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14759    }
14760
14761    int unsafeConvertIncomingUser(int userId) {
14762        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14763                ? mCurrentUserId : userId;
14764    }
14765
14766    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14767            int allowMode, String name, String callerPackage) {
14768        final int callingUserId = UserHandle.getUserId(callingUid);
14769        if (callingUserId == userId) {
14770            return userId;
14771        }
14772
14773        // Note that we may be accessing mCurrentUserId outside of a lock...
14774        // shouldn't be a big deal, if this is being called outside
14775        // of a locked context there is intrinsically a race with
14776        // the value the caller will receive and someone else changing it.
14777        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14778        // we will switch to the calling user if access to the current user fails.
14779        int targetUserId = unsafeConvertIncomingUser(userId);
14780
14781        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14782            final boolean allow;
14783            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14784                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14785                // If the caller has this permission, they always pass go.  And collect $200.
14786                allow = true;
14787            } else if (allowMode == ALLOW_FULL_ONLY) {
14788                // We require full access, sucks to be you.
14789                allow = false;
14790            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14791                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14792                // If the caller does not have either permission, they are always doomed.
14793                allow = false;
14794            } else if (allowMode == ALLOW_NON_FULL) {
14795                // We are blanket allowing non-full access, you lucky caller!
14796                allow = true;
14797            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14798                // We may or may not allow this depending on whether the two users are
14799                // in the same profile.
14800                synchronized (mUserProfileGroupIdsSelfLocked) {
14801                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14802                            UserInfo.NO_PROFILE_GROUP_ID);
14803                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14804                            UserInfo.NO_PROFILE_GROUP_ID);
14805                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14806                            && callingProfile == targetProfile;
14807                }
14808            } else {
14809                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14810            }
14811            if (!allow) {
14812                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14813                    // In this case, they would like to just execute as their
14814                    // owner user instead of failing.
14815                    targetUserId = callingUserId;
14816                } else {
14817                    StringBuilder builder = new StringBuilder(128);
14818                    builder.append("Permission Denial: ");
14819                    builder.append(name);
14820                    if (callerPackage != null) {
14821                        builder.append(" from ");
14822                        builder.append(callerPackage);
14823                    }
14824                    builder.append(" asks to run as user ");
14825                    builder.append(userId);
14826                    builder.append(" but is calling from user ");
14827                    builder.append(UserHandle.getUserId(callingUid));
14828                    builder.append("; this requires ");
14829                    builder.append(INTERACT_ACROSS_USERS_FULL);
14830                    if (allowMode != ALLOW_FULL_ONLY) {
14831                        builder.append(" or ");
14832                        builder.append(INTERACT_ACROSS_USERS);
14833                    }
14834                    String msg = builder.toString();
14835                    Slog.w(TAG, msg);
14836                    throw new SecurityException(msg);
14837                }
14838            }
14839        }
14840        if (!allowAll && targetUserId < 0) {
14841            throw new IllegalArgumentException(
14842                    "Call does not support special user #" + targetUserId);
14843        }
14844        // Check shell permission
14845        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14846            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14847                    targetUserId)) {
14848                throw new SecurityException("Shell does not have permission to access user "
14849                        + targetUserId + "\n " + Debug.getCallers(3));
14850            }
14851        }
14852        return targetUserId;
14853    }
14854
14855    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14856            String className, int flags) {
14857        boolean result = false;
14858        // For apps that don't have pre-defined UIDs, check for permission
14859        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14860            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14861                if (ActivityManager.checkUidPermission(
14862                        INTERACT_ACROSS_USERS,
14863                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14864                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14865                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14866                            + " requests FLAG_SINGLE_USER, but app does not hold "
14867                            + INTERACT_ACROSS_USERS;
14868                    Slog.w(TAG, msg);
14869                    throw new SecurityException(msg);
14870                }
14871                // Permission passed
14872                result = true;
14873            }
14874        } else if ("system".equals(componentProcessName)) {
14875            result = true;
14876        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14877            // Phone app and persistent apps are allowed to export singleuser providers.
14878            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14879                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14880        }
14881        if (DEBUG_MU) {
14882            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14883                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14884        }
14885        return result;
14886    }
14887
14888    /**
14889     * Checks to see if the caller is in the same app as the singleton
14890     * component, or the component is in a special app. It allows special apps
14891     * to export singleton components but prevents exporting singleton
14892     * components for regular apps.
14893     */
14894    boolean isValidSingletonCall(int callingUid, int componentUid) {
14895        int componentAppId = UserHandle.getAppId(componentUid);
14896        return UserHandle.isSameApp(callingUid, componentUid)
14897                || componentAppId == Process.SYSTEM_UID
14898                || componentAppId == Process.PHONE_UID
14899                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14900                        == PackageManager.PERMISSION_GRANTED;
14901    }
14902
14903    public int bindService(IApplicationThread caller, IBinder token,
14904            Intent service, String resolvedType,
14905            IServiceConnection connection, int flags, int userId) {
14906        enforceNotIsolatedCaller("bindService");
14907
14908        // Refuse possible leaked file descriptors
14909        if (service != null && service.hasFileDescriptors() == true) {
14910            throw new IllegalArgumentException("File descriptors passed in Intent");
14911        }
14912
14913        synchronized(this) {
14914            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14915                    connection, flags, userId);
14916        }
14917    }
14918
14919    public boolean unbindService(IServiceConnection connection) {
14920        synchronized (this) {
14921            return mServices.unbindServiceLocked(connection);
14922        }
14923    }
14924
14925    public void publishService(IBinder token, Intent intent, IBinder service) {
14926        // Refuse possible leaked file descriptors
14927        if (intent != null && intent.hasFileDescriptors() == true) {
14928            throw new IllegalArgumentException("File descriptors passed in Intent");
14929        }
14930
14931        synchronized(this) {
14932            if (!(token instanceof ServiceRecord)) {
14933                throw new IllegalArgumentException("Invalid service token");
14934            }
14935            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14936        }
14937    }
14938
14939    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14940        // Refuse possible leaked file descriptors
14941        if (intent != null && intent.hasFileDescriptors() == true) {
14942            throw new IllegalArgumentException("File descriptors passed in Intent");
14943        }
14944
14945        synchronized(this) {
14946            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14947        }
14948    }
14949
14950    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14951        synchronized(this) {
14952            if (!(token instanceof ServiceRecord)) {
14953                throw new IllegalArgumentException("Invalid service token");
14954            }
14955            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14956        }
14957    }
14958
14959    // =========================================================
14960    // BACKUP AND RESTORE
14961    // =========================================================
14962
14963    // Cause the target app to be launched if necessary and its backup agent
14964    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14965    // activity manager to announce its creation.
14966    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14967        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14968        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14969
14970        synchronized(this) {
14971            // !!! TODO: currently no check here that we're already bound
14972            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14973            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14974            synchronized (stats) {
14975                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14976            }
14977
14978            // Backup agent is now in use, its package can't be stopped.
14979            try {
14980                AppGlobals.getPackageManager().setPackageStoppedState(
14981                        app.packageName, false, UserHandle.getUserId(app.uid));
14982            } catch (RemoteException e) {
14983            } catch (IllegalArgumentException e) {
14984                Slog.w(TAG, "Failed trying to unstop package "
14985                        + app.packageName + ": " + e);
14986            }
14987
14988            BackupRecord r = new BackupRecord(ss, app, backupMode);
14989            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14990                    ? new ComponentName(app.packageName, app.backupAgentName)
14991                    : new ComponentName("android", "FullBackupAgent");
14992            // startProcessLocked() returns existing proc's record if it's already running
14993            ProcessRecord proc = startProcessLocked(app.processName, app,
14994                    false, 0, "backup", hostingName, false, false, false);
14995            if (proc == null) {
14996                Slog.e(TAG, "Unable to start backup agent process " + r);
14997                return false;
14998            }
14999
15000            r.app = proc;
15001            mBackupTarget = r;
15002            mBackupAppName = app.packageName;
15003
15004            // Try not to kill the process during backup
15005            updateOomAdjLocked(proc);
15006
15007            // If the process is already attached, schedule the creation of the backup agent now.
15008            // If it is not yet live, this will be done when it attaches to the framework.
15009            if (proc.thread != null) {
15010                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15011                try {
15012                    proc.thread.scheduleCreateBackupAgent(app,
15013                            compatibilityInfoForPackageLocked(app), backupMode);
15014                } catch (RemoteException e) {
15015                    // Will time out on the backup manager side
15016                }
15017            } else {
15018                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15019            }
15020            // Invariants: at this point, the target app process exists and the application
15021            // is either already running or in the process of coming up.  mBackupTarget and
15022            // mBackupAppName describe the app, so that when it binds back to the AM we
15023            // know that it's scheduled for a backup-agent operation.
15024        }
15025
15026        return true;
15027    }
15028
15029    @Override
15030    public void clearPendingBackup() {
15031        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15032        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15033
15034        synchronized (this) {
15035            mBackupTarget = null;
15036            mBackupAppName = null;
15037        }
15038    }
15039
15040    // A backup agent has just come up
15041    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15042        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15043                + " = " + agent);
15044
15045        synchronized(this) {
15046            if (!agentPackageName.equals(mBackupAppName)) {
15047                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15048                return;
15049            }
15050        }
15051
15052        long oldIdent = Binder.clearCallingIdentity();
15053        try {
15054            IBackupManager bm = IBackupManager.Stub.asInterface(
15055                    ServiceManager.getService(Context.BACKUP_SERVICE));
15056            bm.agentConnected(agentPackageName, agent);
15057        } catch (RemoteException e) {
15058            // can't happen; the backup manager service is local
15059        } catch (Exception e) {
15060            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15061            e.printStackTrace();
15062        } finally {
15063            Binder.restoreCallingIdentity(oldIdent);
15064        }
15065    }
15066
15067    // done with this agent
15068    public void unbindBackupAgent(ApplicationInfo appInfo) {
15069        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15070        if (appInfo == null) {
15071            Slog.w(TAG, "unbind backup agent for null app");
15072            return;
15073        }
15074
15075        synchronized(this) {
15076            try {
15077                if (mBackupAppName == null) {
15078                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15079                    return;
15080                }
15081
15082                if (!mBackupAppName.equals(appInfo.packageName)) {
15083                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15084                    return;
15085                }
15086
15087                // Not backing this app up any more; reset its OOM adjustment
15088                final ProcessRecord proc = mBackupTarget.app;
15089                updateOomAdjLocked(proc);
15090
15091                // If the app crashed during backup, 'thread' will be null here
15092                if (proc.thread != null) {
15093                    try {
15094                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15095                                compatibilityInfoForPackageLocked(appInfo));
15096                    } catch (Exception e) {
15097                        Slog.e(TAG, "Exception when unbinding backup agent:");
15098                        e.printStackTrace();
15099                    }
15100                }
15101            } finally {
15102                mBackupTarget = null;
15103                mBackupAppName = null;
15104            }
15105        }
15106    }
15107    // =========================================================
15108    // BROADCASTS
15109    // =========================================================
15110
15111    private final List getStickiesLocked(String action, IntentFilter filter,
15112            List cur, int userId) {
15113        final ContentResolver resolver = mContext.getContentResolver();
15114        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15115        if (stickies == null) {
15116            return cur;
15117        }
15118        final ArrayList<Intent> list = stickies.get(action);
15119        if (list == null) {
15120            return cur;
15121        }
15122        int N = list.size();
15123        for (int i=0; i<N; i++) {
15124            Intent intent = list.get(i);
15125            if (filter.match(resolver, intent, true, TAG) >= 0) {
15126                if (cur == null) {
15127                    cur = new ArrayList<Intent>();
15128                }
15129                cur.add(intent);
15130            }
15131        }
15132        return cur;
15133    }
15134
15135    boolean isPendingBroadcastProcessLocked(int pid) {
15136        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15137                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15138    }
15139
15140    void skipPendingBroadcastLocked(int pid) {
15141            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15142            for (BroadcastQueue queue : mBroadcastQueues) {
15143                queue.skipPendingBroadcastLocked(pid);
15144            }
15145    }
15146
15147    // The app just attached; send any pending broadcasts that it should receive
15148    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15149        boolean didSomething = false;
15150        for (BroadcastQueue queue : mBroadcastQueues) {
15151            didSomething |= queue.sendPendingBroadcastsLocked(app);
15152        }
15153        return didSomething;
15154    }
15155
15156    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15157            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15158        enforceNotIsolatedCaller("registerReceiver");
15159        int callingUid;
15160        int callingPid;
15161        synchronized(this) {
15162            ProcessRecord callerApp = null;
15163            if (caller != null) {
15164                callerApp = getRecordForAppLocked(caller);
15165                if (callerApp == null) {
15166                    throw new SecurityException(
15167                            "Unable to find app for caller " + caller
15168                            + " (pid=" + Binder.getCallingPid()
15169                            + ") when registering receiver " + receiver);
15170                }
15171                if (callerApp.info.uid != Process.SYSTEM_UID &&
15172                        !callerApp.pkgList.containsKey(callerPackage) &&
15173                        !"android".equals(callerPackage)) {
15174                    throw new SecurityException("Given caller package " + callerPackage
15175                            + " is not running in process " + callerApp);
15176                }
15177                callingUid = callerApp.info.uid;
15178                callingPid = callerApp.pid;
15179            } else {
15180                callerPackage = null;
15181                callingUid = Binder.getCallingUid();
15182                callingPid = Binder.getCallingPid();
15183            }
15184
15185            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15186                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15187
15188            List allSticky = null;
15189
15190            // Look for any matching sticky broadcasts...
15191            Iterator actions = filter.actionsIterator();
15192            if (actions != null) {
15193                while (actions.hasNext()) {
15194                    String action = (String)actions.next();
15195                    allSticky = getStickiesLocked(action, filter, allSticky,
15196                            UserHandle.USER_ALL);
15197                    allSticky = getStickiesLocked(action, filter, allSticky,
15198                            UserHandle.getUserId(callingUid));
15199                }
15200            } else {
15201                allSticky = getStickiesLocked(null, filter, allSticky,
15202                        UserHandle.USER_ALL);
15203                allSticky = getStickiesLocked(null, filter, allSticky,
15204                        UserHandle.getUserId(callingUid));
15205            }
15206
15207            // The first sticky in the list is returned directly back to
15208            // the client.
15209            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15210
15211            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15212                    + ": " + sticky);
15213
15214            if (receiver == null) {
15215                return sticky;
15216            }
15217
15218            ReceiverList rl
15219                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15220            if (rl == null) {
15221                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15222                        userId, receiver);
15223                if (rl.app != null) {
15224                    rl.app.receivers.add(rl);
15225                } else {
15226                    try {
15227                        receiver.asBinder().linkToDeath(rl, 0);
15228                    } catch (RemoteException e) {
15229                        return sticky;
15230                    }
15231                    rl.linkedToDeath = true;
15232                }
15233                mRegisteredReceivers.put(receiver.asBinder(), rl);
15234            } else if (rl.uid != callingUid) {
15235                throw new IllegalArgumentException(
15236                        "Receiver requested to register for uid " + callingUid
15237                        + " was previously registered for uid " + rl.uid);
15238            } else if (rl.pid != callingPid) {
15239                throw new IllegalArgumentException(
15240                        "Receiver requested to register for pid " + callingPid
15241                        + " was previously registered for pid " + rl.pid);
15242            } else if (rl.userId != userId) {
15243                throw new IllegalArgumentException(
15244                        "Receiver requested to register for user " + userId
15245                        + " was previously registered for user " + rl.userId);
15246            }
15247            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15248                    permission, callingUid, userId);
15249            rl.add(bf);
15250            if (!bf.debugCheck()) {
15251                Slog.w(TAG, "==> For Dynamic broadast");
15252            }
15253            mReceiverResolver.addFilter(bf);
15254
15255            // Enqueue broadcasts for all existing stickies that match
15256            // this filter.
15257            if (allSticky != null) {
15258                ArrayList receivers = new ArrayList();
15259                receivers.add(bf);
15260
15261                int N = allSticky.size();
15262                for (int i=0; i<N; i++) {
15263                    Intent intent = (Intent)allSticky.get(i);
15264                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15265                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15266                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15267                            null, null, false, true, true, -1);
15268                    queue.enqueueParallelBroadcastLocked(r);
15269                    queue.scheduleBroadcastsLocked();
15270                }
15271            }
15272
15273            return sticky;
15274        }
15275    }
15276
15277    public void unregisterReceiver(IIntentReceiver receiver) {
15278        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15279
15280        final long origId = Binder.clearCallingIdentity();
15281        try {
15282            boolean doTrim = false;
15283
15284            synchronized(this) {
15285                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15286                if (rl != null) {
15287                    if (rl.curBroadcast != null) {
15288                        BroadcastRecord r = rl.curBroadcast;
15289                        final boolean doNext = finishReceiverLocked(
15290                                receiver.asBinder(), r.resultCode, r.resultData,
15291                                r.resultExtras, r.resultAbort);
15292                        if (doNext) {
15293                            doTrim = true;
15294                            r.queue.processNextBroadcast(false);
15295                        }
15296                    }
15297
15298                    if (rl.app != null) {
15299                        rl.app.receivers.remove(rl);
15300                    }
15301                    removeReceiverLocked(rl);
15302                    if (rl.linkedToDeath) {
15303                        rl.linkedToDeath = false;
15304                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15305                    }
15306                }
15307            }
15308
15309            // If we actually concluded any broadcasts, we might now be able
15310            // to trim the recipients' apps from our working set
15311            if (doTrim) {
15312                trimApplications();
15313                return;
15314            }
15315
15316        } finally {
15317            Binder.restoreCallingIdentity(origId);
15318        }
15319    }
15320
15321    void removeReceiverLocked(ReceiverList rl) {
15322        mRegisteredReceivers.remove(rl.receiver.asBinder());
15323        int N = rl.size();
15324        for (int i=0; i<N; i++) {
15325            mReceiverResolver.removeFilter(rl.get(i));
15326        }
15327    }
15328
15329    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15330        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15331            ProcessRecord r = mLruProcesses.get(i);
15332            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15333                try {
15334                    r.thread.dispatchPackageBroadcast(cmd, packages);
15335                } catch (RemoteException ex) {
15336                }
15337            }
15338        }
15339    }
15340
15341    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15342            int callingUid, int[] users) {
15343        List<ResolveInfo> receivers = null;
15344        try {
15345            HashSet<ComponentName> singleUserReceivers = null;
15346            boolean scannedFirstReceivers = false;
15347            for (int user : users) {
15348                // Skip users that have Shell restrictions
15349                if (callingUid == Process.SHELL_UID
15350                        && getUserManagerLocked().hasUserRestriction(
15351                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15352                    continue;
15353                }
15354                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15355                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15356                if (user != 0 && newReceivers != null) {
15357                    // If this is not the primary user, we need to check for
15358                    // any receivers that should be filtered out.
15359                    for (int i=0; i<newReceivers.size(); i++) {
15360                        ResolveInfo ri = newReceivers.get(i);
15361                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15362                            newReceivers.remove(i);
15363                            i--;
15364                        }
15365                    }
15366                }
15367                if (newReceivers != null && newReceivers.size() == 0) {
15368                    newReceivers = null;
15369                }
15370                if (receivers == null) {
15371                    receivers = newReceivers;
15372                } else if (newReceivers != null) {
15373                    // We need to concatenate the additional receivers
15374                    // found with what we have do far.  This would be easy,
15375                    // but we also need to de-dup any receivers that are
15376                    // singleUser.
15377                    if (!scannedFirstReceivers) {
15378                        // Collect any single user receivers we had already retrieved.
15379                        scannedFirstReceivers = true;
15380                        for (int i=0; i<receivers.size(); i++) {
15381                            ResolveInfo ri = receivers.get(i);
15382                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15383                                ComponentName cn = new ComponentName(
15384                                        ri.activityInfo.packageName, ri.activityInfo.name);
15385                                if (singleUserReceivers == null) {
15386                                    singleUserReceivers = new HashSet<ComponentName>();
15387                                }
15388                                singleUserReceivers.add(cn);
15389                            }
15390                        }
15391                    }
15392                    // Add the new results to the existing results, tracking
15393                    // and de-dupping single user receivers.
15394                    for (int i=0; i<newReceivers.size(); i++) {
15395                        ResolveInfo ri = newReceivers.get(i);
15396                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15397                            ComponentName cn = new ComponentName(
15398                                    ri.activityInfo.packageName, ri.activityInfo.name);
15399                            if (singleUserReceivers == null) {
15400                                singleUserReceivers = new HashSet<ComponentName>();
15401                            }
15402                            if (!singleUserReceivers.contains(cn)) {
15403                                singleUserReceivers.add(cn);
15404                                receivers.add(ri);
15405                            }
15406                        } else {
15407                            receivers.add(ri);
15408                        }
15409                    }
15410                }
15411            }
15412        } catch (RemoteException ex) {
15413            // pm is in same process, this will never happen.
15414        }
15415        return receivers;
15416    }
15417
15418    private final int broadcastIntentLocked(ProcessRecord callerApp,
15419            String callerPackage, Intent intent, String resolvedType,
15420            IIntentReceiver resultTo, int resultCode, String resultData,
15421            Bundle map, String requiredPermission, int appOp,
15422            boolean ordered, boolean sticky, int callingPid, int callingUid,
15423            int userId) {
15424        intent = new Intent(intent);
15425
15426        // By default broadcasts do not go to stopped apps.
15427        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15428
15429        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15430            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15431            + " ordered=" + ordered + " userid=" + userId);
15432        if ((resultTo != null) && !ordered) {
15433            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15434        }
15435
15436        userId = handleIncomingUser(callingPid, callingUid, userId,
15437                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15438
15439        // Make sure that the user who is receiving this broadcast is started.
15440        // If not, we will just skip it.
15441
15442        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15443            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15444                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15445                Slog.w(TAG, "Skipping broadcast of " + intent
15446                        + ": user " + userId + " is stopped");
15447                return ActivityManager.BROADCAST_SUCCESS;
15448            }
15449        }
15450
15451        /*
15452         * Prevent non-system code (defined here to be non-persistent
15453         * processes) from sending protected broadcasts.
15454         */
15455        int callingAppId = UserHandle.getAppId(callingUid);
15456        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15457            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15458            || callingAppId == Process.NFC_UID || callingUid == 0) {
15459            // Always okay.
15460        } else if (callerApp == null || !callerApp.persistent) {
15461            try {
15462                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15463                        intent.getAction())) {
15464                    String msg = "Permission Denial: not allowed to send broadcast "
15465                            + intent.getAction() + " from pid="
15466                            + callingPid + ", uid=" + callingUid;
15467                    Slog.w(TAG, msg);
15468                    throw new SecurityException(msg);
15469                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15470                    // Special case for compatibility: we don't want apps to send this,
15471                    // but historically it has not been protected and apps may be using it
15472                    // to poke their own app widget.  So, instead of making it protected,
15473                    // just limit it to the caller.
15474                    if (callerApp == null) {
15475                        String msg = "Permission Denial: not allowed to send broadcast "
15476                                + intent.getAction() + " from unknown caller.";
15477                        Slog.w(TAG, msg);
15478                        throw new SecurityException(msg);
15479                    } else if (intent.getComponent() != null) {
15480                        // They are good enough to send to an explicit component...  verify
15481                        // it is being sent to the calling app.
15482                        if (!intent.getComponent().getPackageName().equals(
15483                                callerApp.info.packageName)) {
15484                            String msg = "Permission Denial: not allowed to send broadcast "
15485                                    + intent.getAction() + " to "
15486                                    + intent.getComponent().getPackageName() + " from "
15487                                    + callerApp.info.packageName;
15488                            Slog.w(TAG, msg);
15489                            throw new SecurityException(msg);
15490                        }
15491                    } else {
15492                        // Limit broadcast to their own package.
15493                        intent.setPackage(callerApp.info.packageName);
15494                    }
15495                }
15496            } catch (RemoteException e) {
15497                Slog.w(TAG, "Remote exception", e);
15498                return ActivityManager.BROADCAST_SUCCESS;
15499            }
15500        }
15501
15502        // Handle special intents: if this broadcast is from the package
15503        // manager about a package being removed, we need to remove all of
15504        // its activities from the history stack.
15505        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15506                intent.getAction());
15507        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15508                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15509                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15510                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15511                || uidRemoved) {
15512            if (checkComponentPermission(
15513                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15514                    callingPid, callingUid, -1, true)
15515                    == PackageManager.PERMISSION_GRANTED) {
15516                if (uidRemoved) {
15517                    final Bundle intentExtras = intent.getExtras();
15518                    final int uid = intentExtras != null
15519                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15520                    if (uid >= 0) {
15521                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15522                        synchronized (bs) {
15523                            bs.removeUidStatsLocked(uid);
15524                        }
15525                        mAppOpsService.uidRemoved(uid);
15526                    }
15527                } else {
15528                    // If resources are unavailable just force stop all
15529                    // those packages and flush the attribute cache as well.
15530                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15531                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15532                        if (list != null && (list.length > 0)) {
15533                            for (String pkg : list) {
15534                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15535                                        "storage unmount");
15536                            }
15537                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15538                            sendPackageBroadcastLocked(
15539                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15540                        }
15541                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15542                            intent.getAction())) {
15543                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15544                    } else {
15545                        Uri data = intent.getData();
15546                        String ssp;
15547                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15548                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15549                                    intent.getAction());
15550                            boolean fullUninstall = removed &&
15551                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15552                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15553                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15554                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15555                                        false, fullUninstall, userId,
15556                                        removed ? "pkg removed" : "pkg changed");
15557                            }
15558                            if (removed) {
15559                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15560                                        new String[] {ssp}, userId);
15561                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15562                                    mAppOpsService.packageRemoved(
15563                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15564
15565                                    // Remove all permissions granted from/to this package
15566                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15567                                }
15568                            }
15569                        }
15570                    }
15571                }
15572            } else {
15573                String msg = "Permission Denial: " + intent.getAction()
15574                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15575                        + ", uid=" + callingUid + ")"
15576                        + " requires "
15577                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15578                Slog.w(TAG, msg);
15579                throw new SecurityException(msg);
15580            }
15581
15582        // Special case for adding a package: by default turn on compatibility
15583        // mode.
15584        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15585            Uri data = intent.getData();
15586            String ssp;
15587            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15588                mCompatModePackages.handlePackageAddedLocked(ssp,
15589                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15590            }
15591        }
15592
15593        /*
15594         * If this is the time zone changed action, queue up a message that will reset the timezone
15595         * of all currently running processes. This message will get queued up before the broadcast
15596         * happens.
15597         */
15598        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15599            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15600        }
15601
15602        /*
15603         * If the user set the time, let all running processes know.
15604         */
15605        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15606            final int is24Hour = intent.getBooleanExtra(
15607                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15608            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15609            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15610            synchronized (stats) {
15611                stats.noteCurrentTimeChangedLocked();
15612            }
15613        }
15614
15615        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15616            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15617        }
15618
15619        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15620            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15621            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15622        }
15623
15624        // Add to the sticky list if requested.
15625        if (sticky) {
15626            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15627                    callingPid, callingUid)
15628                    != PackageManager.PERMISSION_GRANTED) {
15629                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15630                        + callingPid + ", uid=" + callingUid
15631                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15632                Slog.w(TAG, msg);
15633                throw new SecurityException(msg);
15634            }
15635            if (requiredPermission != null) {
15636                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15637                        + " and enforce permission " + requiredPermission);
15638                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15639            }
15640            if (intent.getComponent() != null) {
15641                throw new SecurityException(
15642                        "Sticky broadcasts can't target a specific component");
15643            }
15644            // We use userId directly here, since the "all" target is maintained
15645            // as a separate set of sticky broadcasts.
15646            if (userId != UserHandle.USER_ALL) {
15647                // But first, if this is not a broadcast to all users, then
15648                // make sure it doesn't conflict with an existing broadcast to
15649                // all users.
15650                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15651                        UserHandle.USER_ALL);
15652                if (stickies != null) {
15653                    ArrayList<Intent> list = stickies.get(intent.getAction());
15654                    if (list != null) {
15655                        int N = list.size();
15656                        int i;
15657                        for (i=0; i<N; i++) {
15658                            if (intent.filterEquals(list.get(i))) {
15659                                throw new IllegalArgumentException(
15660                                        "Sticky broadcast " + intent + " for user "
15661                                        + userId + " conflicts with existing global broadcast");
15662                            }
15663                        }
15664                    }
15665                }
15666            }
15667            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15668            if (stickies == null) {
15669                stickies = new ArrayMap<String, ArrayList<Intent>>();
15670                mStickyBroadcasts.put(userId, stickies);
15671            }
15672            ArrayList<Intent> list = stickies.get(intent.getAction());
15673            if (list == null) {
15674                list = new ArrayList<Intent>();
15675                stickies.put(intent.getAction(), list);
15676            }
15677            int N = list.size();
15678            int i;
15679            for (i=0; i<N; i++) {
15680                if (intent.filterEquals(list.get(i))) {
15681                    // This sticky already exists, replace it.
15682                    list.set(i, new Intent(intent));
15683                    break;
15684                }
15685            }
15686            if (i >= N) {
15687                list.add(new Intent(intent));
15688            }
15689        }
15690
15691        int[] users;
15692        if (userId == UserHandle.USER_ALL) {
15693            // Caller wants broadcast to go to all started users.
15694            users = mStartedUserArray;
15695        } else {
15696            // Caller wants broadcast to go to one specific user.
15697            users = new int[] {userId};
15698        }
15699
15700        // Figure out who all will receive this broadcast.
15701        List receivers = null;
15702        List<BroadcastFilter> registeredReceivers = null;
15703        // Need to resolve the intent to interested receivers...
15704        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15705                 == 0) {
15706            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15707        }
15708        if (intent.getComponent() == null) {
15709            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15710                // Query one target user at a time, excluding shell-restricted users
15711                UserManagerService ums = getUserManagerLocked();
15712                for (int i = 0; i < users.length; i++) {
15713                    if (ums.hasUserRestriction(
15714                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15715                        continue;
15716                    }
15717                    List<BroadcastFilter> registeredReceiversForUser =
15718                            mReceiverResolver.queryIntent(intent,
15719                                    resolvedType, false, users[i]);
15720                    if (registeredReceivers == null) {
15721                        registeredReceivers = registeredReceiversForUser;
15722                    } else if (registeredReceiversForUser != null) {
15723                        registeredReceivers.addAll(registeredReceiversForUser);
15724                    }
15725                }
15726            } else {
15727                registeredReceivers = mReceiverResolver.queryIntent(intent,
15728                        resolvedType, false, userId);
15729            }
15730        }
15731
15732        final boolean replacePending =
15733                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15734
15735        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15736                + " replacePending=" + replacePending);
15737
15738        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15739        if (!ordered && NR > 0) {
15740            // If we are not serializing this broadcast, then send the
15741            // registered receivers separately so they don't wait for the
15742            // components to be launched.
15743            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15744            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15745                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15746                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15747                    ordered, sticky, false, userId);
15748            if (DEBUG_BROADCAST) Slog.v(
15749                    TAG, "Enqueueing parallel broadcast " + r);
15750            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15751            if (!replaced) {
15752                queue.enqueueParallelBroadcastLocked(r);
15753                queue.scheduleBroadcastsLocked();
15754            }
15755            registeredReceivers = null;
15756            NR = 0;
15757        }
15758
15759        // Merge into one list.
15760        int ir = 0;
15761        if (receivers != null) {
15762            // A special case for PACKAGE_ADDED: do not allow the package
15763            // being added to see this broadcast.  This prevents them from
15764            // using this as a back door to get run as soon as they are
15765            // installed.  Maybe in the future we want to have a special install
15766            // broadcast or such for apps, but we'd like to deliberately make
15767            // this decision.
15768            String skipPackages[] = null;
15769            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15770                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15771                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15772                Uri data = intent.getData();
15773                if (data != null) {
15774                    String pkgName = data.getSchemeSpecificPart();
15775                    if (pkgName != null) {
15776                        skipPackages = new String[] { pkgName };
15777                    }
15778                }
15779            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15780                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15781            }
15782            if (skipPackages != null && (skipPackages.length > 0)) {
15783                for (String skipPackage : skipPackages) {
15784                    if (skipPackage != null) {
15785                        int NT = receivers.size();
15786                        for (int it=0; it<NT; it++) {
15787                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15788                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15789                                receivers.remove(it);
15790                                it--;
15791                                NT--;
15792                            }
15793                        }
15794                    }
15795                }
15796            }
15797
15798            int NT = receivers != null ? receivers.size() : 0;
15799            int it = 0;
15800            ResolveInfo curt = null;
15801            BroadcastFilter curr = null;
15802            while (it < NT && ir < NR) {
15803                if (curt == null) {
15804                    curt = (ResolveInfo)receivers.get(it);
15805                }
15806                if (curr == null) {
15807                    curr = registeredReceivers.get(ir);
15808                }
15809                if (curr.getPriority() >= curt.priority) {
15810                    // Insert this broadcast record into the final list.
15811                    receivers.add(it, curr);
15812                    ir++;
15813                    curr = null;
15814                    it++;
15815                    NT++;
15816                } else {
15817                    // Skip to the next ResolveInfo in the final list.
15818                    it++;
15819                    curt = null;
15820                }
15821            }
15822        }
15823        while (ir < NR) {
15824            if (receivers == null) {
15825                receivers = new ArrayList();
15826            }
15827            receivers.add(registeredReceivers.get(ir));
15828            ir++;
15829        }
15830
15831        if ((receivers != null && receivers.size() > 0)
15832                || resultTo != null) {
15833            BroadcastQueue queue = broadcastQueueForIntent(intent);
15834            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15835                    callerPackage, callingPid, callingUid, resolvedType,
15836                    requiredPermission, appOp, receivers, resultTo, resultCode,
15837                    resultData, map, ordered, sticky, false, userId);
15838            if (DEBUG_BROADCAST) Slog.v(
15839                    TAG, "Enqueueing ordered broadcast " + r
15840                    + ": prev had " + queue.mOrderedBroadcasts.size());
15841            if (DEBUG_BROADCAST) {
15842                int seq = r.intent.getIntExtra("seq", -1);
15843                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15844            }
15845            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15846            if (!replaced) {
15847                queue.enqueueOrderedBroadcastLocked(r);
15848                queue.scheduleBroadcastsLocked();
15849            }
15850        }
15851
15852        return ActivityManager.BROADCAST_SUCCESS;
15853    }
15854
15855    final Intent verifyBroadcastLocked(Intent intent) {
15856        // Refuse possible leaked file descriptors
15857        if (intent != null && intent.hasFileDescriptors() == true) {
15858            throw new IllegalArgumentException("File descriptors passed in Intent");
15859        }
15860
15861        int flags = intent.getFlags();
15862
15863        if (!mProcessesReady) {
15864            // if the caller really truly claims to know what they're doing, go
15865            // ahead and allow the broadcast without launching any receivers
15866            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15867                intent = new Intent(intent);
15868                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15869            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15870                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15871                        + " before boot completion");
15872                throw new IllegalStateException("Cannot broadcast before boot completed");
15873            }
15874        }
15875
15876        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15877            throw new IllegalArgumentException(
15878                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15879        }
15880
15881        return intent;
15882    }
15883
15884    public final int broadcastIntent(IApplicationThread caller,
15885            Intent intent, String resolvedType, IIntentReceiver resultTo,
15886            int resultCode, String resultData, Bundle map,
15887            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15888        enforceNotIsolatedCaller("broadcastIntent");
15889        synchronized(this) {
15890            intent = verifyBroadcastLocked(intent);
15891
15892            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15893            final int callingPid = Binder.getCallingPid();
15894            final int callingUid = Binder.getCallingUid();
15895            final long origId = Binder.clearCallingIdentity();
15896            int res = broadcastIntentLocked(callerApp,
15897                    callerApp != null ? callerApp.info.packageName : null,
15898                    intent, resolvedType, resultTo,
15899                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15900                    callingPid, callingUid, userId);
15901            Binder.restoreCallingIdentity(origId);
15902            return res;
15903        }
15904    }
15905
15906    int broadcastIntentInPackage(String packageName, int uid,
15907            Intent intent, String resolvedType, IIntentReceiver resultTo,
15908            int resultCode, String resultData, Bundle map,
15909            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15910        synchronized(this) {
15911            intent = verifyBroadcastLocked(intent);
15912
15913            final long origId = Binder.clearCallingIdentity();
15914            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15915                    resultTo, resultCode, resultData, map, requiredPermission,
15916                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15917            Binder.restoreCallingIdentity(origId);
15918            return res;
15919        }
15920    }
15921
15922    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15923        // Refuse possible leaked file descriptors
15924        if (intent != null && intent.hasFileDescriptors() == true) {
15925            throw new IllegalArgumentException("File descriptors passed in Intent");
15926        }
15927
15928        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15929                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15930
15931        synchronized(this) {
15932            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15933                    != PackageManager.PERMISSION_GRANTED) {
15934                String msg = "Permission Denial: unbroadcastIntent() from pid="
15935                        + Binder.getCallingPid()
15936                        + ", uid=" + Binder.getCallingUid()
15937                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15938                Slog.w(TAG, msg);
15939                throw new SecurityException(msg);
15940            }
15941            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15942            if (stickies != null) {
15943                ArrayList<Intent> list = stickies.get(intent.getAction());
15944                if (list != null) {
15945                    int N = list.size();
15946                    int i;
15947                    for (i=0; i<N; i++) {
15948                        if (intent.filterEquals(list.get(i))) {
15949                            list.remove(i);
15950                            break;
15951                        }
15952                    }
15953                    if (list.size() <= 0) {
15954                        stickies.remove(intent.getAction());
15955                    }
15956                }
15957                if (stickies.size() <= 0) {
15958                    mStickyBroadcasts.remove(userId);
15959                }
15960            }
15961        }
15962    }
15963
15964    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15965            String resultData, Bundle resultExtras, boolean resultAbort) {
15966        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15967        if (r == null) {
15968            Slog.w(TAG, "finishReceiver called but not found on queue");
15969            return false;
15970        }
15971
15972        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15973    }
15974
15975    void backgroundServicesFinishedLocked(int userId) {
15976        for (BroadcastQueue queue : mBroadcastQueues) {
15977            queue.backgroundServicesFinishedLocked(userId);
15978        }
15979    }
15980
15981    public void finishReceiver(IBinder who, int resultCode, String resultData,
15982            Bundle resultExtras, boolean resultAbort) {
15983        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15984
15985        // Refuse possible leaked file descriptors
15986        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15987            throw new IllegalArgumentException("File descriptors passed in Bundle");
15988        }
15989
15990        final long origId = Binder.clearCallingIdentity();
15991        try {
15992            boolean doNext = false;
15993            BroadcastRecord r;
15994
15995            synchronized(this) {
15996                r = broadcastRecordForReceiverLocked(who);
15997                if (r != null) {
15998                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15999                        resultData, resultExtras, resultAbort, true);
16000                }
16001            }
16002
16003            if (doNext) {
16004                r.queue.processNextBroadcast(false);
16005            }
16006            trimApplications();
16007        } finally {
16008            Binder.restoreCallingIdentity(origId);
16009        }
16010    }
16011
16012    // =========================================================
16013    // INSTRUMENTATION
16014    // =========================================================
16015
16016    public boolean startInstrumentation(ComponentName className,
16017            String profileFile, int flags, Bundle arguments,
16018            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16019            int userId, String abiOverride) {
16020        enforceNotIsolatedCaller("startInstrumentation");
16021        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16022                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16023        // Refuse possible leaked file descriptors
16024        if (arguments != null && arguments.hasFileDescriptors()) {
16025            throw new IllegalArgumentException("File descriptors passed in Bundle");
16026        }
16027
16028        synchronized(this) {
16029            InstrumentationInfo ii = null;
16030            ApplicationInfo ai = null;
16031            try {
16032                ii = mContext.getPackageManager().getInstrumentationInfo(
16033                    className, STOCK_PM_FLAGS);
16034                ai = AppGlobals.getPackageManager().getApplicationInfo(
16035                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16036            } catch (PackageManager.NameNotFoundException e) {
16037            } catch (RemoteException e) {
16038            }
16039            if (ii == null) {
16040                reportStartInstrumentationFailure(watcher, className,
16041                        "Unable to find instrumentation info for: " + className);
16042                return false;
16043            }
16044            if (ai == null) {
16045                reportStartInstrumentationFailure(watcher, className,
16046                        "Unable to find instrumentation target package: " + ii.targetPackage);
16047                return false;
16048            }
16049
16050            int match = mContext.getPackageManager().checkSignatures(
16051                    ii.targetPackage, ii.packageName);
16052            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16053                String msg = "Permission Denial: starting instrumentation "
16054                        + className + " from pid="
16055                        + Binder.getCallingPid()
16056                        + ", uid=" + Binder.getCallingPid()
16057                        + " not allowed because package " + ii.packageName
16058                        + " does not have a signature matching the target "
16059                        + ii.targetPackage;
16060                reportStartInstrumentationFailure(watcher, className, msg);
16061                throw new SecurityException(msg);
16062            }
16063
16064            final long origId = Binder.clearCallingIdentity();
16065            // Instrumentation can kill and relaunch even persistent processes
16066            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16067                    "start instr");
16068            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16069            app.instrumentationClass = className;
16070            app.instrumentationInfo = ai;
16071            app.instrumentationProfileFile = profileFile;
16072            app.instrumentationArguments = arguments;
16073            app.instrumentationWatcher = watcher;
16074            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16075            app.instrumentationResultClass = className;
16076            Binder.restoreCallingIdentity(origId);
16077        }
16078
16079        return true;
16080    }
16081
16082    /**
16083     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16084     * error to the logs, but if somebody is watching, send the report there too.  This enables
16085     * the "am" command to report errors with more information.
16086     *
16087     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16088     * @param cn The component name of the instrumentation.
16089     * @param report The error report.
16090     */
16091    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16092            ComponentName cn, String report) {
16093        Slog.w(TAG, report);
16094        try {
16095            if (watcher != null) {
16096                Bundle results = new Bundle();
16097                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16098                results.putString("Error", report);
16099                watcher.instrumentationStatus(cn, -1, results);
16100            }
16101        } catch (RemoteException e) {
16102            Slog.w(TAG, e);
16103        }
16104    }
16105
16106    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16107        if (app.instrumentationWatcher != null) {
16108            try {
16109                // NOTE:  IInstrumentationWatcher *must* be oneway here
16110                app.instrumentationWatcher.instrumentationFinished(
16111                    app.instrumentationClass,
16112                    resultCode,
16113                    results);
16114            } catch (RemoteException e) {
16115            }
16116        }
16117        if (app.instrumentationUiAutomationConnection != null) {
16118            try {
16119                app.instrumentationUiAutomationConnection.shutdown();
16120            } catch (RemoteException re) {
16121                /* ignore */
16122            }
16123            // Only a UiAutomation can set this flag and now that
16124            // it is finished we make sure it is reset to its default.
16125            mUserIsMonkey = false;
16126        }
16127        app.instrumentationWatcher = null;
16128        app.instrumentationUiAutomationConnection = null;
16129        app.instrumentationClass = null;
16130        app.instrumentationInfo = null;
16131        app.instrumentationProfileFile = null;
16132        app.instrumentationArguments = null;
16133
16134        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16135                "finished inst");
16136    }
16137
16138    public void finishInstrumentation(IApplicationThread target,
16139            int resultCode, Bundle results) {
16140        int userId = UserHandle.getCallingUserId();
16141        // Refuse possible leaked file descriptors
16142        if (results != null && results.hasFileDescriptors()) {
16143            throw new IllegalArgumentException("File descriptors passed in Intent");
16144        }
16145
16146        synchronized(this) {
16147            ProcessRecord app = getRecordForAppLocked(target);
16148            if (app == null) {
16149                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16150                return;
16151            }
16152            final long origId = Binder.clearCallingIdentity();
16153            finishInstrumentationLocked(app, resultCode, results);
16154            Binder.restoreCallingIdentity(origId);
16155        }
16156    }
16157
16158    // =========================================================
16159    // CONFIGURATION
16160    // =========================================================
16161
16162    public ConfigurationInfo getDeviceConfigurationInfo() {
16163        ConfigurationInfo config = new ConfigurationInfo();
16164        synchronized (this) {
16165            config.reqTouchScreen = mConfiguration.touchscreen;
16166            config.reqKeyboardType = mConfiguration.keyboard;
16167            config.reqNavigation = mConfiguration.navigation;
16168            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16169                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16170                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16171            }
16172            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16173                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16174                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16175            }
16176            config.reqGlEsVersion = GL_ES_VERSION;
16177        }
16178        return config;
16179    }
16180
16181    ActivityStack getFocusedStack() {
16182        return mStackSupervisor.getFocusedStack();
16183    }
16184
16185    public Configuration getConfiguration() {
16186        Configuration ci;
16187        synchronized(this) {
16188            ci = new Configuration(mConfiguration);
16189        }
16190        return ci;
16191    }
16192
16193    public void updatePersistentConfiguration(Configuration values) {
16194        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16195                "updateConfiguration()");
16196        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16197                "updateConfiguration()");
16198        if (values == null) {
16199            throw new NullPointerException("Configuration must not be null");
16200        }
16201
16202        synchronized(this) {
16203            final long origId = Binder.clearCallingIdentity();
16204            updateConfigurationLocked(values, null, true, false);
16205            Binder.restoreCallingIdentity(origId);
16206        }
16207    }
16208
16209    public void updateConfiguration(Configuration values) {
16210        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16211                "updateConfiguration()");
16212
16213        synchronized(this) {
16214            if (values == null && mWindowManager != null) {
16215                // sentinel: fetch the current configuration from the window manager
16216                values = mWindowManager.computeNewConfiguration();
16217            }
16218
16219            if (mWindowManager != null) {
16220                mProcessList.applyDisplaySize(mWindowManager);
16221            }
16222
16223            final long origId = Binder.clearCallingIdentity();
16224            if (values != null) {
16225                Settings.System.clearConfiguration(values);
16226            }
16227            updateConfigurationLocked(values, null, false, false);
16228            Binder.restoreCallingIdentity(origId);
16229        }
16230    }
16231
16232    /**
16233     * Do either or both things: (1) change the current configuration, and (2)
16234     * make sure the given activity is running with the (now) current
16235     * configuration.  Returns true if the activity has been left running, or
16236     * false if <var>starting</var> is being destroyed to match the new
16237     * configuration.
16238     * @param persistent TODO
16239     */
16240    boolean updateConfigurationLocked(Configuration values,
16241            ActivityRecord starting, boolean persistent, boolean initLocale) {
16242        int changes = 0;
16243
16244        if (values != null) {
16245            Configuration newConfig = new Configuration(mConfiguration);
16246            changes = newConfig.updateFrom(values);
16247            if (changes != 0) {
16248                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16249                    Slog.i(TAG, "Updating configuration to: " + values);
16250                }
16251
16252                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16253
16254                if (values.locale != null && !initLocale) {
16255                    saveLocaleLocked(values.locale,
16256                                     !values.locale.equals(mConfiguration.locale),
16257                                     values.userSetLocale);
16258                }
16259
16260                mConfigurationSeq++;
16261                if (mConfigurationSeq <= 0) {
16262                    mConfigurationSeq = 1;
16263                }
16264                newConfig.seq = mConfigurationSeq;
16265                mConfiguration = newConfig;
16266                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16267                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16268                //mUsageStatsService.noteStartConfig(newConfig);
16269
16270                final Configuration configCopy = new Configuration(mConfiguration);
16271
16272                // TODO: If our config changes, should we auto dismiss any currently
16273                // showing dialogs?
16274                mShowDialogs = shouldShowDialogs(newConfig);
16275
16276                AttributeCache ac = AttributeCache.instance();
16277                if (ac != null) {
16278                    ac.updateConfiguration(configCopy);
16279                }
16280
16281                // Make sure all resources in our process are updated
16282                // right now, so that anyone who is going to retrieve
16283                // resource values after we return will be sure to get
16284                // the new ones.  This is especially important during
16285                // boot, where the first config change needs to guarantee
16286                // all resources have that config before following boot
16287                // code is executed.
16288                mSystemThread.applyConfigurationToResources(configCopy);
16289
16290                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16291                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16292                    msg.obj = new Configuration(configCopy);
16293                    mHandler.sendMessage(msg);
16294                }
16295
16296                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16297                    ProcessRecord app = mLruProcesses.get(i);
16298                    try {
16299                        if (app.thread != null) {
16300                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16301                                    + app.processName + " new config " + mConfiguration);
16302                            app.thread.scheduleConfigurationChanged(configCopy);
16303                        }
16304                    } catch (Exception e) {
16305                    }
16306                }
16307                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16308                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16309                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16310                        | Intent.FLAG_RECEIVER_FOREGROUND);
16311                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16312                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16313                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16314                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16315                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16316                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16317                    broadcastIntentLocked(null, null, intent,
16318                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16319                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16320                }
16321            }
16322        }
16323
16324        boolean kept = true;
16325        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16326        // mainStack is null during startup.
16327        if (mainStack != null) {
16328            if (changes != 0 && starting == null) {
16329                // If the configuration changed, and the caller is not already
16330                // in the process of starting an activity, then find the top
16331                // activity to check if its configuration needs to change.
16332                starting = mainStack.topRunningActivityLocked(null);
16333            }
16334
16335            if (starting != null) {
16336                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16337                // And we need to make sure at this point that all other activities
16338                // are made visible with the correct configuration.
16339                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16340            }
16341        }
16342
16343        if (values != null && mWindowManager != null) {
16344            mWindowManager.setNewConfiguration(mConfiguration);
16345        }
16346
16347        return kept;
16348    }
16349
16350    /**
16351     * Decide based on the configuration whether we should shouw the ANR,
16352     * crash, etc dialogs.  The idea is that if there is no affordnace to
16353     * press the on-screen buttons, we shouldn't show the dialog.
16354     *
16355     * A thought: SystemUI might also want to get told about this, the Power
16356     * dialog / global actions also might want different behaviors.
16357     */
16358    private static final boolean shouldShowDialogs(Configuration config) {
16359        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16360                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16361    }
16362
16363    /**
16364     * Save the locale.  You must be inside a synchronized (this) block.
16365     */
16366    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16367        if(isDiff) {
16368            SystemProperties.set("user.language", l.getLanguage());
16369            SystemProperties.set("user.region", l.getCountry());
16370        }
16371
16372        if(isPersist) {
16373            SystemProperties.set("persist.sys.language", l.getLanguage());
16374            SystemProperties.set("persist.sys.country", l.getCountry());
16375            SystemProperties.set("persist.sys.localevar", l.getVariant());
16376
16377            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16378        }
16379    }
16380
16381    @Override
16382    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16383        synchronized (this) {
16384            ActivityRecord srec = ActivityRecord.forToken(token);
16385            if (srec.task != null && srec.task.stack != null) {
16386                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16387            }
16388        }
16389        return false;
16390    }
16391
16392    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16393            Intent resultData) {
16394
16395        synchronized (this) {
16396            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16397            if (stack != null) {
16398                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16399            }
16400            return false;
16401        }
16402    }
16403
16404    public int getLaunchedFromUid(IBinder activityToken) {
16405        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16406        if (srec == null) {
16407            return -1;
16408        }
16409        return srec.launchedFromUid;
16410    }
16411
16412    public String getLaunchedFromPackage(IBinder activityToken) {
16413        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16414        if (srec == null) {
16415            return null;
16416        }
16417        return srec.launchedFromPackage;
16418    }
16419
16420    // =========================================================
16421    // LIFETIME MANAGEMENT
16422    // =========================================================
16423
16424    // Returns which broadcast queue the app is the current [or imminent] receiver
16425    // on, or 'null' if the app is not an active broadcast recipient.
16426    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16427        BroadcastRecord r = app.curReceiver;
16428        if (r != null) {
16429            return r.queue;
16430        }
16431
16432        // It's not the current receiver, but it might be starting up to become one
16433        synchronized (this) {
16434            for (BroadcastQueue queue : mBroadcastQueues) {
16435                r = queue.mPendingBroadcast;
16436                if (r != null && r.curApp == app) {
16437                    // found it; report which queue it's in
16438                    return queue;
16439                }
16440            }
16441        }
16442
16443        return null;
16444    }
16445
16446    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16447            boolean doingAll, long now) {
16448        if (mAdjSeq == app.adjSeq) {
16449            // This adjustment has already been computed.
16450            return app.curRawAdj;
16451        }
16452
16453        if (app.thread == null) {
16454            app.adjSeq = mAdjSeq;
16455            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16456            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16457            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16458        }
16459
16460        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16461        app.adjSource = null;
16462        app.adjTarget = null;
16463        app.empty = false;
16464        app.cached = false;
16465
16466        final int activitiesSize = app.activities.size();
16467
16468        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16469            // The max adjustment doesn't allow this app to be anything
16470            // below foreground, so it is not worth doing work for it.
16471            app.adjType = "fixed";
16472            app.adjSeq = mAdjSeq;
16473            app.curRawAdj = app.maxAdj;
16474            app.foregroundActivities = false;
16475            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16476            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16477            // System processes can do UI, and when they do we want to have
16478            // them trim their memory after the user leaves the UI.  To
16479            // facilitate this, here we need to determine whether or not it
16480            // is currently showing UI.
16481            app.systemNoUi = true;
16482            if (app == TOP_APP) {
16483                app.systemNoUi = false;
16484            } else if (activitiesSize > 0) {
16485                for (int j = 0; j < activitiesSize; j++) {
16486                    final ActivityRecord r = app.activities.get(j);
16487                    if (r.visible) {
16488                        app.systemNoUi = false;
16489                    }
16490                }
16491            }
16492            if (!app.systemNoUi) {
16493                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16494            }
16495            return (app.curAdj=app.maxAdj);
16496        }
16497
16498        app.systemNoUi = false;
16499
16500        // Determine the importance of the process, starting with most
16501        // important to least, and assign an appropriate OOM adjustment.
16502        int adj;
16503        int schedGroup;
16504        int procState;
16505        boolean foregroundActivities = false;
16506        BroadcastQueue queue;
16507        if (app == TOP_APP) {
16508            // The last app on the list is the foreground app.
16509            adj = ProcessList.FOREGROUND_APP_ADJ;
16510            schedGroup = Process.THREAD_GROUP_DEFAULT;
16511            app.adjType = "top-activity";
16512            foregroundActivities = true;
16513            procState = ActivityManager.PROCESS_STATE_TOP;
16514        } else if (app.instrumentationClass != null) {
16515            // Don't want to kill running instrumentation.
16516            adj = ProcessList.FOREGROUND_APP_ADJ;
16517            schedGroup = Process.THREAD_GROUP_DEFAULT;
16518            app.adjType = "instrumentation";
16519            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16520        } else if ((queue = isReceivingBroadcast(app)) != null) {
16521            // An app that is currently receiving a broadcast also
16522            // counts as being in the foreground for OOM killer purposes.
16523            // It's placed in a sched group based on the nature of the
16524            // broadcast as reflected by which queue it's active in.
16525            adj = ProcessList.FOREGROUND_APP_ADJ;
16526            schedGroup = (queue == mFgBroadcastQueue)
16527                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16528            app.adjType = "broadcast";
16529            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16530        } else if (app.executingServices.size() > 0) {
16531            // An app that is currently executing a service callback also
16532            // counts as being in the foreground.
16533            adj = ProcessList.FOREGROUND_APP_ADJ;
16534            schedGroup = app.execServicesFg ?
16535                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16536            app.adjType = "exec-service";
16537            procState = ActivityManager.PROCESS_STATE_SERVICE;
16538            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16539        } else {
16540            // As far as we know the process is empty.  We may change our mind later.
16541            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16542            // At this point we don't actually know the adjustment.  Use the cached adj
16543            // value that the caller wants us to.
16544            adj = cachedAdj;
16545            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16546            app.cached = true;
16547            app.empty = true;
16548            app.adjType = "cch-empty";
16549        }
16550
16551        // Examine all activities if not already foreground.
16552        if (!foregroundActivities && activitiesSize > 0) {
16553            for (int j = 0; j < activitiesSize; j++) {
16554                final ActivityRecord r = app.activities.get(j);
16555                if (r.app != app) {
16556                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16557                            + app + "?!?");
16558                    continue;
16559                }
16560                if (r.visible) {
16561                    // App has a visible activity; only upgrade adjustment.
16562                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16563                        adj = ProcessList.VISIBLE_APP_ADJ;
16564                        app.adjType = "visible";
16565                    }
16566                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16567                        procState = ActivityManager.PROCESS_STATE_TOP;
16568                    }
16569                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16570                    app.cached = false;
16571                    app.empty = false;
16572                    foregroundActivities = true;
16573                    break;
16574                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16575                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16576                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16577                        app.adjType = "pausing";
16578                    }
16579                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16580                        procState = ActivityManager.PROCESS_STATE_TOP;
16581                    }
16582                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16583                    app.cached = false;
16584                    app.empty = false;
16585                    foregroundActivities = true;
16586                } else if (r.state == ActivityState.STOPPING) {
16587                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16588                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16589                        app.adjType = "stopping";
16590                    }
16591                    // For the process state, we will at this point consider the
16592                    // process to be cached.  It will be cached either as an activity
16593                    // or empty depending on whether the activity is finishing.  We do
16594                    // this so that we can treat the process as cached for purposes of
16595                    // memory trimming (determing current memory level, trim command to
16596                    // send to process) since there can be an arbitrary number of stopping
16597                    // processes and they should soon all go into the cached state.
16598                    if (!r.finishing) {
16599                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16600                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16601                        }
16602                    }
16603                    app.cached = false;
16604                    app.empty = false;
16605                    foregroundActivities = true;
16606                } else {
16607                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16608                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16609                        app.adjType = "cch-act";
16610                    }
16611                }
16612            }
16613        }
16614
16615        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16616            if (app.foregroundServices) {
16617                // The user is aware of this app, so make it visible.
16618                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16619                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16620                app.cached = false;
16621                app.adjType = "fg-service";
16622                schedGroup = Process.THREAD_GROUP_DEFAULT;
16623            } else if (app.forcingToForeground != null) {
16624                // The user is aware of this app, so make it visible.
16625                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16626                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16627                app.cached = false;
16628                app.adjType = "force-fg";
16629                app.adjSource = app.forcingToForeground;
16630                schedGroup = Process.THREAD_GROUP_DEFAULT;
16631            }
16632        }
16633
16634        if (app == mHeavyWeightProcess) {
16635            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16636                // We don't want to kill the current heavy-weight process.
16637                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16638                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16639                app.cached = false;
16640                app.adjType = "heavy";
16641            }
16642            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16643                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16644            }
16645        }
16646
16647        if (app == mHomeProcess) {
16648            if (adj > ProcessList.HOME_APP_ADJ) {
16649                // This process is hosting what we currently consider to be the
16650                // home app, so we don't want to let it go into the background.
16651                adj = ProcessList.HOME_APP_ADJ;
16652                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16653                app.cached = false;
16654                app.adjType = "home";
16655            }
16656            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16657                procState = ActivityManager.PROCESS_STATE_HOME;
16658            }
16659        }
16660
16661        if (app == mPreviousProcess && app.activities.size() > 0) {
16662            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16663                // This was the previous process that showed UI to the user.
16664                // We want to try to keep it around more aggressively, to give
16665                // a good experience around switching between two apps.
16666                adj = ProcessList.PREVIOUS_APP_ADJ;
16667                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16668                app.cached = false;
16669                app.adjType = "previous";
16670            }
16671            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16672                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16673            }
16674        }
16675
16676        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16677                + " reason=" + app.adjType);
16678
16679        // By default, we use the computed adjustment.  It may be changed if
16680        // there are applications dependent on our services or providers, but
16681        // this gives us a baseline and makes sure we don't get into an
16682        // infinite recursion.
16683        app.adjSeq = mAdjSeq;
16684        app.curRawAdj = adj;
16685        app.hasStartedServices = false;
16686
16687        if (mBackupTarget != null && app == mBackupTarget.app) {
16688            // If possible we want to avoid killing apps while they're being backed up
16689            if (adj > ProcessList.BACKUP_APP_ADJ) {
16690                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16691                adj = ProcessList.BACKUP_APP_ADJ;
16692                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16693                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16694                }
16695                app.adjType = "backup";
16696                app.cached = false;
16697            }
16698            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16699                procState = ActivityManager.PROCESS_STATE_BACKUP;
16700            }
16701        }
16702
16703        boolean mayBeTop = false;
16704
16705        for (int is = app.services.size()-1;
16706                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16707                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16708                        || procState > ActivityManager.PROCESS_STATE_TOP);
16709                is--) {
16710            ServiceRecord s = app.services.valueAt(is);
16711            if (s.startRequested) {
16712                app.hasStartedServices = true;
16713                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16714                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16715                }
16716                if (app.hasShownUi && app != mHomeProcess) {
16717                    // If this process has shown some UI, let it immediately
16718                    // go to the LRU list because it may be pretty heavy with
16719                    // UI stuff.  We'll tag it with a label just to help
16720                    // debug and understand what is going on.
16721                    if (adj > ProcessList.SERVICE_ADJ) {
16722                        app.adjType = "cch-started-ui-services";
16723                    }
16724                } else {
16725                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16726                        // This service has seen some activity within
16727                        // recent memory, so we will keep its process ahead
16728                        // of the background processes.
16729                        if (adj > ProcessList.SERVICE_ADJ) {
16730                            adj = ProcessList.SERVICE_ADJ;
16731                            app.adjType = "started-services";
16732                            app.cached = false;
16733                        }
16734                    }
16735                    // If we have let the service slide into the background
16736                    // state, still have some text describing what it is doing
16737                    // even though the service no longer has an impact.
16738                    if (adj > ProcessList.SERVICE_ADJ) {
16739                        app.adjType = "cch-started-services";
16740                    }
16741                }
16742            }
16743            for (int conni = s.connections.size()-1;
16744                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16745                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16746                            || procState > ActivityManager.PROCESS_STATE_TOP);
16747                    conni--) {
16748                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16749                for (int i = 0;
16750                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16751                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16752                                || procState > ActivityManager.PROCESS_STATE_TOP);
16753                        i++) {
16754                    // XXX should compute this based on the max of
16755                    // all connected clients.
16756                    ConnectionRecord cr = clist.get(i);
16757                    if (cr.binding.client == app) {
16758                        // Binding to ourself is not interesting.
16759                        continue;
16760                    }
16761                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16762                        ProcessRecord client = cr.binding.client;
16763                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16764                                TOP_APP, doingAll, now);
16765                        int clientProcState = client.curProcState;
16766                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16767                            // If the other app is cached for any reason, for purposes here
16768                            // we are going to consider it empty.  The specific cached state
16769                            // doesn't propagate except under certain conditions.
16770                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16771                        }
16772                        String adjType = null;
16773                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16774                            // Not doing bind OOM management, so treat
16775                            // this guy more like a started service.
16776                            if (app.hasShownUi && app != mHomeProcess) {
16777                                // If this process has shown some UI, let it immediately
16778                                // go to the LRU list because it may be pretty heavy with
16779                                // UI stuff.  We'll tag it with a label just to help
16780                                // debug and understand what is going on.
16781                                if (adj > clientAdj) {
16782                                    adjType = "cch-bound-ui-services";
16783                                }
16784                                app.cached = false;
16785                                clientAdj = adj;
16786                                clientProcState = procState;
16787                            } else {
16788                                if (now >= (s.lastActivity
16789                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16790                                    // This service has not seen activity within
16791                                    // recent memory, so allow it to drop to the
16792                                    // LRU list if there is no other reason to keep
16793                                    // it around.  We'll also tag it with a label just
16794                                    // to help debug and undertand what is going on.
16795                                    if (adj > clientAdj) {
16796                                        adjType = "cch-bound-services";
16797                                    }
16798                                    clientAdj = adj;
16799                                }
16800                            }
16801                        }
16802                        if (adj > clientAdj) {
16803                            // If this process has recently shown UI, and
16804                            // the process that is binding to it is less
16805                            // important than being visible, then we don't
16806                            // care about the binding as much as we care
16807                            // about letting this process get into the LRU
16808                            // list to be killed and restarted if needed for
16809                            // memory.
16810                            if (app.hasShownUi && app != mHomeProcess
16811                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16812                                adjType = "cch-bound-ui-services";
16813                            } else {
16814                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16815                                        |Context.BIND_IMPORTANT)) != 0) {
16816                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
16817                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
16818                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16819                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16820                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16821                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16822                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16823                                    adj = clientAdj;
16824                                } else {
16825                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16826                                        adj = ProcessList.VISIBLE_APP_ADJ;
16827                                    }
16828                                }
16829                                if (!client.cached) {
16830                                    app.cached = false;
16831                                }
16832                                adjType = "service";
16833                            }
16834                        }
16835                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16836                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16837                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16838                            }
16839                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16840                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16841                                    // Special handling of clients who are in the top state.
16842                                    // We *may* want to consider this process to be in the
16843                                    // top state as well, but only if there is not another
16844                                    // reason for it to be running.  Being on the top is a
16845                                    // special state, meaning you are specifically running
16846                                    // for the current top app.  If the process is already
16847                                    // running in the background for some other reason, it
16848                                    // is more important to continue considering it to be
16849                                    // in the background state.
16850                                    mayBeTop = true;
16851                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16852                                } else {
16853                                    // Special handling for above-top states (persistent
16854                                    // processes).  These should not bring the current process
16855                                    // into the top state, since they are not on top.  Instead
16856                                    // give them the best state after that.
16857                                    clientProcState =
16858                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16859                                }
16860                            }
16861                        } else {
16862                            if (clientProcState <
16863                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16864                                clientProcState =
16865                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16866                            }
16867                        }
16868                        if (procState > clientProcState) {
16869                            procState = clientProcState;
16870                        }
16871                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16872                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16873                            app.pendingUiClean = true;
16874                        }
16875                        if (adjType != null) {
16876                            app.adjType = adjType;
16877                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16878                                    .REASON_SERVICE_IN_USE;
16879                            app.adjSource = cr.binding.client;
16880                            app.adjSourceProcState = clientProcState;
16881                            app.adjTarget = s.name;
16882                        }
16883                    }
16884                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16885                        app.treatLikeActivity = true;
16886                    }
16887                    final ActivityRecord a = cr.activity;
16888                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16889                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16890                                (a.visible || a.state == ActivityState.RESUMED
16891                                 || a.state == ActivityState.PAUSING)) {
16892                            adj = ProcessList.FOREGROUND_APP_ADJ;
16893                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16894                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16895                            }
16896                            app.cached = false;
16897                            app.adjType = "service";
16898                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16899                                    .REASON_SERVICE_IN_USE;
16900                            app.adjSource = a;
16901                            app.adjSourceProcState = procState;
16902                            app.adjTarget = s.name;
16903                        }
16904                    }
16905                }
16906            }
16907        }
16908
16909        for (int provi = app.pubProviders.size()-1;
16910                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16911                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16912                        || procState > ActivityManager.PROCESS_STATE_TOP);
16913                provi--) {
16914            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16915            for (int i = cpr.connections.size()-1;
16916                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16917                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16918                            || procState > ActivityManager.PROCESS_STATE_TOP);
16919                    i--) {
16920                ContentProviderConnection conn = cpr.connections.get(i);
16921                ProcessRecord client = conn.client;
16922                if (client == app) {
16923                    // Being our own client is not interesting.
16924                    continue;
16925                }
16926                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16927                int clientProcState = client.curProcState;
16928                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16929                    // If the other app is cached for any reason, for purposes here
16930                    // we are going to consider it empty.
16931                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16932                }
16933                if (adj > clientAdj) {
16934                    if (app.hasShownUi && app != mHomeProcess
16935                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16936                        app.adjType = "cch-ui-provider";
16937                    } else {
16938                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16939                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16940                        app.adjType = "provider";
16941                    }
16942                    app.cached &= client.cached;
16943                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16944                            .REASON_PROVIDER_IN_USE;
16945                    app.adjSource = client;
16946                    app.adjSourceProcState = clientProcState;
16947                    app.adjTarget = cpr.name;
16948                }
16949                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16950                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16951                        // Special handling of clients who are in the top state.
16952                        // We *may* want to consider this process to be in the
16953                        // top state as well, but only if there is not another
16954                        // reason for it to be running.  Being on the top is a
16955                        // special state, meaning you are specifically running
16956                        // for the current top app.  If the process is already
16957                        // running in the background for some other reason, it
16958                        // is more important to continue considering it to be
16959                        // in the background state.
16960                        mayBeTop = true;
16961                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16962                    } else {
16963                        // Special handling for above-top states (persistent
16964                        // processes).  These should not bring the current process
16965                        // into the top state, since they are not on top.  Instead
16966                        // give them the best state after that.
16967                        clientProcState =
16968                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16969                    }
16970                }
16971                if (procState > clientProcState) {
16972                    procState = clientProcState;
16973                }
16974                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16975                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16976                }
16977            }
16978            // If the provider has external (non-framework) process
16979            // dependencies, ensure that its adjustment is at least
16980            // FOREGROUND_APP_ADJ.
16981            if (cpr.hasExternalProcessHandles()) {
16982                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16983                    adj = ProcessList.FOREGROUND_APP_ADJ;
16984                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16985                    app.cached = false;
16986                    app.adjType = "provider";
16987                    app.adjTarget = cpr.name;
16988                }
16989                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16990                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16991                }
16992            }
16993        }
16994
16995        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16996            // A client of one of our services or providers is in the top state.  We
16997            // *may* want to be in the top state, but not if we are already running in
16998            // the background for some other reason.  For the decision here, we are going
16999            // to pick out a few specific states that we want to remain in when a client
17000            // is top (states that tend to be longer-term) and otherwise allow it to go
17001            // to the top state.
17002            switch (procState) {
17003                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17004                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17005                case ActivityManager.PROCESS_STATE_SERVICE:
17006                    // These all are longer-term states, so pull them up to the top
17007                    // of the background states, but not all the way to the top state.
17008                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17009                    break;
17010                default:
17011                    // Otherwise, top is a better choice, so take it.
17012                    procState = ActivityManager.PROCESS_STATE_TOP;
17013                    break;
17014            }
17015        }
17016
17017        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17018            if (app.hasClientActivities) {
17019                // This is a cached process, but with client activities.  Mark it so.
17020                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17021                app.adjType = "cch-client-act";
17022            } else if (app.treatLikeActivity) {
17023                // This is a cached process, but somebody wants us to treat it like it has
17024                // an activity, okay!
17025                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17026                app.adjType = "cch-as-act";
17027            }
17028        }
17029
17030        if (adj == ProcessList.SERVICE_ADJ) {
17031            if (doingAll) {
17032                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17033                mNewNumServiceProcs++;
17034                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17035                if (!app.serviceb) {
17036                    // This service isn't far enough down on the LRU list to
17037                    // normally be a B service, but if we are low on RAM and it
17038                    // is large we want to force it down since we would prefer to
17039                    // keep launcher over it.
17040                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17041                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17042                        app.serviceHighRam = true;
17043                        app.serviceb = true;
17044                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17045                    } else {
17046                        mNewNumAServiceProcs++;
17047                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17048                    }
17049                } else {
17050                    app.serviceHighRam = false;
17051                }
17052            }
17053            if (app.serviceb) {
17054                adj = ProcessList.SERVICE_B_ADJ;
17055            }
17056        }
17057
17058        app.curRawAdj = adj;
17059
17060        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17061        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17062        if (adj > app.maxAdj) {
17063            adj = app.maxAdj;
17064            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17065                schedGroup = Process.THREAD_GROUP_DEFAULT;
17066            }
17067        }
17068
17069        // Do final modification to adj.  Everything we do between here and applying
17070        // the final setAdj must be done in this function, because we will also use
17071        // it when computing the final cached adj later.  Note that we don't need to
17072        // worry about this for max adj above, since max adj will always be used to
17073        // keep it out of the cached vaues.
17074        app.curAdj = app.modifyRawOomAdj(adj);
17075        app.curSchedGroup = schedGroup;
17076        app.curProcState = procState;
17077        app.foregroundActivities = foregroundActivities;
17078
17079        return app.curRawAdj;
17080    }
17081
17082    /**
17083     * Schedule PSS collection of a process.
17084     */
17085    void requestPssLocked(ProcessRecord proc, int procState) {
17086        if (mPendingPssProcesses.contains(proc)) {
17087            return;
17088        }
17089        if (mPendingPssProcesses.size() == 0) {
17090            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17091        }
17092        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17093        proc.pssProcState = procState;
17094        mPendingPssProcesses.add(proc);
17095    }
17096
17097    /**
17098     * Schedule PSS collection of all processes.
17099     */
17100    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17101        if (!always) {
17102            if (now < (mLastFullPssTime +
17103                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17104                return;
17105            }
17106        }
17107        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17108        mLastFullPssTime = now;
17109        mFullPssPending = true;
17110        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17111        mPendingPssProcesses.clear();
17112        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17113            ProcessRecord app = mLruProcesses.get(i);
17114            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17115                app.pssProcState = app.setProcState;
17116                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17117                        isSleeping(), now);
17118                mPendingPssProcesses.add(app);
17119            }
17120        }
17121        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17122    }
17123
17124    /**
17125     * Ask a given process to GC right now.
17126     */
17127    final void performAppGcLocked(ProcessRecord app) {
17128        try {
17129            app.lastRequestedGc = SystemClock.uptimeMillis();
17130            if (app.thread != null) {
17131                if (app.reportLowMemory) {
17132                    app.reportLowMemory = false;
17133                    app.thread.scheduleLowMemory();
17134                } else {
17135                    app.thread.processInBackground();
17136                }
17137            }
17138        } catch (Exception e) {
17139            // whatever.
17140        }
17141    }
17142
17143    /**
17144     * Returns true if things are idle enough to perform GCs.
17145     */
17146    private final boolean canGcNowLocked() {
17147        boolean processingBroadcasts = false;
17148        for (BroadcastQueue q : mBroadcastQueues) {
17149            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17150                processingBroadcasts = true;
17151            }
17152        }
17153        return !processingBroadcasts
17154                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17155    }
17156
17157    /**
17158     * Perform GCs on all processes that are waiting for it, but only
17159     * if things are idle.
17160     */
17161    final void performAppGcsLocked() {
17162        final int N = mProcessesToGc.size();
17163        if (N <= 0) {
17164            return;
17165        }
17166        if (canGcNowLocked()) {
17167            while (mProcessesToGc.size() > 0) {
17168                ProcessRecord proc = mProcessesToGc.remove(0);
17169                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17170                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17171                            <= SystemClock.uptimeMillis()) {
17172                        // To avoid spamming the system, we will GC processes one
17173                        // at a time, waiting a few seconds between each.
17174                        performAppGcLocked(proc);
17175                        scheduleAppGcsLocked();
17176                        return;
17177                    } else {
17178                        // It hasn't been long enough since we last GCed this
17179                        // process...  put it in the list to wait for its time.
17180                        addProcessToGcListLocked(proc);
17181                        break;
17182                    }
17183                }
17184            }
17185
17186            scheduleAppGcsLocked();
17187        }
17188    }
17189
17190    /**
17191     * If all looks good, perform GCs on all processes waiting for them.
17192     */
17193    final void performAppGcsIfAppropriateLocked() {
17194        if (canGcNowLocked()) {
17195            performAppGcsLocked();
17196            return;
17197        }
17198        // Still not idle, wait some more.
17199        scheduleAppGcsLocked();
17200    }
17201
17202    /**
17203     * Schedule the execution of all pending app GCs.
17204     */
17205    final void scheduleAppGcsLocked() {
17206        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17207
17208        if (mProcessesToGc.size() > 0) {
17209            // Schedule a GC for the time to the next process.
17210            ProcessRecord proc = mProcessesToGc.get(0);
17211            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17212
17213            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17214            long now = SystemClock.uptimeMillis();
17215            if (when < (now+GC_TIMEOUT)) {
17216                when = now + GC_TIMEOUT;
17217            }
17218            mHandler.sendMessageAtTime(msg, when);
17219        }
17220    }
17221
17222    /**
17223     * Add a process to the array of processes waiting to be GCed.  Keeps the
17224     * list in sorted order by the last GC time.  The process can't already be
17225     * on the list.
17226     */
17227    final void addProcessToGcListLocked(ProcessRecord proc) {
17228        boolean added = false;
17229        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17230            if (mProcessesToGc.get(i).lastRequestedGc <
17231                    proc.lastRequestedGc) {
17232                added = true;
17233                mProcessesToGc.add(i+1, proc);
17234                break;
17235            }
17236        }
17237        if (!added) {
17238            mProcessesToGc.add(0, proc);
17239        }
17240    }
17241
17242    /**
17243     * Set up to ask a process to GC itself.  This will either do it
17244     * immediately, or put it on the list of processes to gc the next
17245     * time things are idle.
17246     */
17247    final void scheduleAppGcLocked(ProcessRecord app) {
17248        long now = SystemClock.uptimeMillis();
17249        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17250            return;
17251        }
17252        if (!mProcessesToGc.contains(app)) {
17253            addProcessToGcListLocked(app);
17254            scheduleAppGcsLocked();
17255        }
17256    }
17257
17258    final void checkExcessivePowerUsageLocked(boolean doKills) {
17259        updateCpuStatsNow();
17260
17261        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17262        boolean doWakeKills = doKills;
17263        boolean doCpuKills = doKills;
17264        if (mLastPowerCheckRealtime == 0) {
17265            doWakeKills = false;
17266        }
17267        if (mLastPowerCheckUptime == 0) {
17268            doCpuKills = false;
17269        }
17270        if (stats.isScreenOn()) {
17271            doWakeKills = false;
17272        }
17273        final long curRealtime = SystemClock.elapsedRealtime();
17274        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17275        final long curUptime = SystemClock.uptimeMillis();
17276        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17277        mLastPowerCheckRealtime = curRealtime;
17278        mLastPowerCheckUptime = curUptime;
17279        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17280            doWakeKills = false;
17281        }
17282        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17283            doCpuKills = false;
17284        }
17285        int i = mLruProcesses.size();
17286        while (i > 0) {
17287            i--;
17288            ProcessRecord app = mLruProcesses.get(i);
17289            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17290                long wtime;
17291                synchronized (stats) {
17292                    wtime = stats.getProcessWakeTime(app.info.uid,
17293                            app.pid, curRealtime);
17294                }
17295                long wtimeUsed = wtime - app.lastWakeTime;
17296                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17297                if (DEBUG_POWER) {
17298                    StringBuilder sb = new StringBuilder(128);
17299                    sb.append("Wake for ");
17300                    app.toShortString(sb);
17301                    sb.append(": over ");
17302                    TimeUtils.formatDuration(realtimeSince, sb);
17303                    sb.append(" used ");
17304                    TimeUtils.formatDuration(wtimeUsed, sb);
17305                    sb.append(" (");
17306                    sb.append((wtimeUsed*100)/realtimeSince);
17307                    sb.append("%)");
17308                    Slog.i(TAG, sb.toString());
17309                    sb.setLength(0);
17310                    sb.append("CPU for ");
17311                    app.toShortString(sb);
17312                    sb.append(": over ");
17313                    TimeUtils.formatDuration(uptimeSince, sb);
17314                    sb.append(" used ");
17315                    TimeUtils.formatDuration(cputimeUsed, sb);
17316                    sb.append(" (");
17317                    sb.append((cputimeUsed*100)/uptimeSince);
17318                    sb.append("%)");
17319                    Slog.i(TAG, sb.toString());
17320                }
17321                // If a process has held a wake lock for more
17322                // than 50% of the time during this period,
17323                // that sounds bad.  Kill!
17324                if (doWakeKills && realtimeSince > 0
17325                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17326                    synchronized (stats) {
17327                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17328                                realtimeSince, wtimeUsed);
17329                    }
17330                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17331                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17332                } else if (doCpuKills && uptimeSince > 0
17333                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17334                    synchronized (stats) {
17335                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17336                                uptimeSince, cputimeUsed);
17337                    }
17338                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17339                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17340                } else {
17341                    app.lastWakeTime = wtime;
17342                    app.lastCpuTime = app.curCpuTime;
17343                }
17344            }
17345        }
17346    }
17347
17348    private final boolean applyOomAdjLocked(ProcessRecord app,
17349            ProcessRecord TOP_APP, boolean doingAll, long now) {
17350        boolean success = true;
17351
17352        if (app.curRawAdj != app.setRawAdj) {
17353            app.setRawAdj = app.curRawAdj;
17354        }
17355
17356        int changes = 0;
17357
17358        if (app.curAdj != app.setAdj) {
17359            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17360            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17361                TAG, "Set " + app.pid + " " + app.processName +
17362                " adj " + app.curAdj + ": " + app.adjType);
17363            app.setAdj = app.curAdj;
17364        }
17365
17366        if (app.setSchedGroup != app.curSchedGroup) {
17367            app.setSchedGroup = app.curSchedGroup;
17368            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17369                    "Setting process group of " + app.processName
17370                    + " to " + app.curSchedGroup);
17371            if (app.waitingToKill != null &&
17372                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17373                app.kill(app.waitingToKill, true);
17374                success = false;
17375            } else {
17376                if (true) {
17377                    long oldId = Binder.clearCallingIdentity();
17378                    try {
17379                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17380                    } catch (Exception e) {
17381                        Slog.w(TAG, "Failed setting process group of " + app.pid
17382                                + " to " + app.curSchedGroup);
17383                        e.printStackTrace();
17384                    } finally {
17385                        Binder.restoreCallingIdentity(oldId);
17386                    }
17387                } else {
17388                    if (app.thread != null) {
17389                        try {
17390                            app.thread.setSchedulingGroup(app.curSchedGroup);
17391                        } catch (RemoteException e) {
17392                        }
17393                    }
17394                }
17395                Process.setSwappiness(app.pid,
17396                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17397            }
17398        }
17399        if (app.repForegroundActivities != app.foregroundActivities) {
17400            app.repForegroundActivities = app.foregroundActivities;
17401            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17402        }
17403        if (app.repProcState != app.curProcState) {
17404            app.repProcState = app.curProcState;
17405            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17406            if (app.thread != null) {
17407                try {
17408                    if (false) {
17409                        //RuntimeException h = new RuntimeException("here");
17410                        Slog.i(TAG, "Sending new process state " + app.repProcState
17411                                + " to " + app /*, h*/);
17412                    }
17413                    app.thread.setProcessState(app.repProcState);
17414                } catch (RemoteException e) {
17415                }
17416            }
17417        }
17418        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17419                app.setProcState)) {
17420            app.lastStateTime = now;
17421            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17422                    isSleeping(), now);
17423            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17424                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17425                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17426                    + (app.nextPssTime-now) + ": " + app);
17427        } else {
17428            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17429                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17430                requestPssLocked(app, app.setProcState);
17431                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17432                        isSleeping(), now);
17433            } else if (false && DEBUG_PSS) {
17434                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17435            }
17436        }
17437        if (app.setProcState != app.curProcState) {
17438            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17439                    "Proc state change of " + app.processName
17440                    + " to " + app.curProcState);
17441            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17442            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17443            if (setImportant && !curImportant) {
17444                // This app is no longer something we consider important enough to allow to
17445                // use arbitrary amounts of battery power.  Note
17446                // its current wake lock time to later know to kill it if
17447                // it is not behaving well.
17448                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17449                synchronized (stats) {
17450                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17451                            app.pid, SystemClock.elapsedRealtime());
17452                }
17453                app.lastCpuTime = app.curCpuTime;
17454
17455            }
17456            app.setProcState = app.curProcState;
17457            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17458                app.notCachedSinceIdle = false;
17459            }
17460            if (!doingAll) {
17461                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17462            } else {
17463                app.procStateChanged = true;
17464            }
17465        }
17466
17467        if (changes != 0) {
17468            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17469            int i = mPendingProcessChanges.size()-1;
17470            ProcessChangeItem item = null;
17471            while (i >= 0) {
17472                item = mPendingProcessChanges.get(i);
17473                if (item.pid == app.pid) {
17474                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17475                    break;
17476                }
17477                i--;
17478            }
17479            if (i < 0) {
17480                // No existing item in pending changes; need a new one.
17481                final int NA = mAvailProcessChanges.size();
17482                if (NA > 0) {
17483                    item = mAvailProcessChanges.remove(NA-1);
17484                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17485                } else {
17486                    item = new ProcessChangeItem();
17487                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17488                }
17489                item.changes = 0;
17490                item.pid = app.pid;
17491                item.uid = app.info.uid;
17492                if (mPendingProcessChanges.size() == 0) {
17493                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17494                            "*** Enqueueing dispatch processes changed!");
17495                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17496                }
17497                mPendingProcessChanges.add(item);
17498            }
17499            item.changes |= changes;
17500            item.processState = app.repProcState;
17501            item.foregroundActivities = app.repForegroundActivities;
17502            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17503                    + Integer.toHexString(System.identityHashCode(item))
17504                    + " " + app.toShortString() + ": changes=" + item.changes
17505                    + " procState=" + item.processState
17506                    + " foreground=" + item.foregroundActivities
17507                    + " type=" + app.adjType + " source=" + app.adjSource
17508                    + " target=" + app.adjTarget);
17509        }
17510
17511        return success;
17512    }
17513
17514    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17515        if (proc.thread != null) {
17516            if (proc.baseProcessTracker != null) {
17517                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17518            }
17519            if (proc.repProcState >= 0) {
17520                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17521                        proc.repProcState);
17522            }
17523        }
17524    }
17525
17526    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17527            ProcessRecord TOP_APP, boolean doingAll, long now) {
17528        if (app.thread == null) {
17529            return false;
17530        }
17531
17532        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17533
17534        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17535    }
17536
17537    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17538            boolean oomAdj) {
17539        if (isForeground != proc.foregroundServices) {
17540            proc.foregroundServices = isForeground;
17541            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17542                    proc.info.uid);
17543            if (isForeground) {
17544                if (curProcs == null) {
17545                    curProcs = new ArrayList<ProcessRecord>();
17546                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17547                }
17548                if (!curProcs.contains(proc)) {
17549                    curProcs.add(proc);
17550                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17551                            proc.info.packageName, proc.info.uid);
17552                }
17553            } else {
17554                if (curProcs != null) {
17555                    if (curProcs.remove(proc)) {
17556                        mBatteryStatsService.noteEvent(
17557                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17558                                proc.info.packageName, proc.info.uid);
17559                        if (curProcs.size() <= 0) {
17560                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17561                        }
17562                    }
17563                }
17564            }
17565            if (oomAdj) {
17566                updateOomAdjLocked();
17567            }
17568        }
17569    }
17570
17571    private final ActivityRecord resumedAppLocked() {
17572        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17573        String pkg;
17574        int uid;
17575        if (act != null) {
17576            pkg = act.packageName;
17577            uid = act.info.applicationInfo.uid;
17578        } else {
17579            pkg = null;
17580            uid = -1;
17581        }
17582        // Has the UID or resumed package name changed?
17583        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17584                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17585            if (mCurResumedPackage != null) {
17586                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17587                        mCurResumedPackage, mCurResumedUid);
17588            }
17589            mCurResumedPackage = pkg;
17590            mCurResumedUid = uid;
17591            if (mCurResumedPackage != null) {
17592                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17593                        mCurResumedPackage, mCurResumedUid);
17594            }
17595        }
17596        return act;
17597    }
17598
17599    final boolean updateOomAdjLocked(ProcessRecord app) {
17600        final ActivityRecord TOP_ACT = resumedAppLocked();
17601        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17602        final boolean wasCached = app.cached;
17603
17604        mAdjSeq++;
17605
17606        // This is the desired cached adjusment we want to tell it to use.
17607        // If our app is currently cached, we know it, and that is it.  Otherwise,
17608        // we don't know it yet, and it needs to now be cached we will then
17609        // need to do a complete oom adj.
17610        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17611                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17612        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17613                SystemClock.uptimeMillis());
17614        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17615            // Changed to/from cached state, so apps after it in the LRU
17616            // list may also be changed.
17617            updateOomAdjLocked();
17618        }
17619        return success;
17620    }
17621
17622    final void updateOomAdjLocked() {
17623        final ActivityRecord TOP_ACT = resumedAppLocked();
17624        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17625        final long now = SystemClock.uptimeMillis();
17626        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17627        final int N = mLruProcesses.size();
17628
17629        if (false) {
17630            RuntimeException e = new RuntimeException();
17631            e.fillInStackTrace();
17632            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17633        }
17634
17635        mAdjSeq++;
17636        mNewNumServiceProcs = 0;
17637        mNewNumAServiceProcs = 0;
17638
17639        final int emptyProcessLimit;
17640        final int cachedProcessLimit;
17641        if (mProcessLimit <= 0) {
17642            emptyProcessLimit = cachedProcessLimit = 0;
17643        } else if (mProcessLimit == 1) {
17644            emptyProcessLimit = 1;
17645            cachedProcessLimit = 0;
17646        } else {
17647            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17648            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17649        }
17650
17651        // Let's determine how many processes we have running vs.
17652        // how many slots we have for background processes; we may want
17653        // to put multiple processes in a slot of there are enough of
17654        // them.
17655        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17656                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17657        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17658        if (numEmptyProcs > cachedProcessLimit) {
17659            // If there are more empty processes than our limit on cached
17660            // processes, then use the cached process limit for the factor.
17661            // This ensures that the really old empty processes get pushed
17662            // down to the bottom, so if we are running low on memory we will
17663            // have a better chance at keeping around more cached processes
17664            // instead of a gazillion empty processes.
17665            numEmptyProcs = cachedProcessLimit;
17666        }
17667        int emptyFactor = numEmptyProcs/numSlots;
17668        if (emptyFactor < 1) emptyFactor = 1;
17669        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17670        if (cachedFactor < 1) cachedFactor = 1;
17671        int stepCached = 0;
17672        int stepEmpty = 0;
17673        int numCached = 0;
17674        int numEmpty = 0;
17675        int numTrimming = 0;
17676
17677        mNumNonCachedProcs = 0;
17678        mNumCachedHiddenProcs = 0;
17679
17680        // First update the OOM adjustment for each of the
17681        // application processes based on their current state.
17682        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17683        int nextCachedAdj = curCachedAdj+1;
17684        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17685        int nextEmptyAdj = curEmptyAdj+2;
17686        for (int i=N-1; i>=0; i--) {
17687            ProcessRecord app = mLruProcesses.get(i);
17688            if (!app.killedByAm && app.thread != null) {
17689                app.procStateChanged = false;
17690                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17691
17692                // If we haven't yet assigned the final cached adj
17693                // to the process, do that now.
17694                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17695                    switch (app.curProcState) {
17696                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17697                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17698                            // This process is a cached process holding activities...
17699                            // assign it the next cached value for that type, and then
17700                            // step that cached level.
17701                            app.curRawAdj = curCachedAdj;
17702                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17703                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17704                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17705                                    + ")");
17706                            if (curCachedAdj != nextCachedAdj) {
17707                                stepCached++;
17708                                if (stepCached >= cachedFactor) {
17709                                    stepCached = 0;
17710                                    curCachedAdj = nextCachedAdj;
17711                                    nextCachedAdj += 2;
17712                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17713                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17714                                    }
17715                                }
17716                            }
17717                            break;
17718                        default:
17719                            // For everything else, assign next empty cached process
17720                            // level and bump that up.  Note that this means that
17721                            // long-running services that have dropped down to the
17722                            // cached level will be treated as empty (since their process
17723                            // state is still as a service), which is what we want.
17724                            app.curRawAdj = curEmptyAdj;
17725                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17726                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17727                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17728                                    + ")");
17729                            if (curEmptyAdj != nextEmptyAdj) {
17730                                stepEmpty++;
17731                                if (stepEmpty >= emptyFactor) {
17732                                    stepEmpty = 0;
17733                                    curEmptyAdj = nextEmptyAdj;
17734                                    nextEmptyAdj += 2;
17735                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17736                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17737                                    }
17738                                }
17739                            }
17740                            break;
17741                    }
17742                }
17743
17744                applyOomAdjLocked(app, TOP_APP, true, now);
17745
17746                // Count the number of process types.
17747                switch (app.curProcState) {
17748                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17749                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17750                        mNumCachedHiddenProcs++;
17751                        numCached++;
17752                        if (numCached > cachedProcessLimit) {
17753                            app.kill("cached #" + numCached, true);
17754                        }
17755                        break;
17756                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17757                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17758                                && app.lastActivityTime < oldTime) {
17759                            app.kill("empty for "
17760                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17761                                    / 1000) + "s", true);
17762                        } else {
17763                            numEmpty++;
17764                            if (numEmpty > emptyProcessLimit) {
17765                                app.kill("empty #" + numEmpty, true);
17766                            }
17767                        }
17768                        break;
17769                    default:
17770                        mNumNonCachedProcs++;
17771                        break;
17772                }
17773
17774                if (app.isolated && app.services.size() <= 0) {
17775                    // If this is an isolated process, and there are no
17776                    // services running in it, then the process is no longer
17777                    // needed.  We agressively kill these because we can by
17778                    // definition not re-use the same process again, and it is
17779                    // good to avoid having whatever code was running in them
17780                    // left sitting around after no longer needed.
17781                    app.kill("isolated not needed", true);
17782                }
17783
17784                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17785                        && !app.killedByAm) {
17786                    numTrimming++;
17787                }
17788            }
17789        }
17790
17791        mNumServiceProcs = mNewNumServiceProcs;
17792
17793        // Now determine the memory trimming level of background processes.
17794        // Unfortunately we need to start at the back of the list to do this
17795        // properly.  We only do this if the number of background apps we
17796        // are managing to keep around is less than half the maximum we desire;
17797        // if we are keeping a good number around, we'll let them use whatever
17798        // memory they want.
17799        final int numCachedAndEmpty = numCached + numEmpty;
17800        int memFactor;
17801        if (numCached <= ProcessList.TRIM_CACHED_APPS
17802                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17803            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17804                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17805            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17806                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17807            } else {
17808                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17809            }
17810        } else {
17811            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17812        }
17813        // We always allow the memory level to go up (better).  We only allow it to go
17814        // down if we are in a state where that is allowed, *and* the total number of processes
17815        // has gone down since last time.
17816        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17817                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17818                + " last=" + mLastNumProcesses);
17819        if (memFactor > mLastMemoryLevel) {
17820            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17821                memFactor = mLastMemoryLevel;
17822                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17823            }
17824        }
17825        mLastMemoryLevel = memFactor;
17826        mLastNumProcesses = mLruProcesses.size();
17827        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17828        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17829        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17830            if (mLowRamStartTime == 0) {
17831                mLowRamStartTime = now;
17832            }
17833            int step = 0;
17834            int fgTrimLevel;
17835            switch (memFactor) {
17836                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17837                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17838                    break;
17839                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17840                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17841                    break;
17842                default:
17843                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17844                    break;
17845            }
17846            int factor = numTrimming/3;
17847            int minFactor = 2;
17848            if (mHomeProcess != null) minFactor++;
17849            if (mPreviousProcess != null) minFactor++;
17850            if (factor < minFactor) factor = minFactor;
17851            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17852            for (int i=N-1; i>=0; i--) {
17853                ProcessRecord app = mLruProcesses.get(i);
17854                if (allChanged || app.procStateChanged) {
17855                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17856                    app.procStateChanged = false;
17857                }
17858                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17859                        && !app.killedByAm) {
17860                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17861                        try {
17862                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17863                                    "Trimming memory of " + app.processName
17864                                    + " to " + curLevel);
17865                            app.thread.scheduleTrimMemory(curLevel);
17866                        } catch (RemoteException e) {
17867                        }
17868                        if (false) {
17869                            // For now we won't do this; our memory trimming seems
17870                            // to be good enough at this point that destroying
17871                            // activities causes more harm than good.
17872                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17873                                    && app != mHomeProcess && app != mPreviousProcess) {
17874                                // Need to do this on its own message because the stack may not
17875                                // be in a consistent state at this point.
17876                                // For these apps we will also finish their activities
17877                                // to help them free memory.
17878                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17879                            }
17880                        }
17881                    }
17882                    app.trimMemoryLevel = curLevel;
17883                    step++;
17884                    if (step >= factor) {
17885                        step = 0;
17886                        switch (curLevel) {
17887                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17888                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17889                                break;
17890                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17891                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17892                                break;
17893                        }
17894                    }
17895                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17896                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17897                            && app.thread != null) {
17898                        try {
17899                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17900                                    "Trimming memory of heavy-weight " + app.processName
17901                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17902                            app.thread.scheduleTrimMemory(
17903                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17904                        } catch (RemoteException e) {
17905                        }
17906                    }
17907                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17908                } else {
17909                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17910                            || app.systemNoUi) && app.pendingUiClean) {
17911                        // If this application is now in the background and it
17912                        // had done UI, then give it the special trim level to
17913                        // have it free UI resources.
17914                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17915                        if (app.trimMemoryLevel < level && app.thread != null) {
17916                            try {
17917                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17918                                        "Trimming memory of bg-ui " + app.processName
17919                                        + " to " + level);
17920                                app.thread.scheduleTrimMemory(level);
17921                            } catch (RemoteException e) {
17922                            }
17923                        }
17924                        app.pendingUiClean = false;
17925                    }
17926                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17927                        try {
17928                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17929                                    "Trimming memory of fg " + app.processName
17930                                    + " to " + fgTrimLevel);
17931                            app.thread.scheduleTrimMemory(fgTrimLevel);
17932                        } catch (RemoteException e) {
17933                        }
17934                    }
17935                    app.trimMemoryLevel = fgTrimLevel;
17936                }
17937            }
17938        } else {
17939            if (mLowRamStartTime != 0) {
17940                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17941                mLowRamStartTime = 0;
17942            }
17943            for (int i=N-1; i>=0; i--) {
17944                ProcessRecord app = mLruProcesses.get(i);
17945                if (allChanged || app.procStateChanged) {
17946                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17947                    app.procStateChanged = false;
17948                }
17949                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17950                        || app.systemNoUi) && app.pendingUiClean) {
17951                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17952                            && app.thread != null) {
17953                        try {
17954                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17955                                    "Trimming memory of ui hidden " + app.processName
17956                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17957                            app.thread.scheduleTrimMemory(
17958                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17959                        } catch (RemoteException e) {
17960                        }
17961                    }
17962                    app.pendingUiClean = false;
17963                }
17964                app.trimMemoryLevel = 0;
17965            }
17966        }
17967
17968        if (mAlwaysFinishActivities) {
17969            // Need to do this on its own message because the stack may not
17970            // be in a consistent state at this point.
17971            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17972        }
17973
17974        if (allChanged) {
17975            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17976        }
17977
17978        if (mProcessStats.shouldWriteNowLocked(now)) {
17979            mHandler.post(new Runnable() {
17980                @Override public void run() {
17981                    synchronized (ActivityManagerService.this) {
17982                        mProcessStats.writeStateAsyncLocked();
17983                    }
17984                }
17985            });
17986        }
17987
17988        if (DEBUG_OOM_ADJ) {
17989            if (false) {
17990                RuntimeException here = new RuntimeException("here");
17991                here.fillInStackTrace();
17992                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
17993            } else {
17994                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17995            }
17996        }
17997    }
17998
17999    final void trimApplications() {
18000        synchronized (this) {
18001            int i;
18002
18003            // First remove any unused application processes whose package
18004            // has been removed.
18005            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18006                final ProcessRecord app = mRemovedProcesses.get(i);
18007                if (app.activities.size() == 0
18008                        && app.curReceiver == null && app.services.size() == 0) {
18009                    Slog.i(
18010                        TAG, "Exiting empty application process "
18011                        + app.processName + " ("
18012                        + (app.thread != null ? app.thread.asBinder() : null)
18013                        + ")\n");
18014                    if (app.pid > 0 && app.pid != MY_PID) {
18015                        app.kill("empty", false);
18016                    } else {
18017                        try {
18018                            app.thread.scheduleExit();
18019                        } catch (Exception e) {
18020                            // Ignore exceptions.
18021                        }
18022                    }
18023                    cleanUpApplicationRecordLocked(app, false, true, -1);
18024                    mRemovedProcesses.remove(i);
18025
18026                    if (app.persistent) {
18027                        addAppLocked(app.info, false, null /* ABI override */);
18028                    }
18029                }
18030            }
18031
18032            // Now update the oom adj for all processes.
18033            updateOomAdjLocked();
18034        }
18035    }
18036
18037    /** This method sends the specified signal to each of the persistent apps */
18038    public void signalPersistentProcesses(int sig) throws RemoteException {
18039        if (sig != Process.SIGNAL_USR1) {
18040            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18041        }
18042
18043        synchronized (this) {
18044            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18045                    != PackageManager.PERMISSION_GRANTED) {
18046                throw new SecurityException("Requires permission "
18047                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18048            }
18049
18050            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18051                ProcessRecord r = mLruProcesses.get(i);
18052                if (r.thread != null && r.persistent) {
18053                    Process.sendSignal(r.pid, sig);
18054                }
18055            }
18056        }
18057    }
18058
18059    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18060        if (proc == null || proc == mProfileProc) {
18061            proc = mProfileProc;
18062            profileType = mProfileType;
18063            clearProfilerLocked();
18064        }
18065        if (proc == null) {
18066            return;
18067        }
18068        try {
18069            proc.thread.profilerControl(false, null, profileType);
18070        } catch (RemoteException e) {
18071            throw new IllegalStateException("Process disappeared");
18072        }
18073    }
18074
18075    private void clearProfilerLocked() {
18076        if (mProfileFd != null) {
18077            try {
18078                mProfileFd.close();
18079            } catch (IOException e) {
18080            }
18081        }
18082        mProfileApp = null;
18083        mProfileProc = null;
18084        mProfileFile = null;
18085        mProfileType = 0;
18086        mAutoStopProfiler = false;
18087        mSamplingInterval = 0;
18088    }
18089
18090    public boolean profileControl(String process, int userId, boolean start,
18091            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18092
18093        try {
18094            synchronized (this) {
18095                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18096                // its own permission.
18097                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18098                        != PackageManager.PERMISSION_GRANTED) {
18099                    throw new SecurityException("Requires permission "
18100                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18101                }
18102
18103                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18104                    throw new IllegalArgumentException("null profile info or fd");
18105                }
18106
18107                ProcessRecord proc = null;
18108                if (process != null) {
18109                    proc = findProcessLocked(process, userId, "profileControl");
18110                }
18111
18112                if (start && (proc == null || proc.thread == null)) {
18113                    throw new IllegalArgumentException("Unknown process: " + process);
18114                }
18115
18116                if (start) {
18117                    stopProfilerLocked(null, 0);
18118                    setProfileApp(proc.info, proc.processName, profilerInfo);
18119                    mProfileProc = proc;
18120                    mProfileType = profileType;
18121                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18122                    try {
18123                        fd = fd.dup();
18124                    } catch (IOException e) {
18125                        fd = null;
18126                    }
18127                    profilerInfo.profileFd = fd;
18128                    proc.thread.profilerControl(start, profilerInfo, profileType);
18129                    fd = null;
18130                    mProfileFd = null;
18131                } else {
18132                    stopProfilerLocked(proc, profileType);
18133                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18134                        try {
18135                            profilerInfo.profileFd.close();
18136                        } catch (IOException e) {
18137                        }
18138                    }
18139                }
18140
18141                return true;
18142            }
18143        } catch (RemoteException e) {
18144            throw new IllegalStateException("Process disappeared");
18145        } finally {
18146            if (profilerInfo != null && profilerInfo.profileFd != null) {
18147                try {
18148                    profilerInfo.profileFd.close();
18149                } catch (IOException e) {
18150                }
18151            }
18152        }
18153    }
18154
18155    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18156        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18157                userId, true, ALLOW_FULL_ONLY, callName, null);
18158        ProcessRecord proc = null;
18159        try {
18160            int pid = Integer.parseInt(process);
18161            synchronized (mPidsSelfLocked) {
18162                proc = mPidsSelfLocked.get(pid);
18163            }
18164        } catch (NumberFormatException e) {
18165        }
18166
18167        if (proc == null) {
18168            ArrayMap<String, SparseArray<ProcessRecord>> all
18169                    = mProcessNames.getMap();
18170            SparseArray<ProcessRecord> procs = all.get(process);
18171            if (procs != null && procs.size() > 0) {
18172                proc = procs.valueAt(0);
18173                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18174                    for (int i=1; i<procs.size(); i++) {
18175                        ProcessRecord thisProc = procs.valueAt(i);
18176                        if (thisProc.userId == userId) {
18177                            proc = thisProc;
18178                            break;
18179                        }
18180                    }
18181                }
18182            }
18183        }
18184
18185        return proc;
18186    }
18187
18188    public boolean dumpHeap(String process, int userId, boolean managed,
18189            String path, ParcelFileDescriptor fd) throws RemoteException {
18190
18191        try {
18192            synchronized (this) {
18193                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18194                // its own permission (same as profileControl).
18195                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18196                        != PackageManager.PERMISSION_GRANTED) {
18197                    throw new SecurityException("Requires permission "
18198                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18199                }
18200
18201                if (fd == null) {
18202                    throw new IllegalArgumentException("null fd");
18203                }
18204
18205                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18206                if (proc == null || proc.thread == null) {
18207                    throw new IllegalArgumentException("Unknown process: " + process);
18208                }
18209
18210                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18211                if (!isDebuggable) {
18212                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18213                        throw new SecurityException("Process not debuggable: " + proc);
18214                    }
18215                }
18216
18217                proc.thread.dumpHeap(managed, path, fd);
18218                fd = null;
18219                return true;
18220            }
18221        } catch (RemoteException e) {
18222            throw new IllegalStateException("Process disappeared");
18223        } finally {
18224            if (fd != null) {
18225                try {
18226                    fd.close();
18227                } catch (IOException e) {
18228                }
18229            }
18230        }
18231    }
18232
18233    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18234    public void monitor() {
18235        synchronized (this) { }
18236    }
18237
18238    void onCoreSettingsChange(Bundle settings) {
18239        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18240            ProcessRecord processRecord = mLruProcesses.get(i);
18241            try {
18242                if (processRecord.thread != null) {
18243                    processRecord.thread.setCoreSettings(settings);
18244                }
18245            } catch (RemoteException re) {
18246                /* ignore */
18247            }
18248        }
18249    }
18250
18251    // Multi-user methods
18252
18253    /**
18254     * Start user, if its not already running, but don't bring it to foreground.
18255     */
18256    @Override
18257    public boolean startUserInBackground(final int userId) {
18258        return startUser(userId, /* foreground */ false);
18259    }
18260
18261    /**
18262     * Start user, if its not already running, and bring it to foreground.
18263     */
18264    boolean startUserInForeground(final int userId, Dialog dlg) {
18265        boolean result = startUser(userId, /* foreground */ true);
18266        dlg.dismiss();
18267        return result;
18268    }
18269
18270    /**
18271     * Refreshes the list of users related to the current user when either a
18272     * user switch happens or when a new related user is started in the
18273     * background.
18274     */
18275    private void updateCurrentProfileIdsLocked() {
18276        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18277                mCurrentUserId, false /* enabledOnly */);
18278        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18279        for (int i = 0; i < currentProfileIds.length; i++) {
18280            currentProfileIds[i] = profiles.get(i).id;
18281        }
18282        mCurrentProfileIds = currentProfileIds;
18283
18284        synchronized (mUserProfileGroupIdsSelfLocked) {
18285            mUserProfileGroupIdsSelfLocked.clear();
18286            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18287            for (int i = 0; i < users.size(); i++) {
18288                UserInfo user = users.get(i);
18289                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18290                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18291                }
18292            }
18293        }
18294    }
18295
18296    private Set getProfileIdsLocked(int userId) {
18297        Set userIds = new HashSet<Integer>();
18298        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18299                userId, false /* enabledOnly */);
18300        for (UserInfo user : profiles) {
18301            userIds.add(Integer.valueOf(user.id));
18302        }
18303        return userIds;
18304    }
18305
18306    @Override
18307    public boolean switchUser(final int userId) {
18308        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18309        String userName;
18310        synchronized (this) {
18311            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18312            if (userInfo == null) {
18313                Slog.w(TAG, "No user info for user #" + userId);
18314                return false;
18315            }
18316            if (userInfo.isManagedProfile()) {
18317                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18318                return false;
18319            }
18320            userName = userInfo.name;
18321            mTargetUserId = userId;
18322        }
18323        mHandler.removeMessages(START_USER_SWITCH_MSG);
18324        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18325        return true;
18326    }
18327
18328    private void showUserSwitchDialog(int userId, String userName) {
18329        // The dialog will show and then initiate the user switch by calling startUserInForeground
18330        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18331                true /* above system */);
18332        d.show();
18333    }
18334
18335    private boolean startUser(final int userId, final boolean foreground) {
18336        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18337                != PackageManager.PERMISSION_GRANTED) {
18338            String msg = "Permission Denial: switchUser() from pid="
18339                    + Binder.getCallingPid()
18340                    + ", uid=" + Binder.getCallingUid()
18341                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18342            Slog.w(TAG, msg);
18343            throw new SecurityException(msg);
18344        }
18345
18346        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18347
18348        final long ident = Binder.clearCallingIdentity();
18349        try {
18350            synchronized (this) {
18351                final int oldUserId = mCurrentUserId;
18352                if (oldUserId == userId) {
18353                    return true;
18354                }
18355
18356                mStackSupervisor.setLockTaskModeLocked(null, false);
18357
18358                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18359                if (userInfo == null) {
18360                    Slog.w(TAG, "No user info for user #" + userId);
18361                    return false;
18362                }
18363                if (foreground && userInfo.isManagedProfile()) {
18364                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18365                    return false;
18366                }
18367
18368                if (foreground) {
18369                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18370                            R.anim.screen_user_enter);
18371                }
18372
18373                boolean needStart = false;
18374
18375                // If the user we are switching to is not currently started, then
18376                // we need to start it now.
18377                if (mStartedUsers.get(userId) == null) {
18378                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18379                    updateStartedUserArrayLocked();
18380                    needStart = true;
18381                }
18382
18383                final Integer userIdInt = Integer.valueOf(userId);
18384                mUserLru.remove(userIdInt);
18385                mUserLru.add(userIdInt);
18386
18387                if (foreground) {
18388                    mCurrentUserId = userId;
18389                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18390                    updateCurrentProfileIdsLocked();
18391                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18392                    // Once the internal notion of the active user has switched, we lock the device
18393                    // with the option to show the user switcher on the keyguard.
18394                    mWindowManager.lockNow(null);
18395                } else {
18396                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18397                    updateCurrentProfileIdsLocked();
18398                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18399                    mUserLru.remove(currentUserIdInt);
18400                    mUserLru.add(currentUserIdInt);
18401                }
18402
18403                final UserStartedState uss = mStartedUsers.get(userId);
18404
18405                // Make sure user is in the started state.  If it is currently
18406                // stopping, we need to knock that off.
18407                if (uss.mState == UserStartedState.STATE_STOPPING) {
18408                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18409                    // so we can just fairly silently bring the user back from
18410                    // the almost-dead.
18411                    uss.mState = UserStartedState.STATE_RUNNING;
18412                    updateStartedUserArrayLocked();
18413                    needStart = true;
18414                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18415                    // This means ACTION_SHUTDOWN has been sent, so we will
18416                    // need to treat this as a new boot of the user.
18417                    uss.mState = UserStartedState.STATE_BOOTING;
18418                    updateStartedUserArrayLocked();
18419                    needStart = true;
18420                }
18421
18422                if (uss.mState == UserStartedState.STATE_BOOTING) {
18423                    // Booting up a new user, need to tell system services about it.
18424                    // Note that this is on the same handler as scheduling of broadcasts,
18425                    // which is important because it needs to go first.
18426                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18427                }
18428
18429                if (foreground) {
18430                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18431                            oldUserId));
18432                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18433                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18434                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18435                            oldUserId, userId, uss));
18436                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18437                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18438                }
18439
18440                if (needStart) {
18441                    // Send USER_STARTED broadcast
18442                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18443                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18444                            | Intent.FLAG_RECEIVER_FOREGROUND);
18445                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18446                    broadcastIntentLocked(null, null, intent,
18447                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18448                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18449                }
18450
18451                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18452                    if (userId != UserHandle.USER_OWNER) {
18453                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18454                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18455                        broadcastIntentLocked(null, null, intent, null,
18456                                new IIntentReceiver.Stub() {
18457                                    public void performReceive(Intent intent, int resultCode,
18458                                            String data, Bundle extras, boolean ordered,
18459                                            boolean sticky, int sendingUser) {
18460                                        onUserInitialized(uss, foreground, oldUserId, userId);
18461                                    }
18462                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18463                                true, false, MY_PID, Process.SYSTEM_UID,
18464                                userId);
18465                        uss.initializing = true;
18466                    } else {
18467                        getUserManagerLocked().makeInitialized(userInfo.id);
18468                    }
18469                }
18470
18471                if (foreground) {
18472                    if (!uss.initializing) {
18473                        moveUserToForeground(uss, oldUserId, userId);
18474                    }
18475                } else {
18476                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18477                }
18478
18479                if (needStart) {
18480                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18481                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18482                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18483                    broadcastIntentLocked(null, null, intent,
18484                            null, new IIntentReceiver.Stub() {
18485                                @Override
18486                                public void performReceive(Intent intent, int resultCode, String data,
18487                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18488                                        throws RemoteException {
18489                                }
18490                            }, 0, null, null,
18491                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18492                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18493                }
18494            }
18495        } finally {
18496            Binder.restoreCallingIdentity(ident);
18497        }
18498
18499        return true;
18500    }
18501
18502    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18503        long ident = Binder.clearCallingIdentity();
18504        try {
18505            Intent intent;
18506            if (oldUserId >= 0) {
18507                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18508                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18509                int count = profiles.size();
18510                for (int i = 0; i < count; i++) {
18511                    int profileUserId = profiles.get(i).id;
18512                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18513                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18514                            | Intent.FLAG_RECEIVER_FOREGROUND);
18515                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18516                    broadcastIntentLocked(null, null, intent,
18517                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18518                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18519                }
18520            }
18521            if (newUserId >= 0) {
18522                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18523                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18524                int count = profiles.size();
18525                for (int i = 0; i < count; i++) {
18526                    int profileUserId = profiles.get(i).id;
18527                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18528                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18529                            | Intent.FLAG_RECEIVER_FOREGROUND);
18530                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18531                    broadcastIntentLocked(null, null, intent,
18532                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18533                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18534                }
18535                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18536                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18537                        | Intent.FLAG_RECEIVER_FOREGROUND);
18538                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18539                broadcastIntentLocked(null, null, intent,
18540                        null, null, 0, null, null,
18541                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18542                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18543            }
18544        } finally {
18545            Binder.restoreCallingIdentity(ident);
18546        }
18547    }
18548
18549    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18550            final int newUserId) {
18551        final int N = mUserSwitchObservers.beginBroadcast();
18552        if (N > 0) {
18553            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18554                int mCount = 0;
18555                @Override
18556                public void sendResult(Bundle data) throws RemoteException {
18557                    synchronized (ActivityManagerService.this) {
18558                        if (mCurUserSwitchCallback == this) {
18559                            mCount++;
18560                            if (mCount == N) {
18561                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18562                            }
18563                        }
18564                    }
18565                }
18566            };
18567            synchronized (this) {
18568                uss.switching = true;
18569                mCurUserSwitchCallback = callback;
18570            }
18571            for (int i=0; i<N; i++) {
18572                try {
18573                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18574                            newUserId, callback);
18575                } catch (RemoteException e) {
18576                }
18577            }
18578        } else {
18579            synchronized (this) {
18580                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18581            }
18582        }
18583        mUserSwitchObservers.finishBroadcast();
18584    }
18585
18586    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18587        synchronized (this) {
18588            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18589            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18590        }
18591    }
18592
18593    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18594        mCurUserSwitchCallback = null;
18595        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18596        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18597                oldUserId, newUserId, uss));
18598    }
18599
18600    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18601        synchronized (this) {
18602            if (foreground) {
18603                moveUserToForeground(uss, oldUserId, newUserId);
18604            }
18605        }
18606
18607        completeSwitchAndInitalize(uss, newUserId, true, false);
18608    }
18609
18610    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18611        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18612        if (homeInFront) {
18613            startHomeActivityLocked(newUserId);
18614        } else {
18615            mStackSupervisor.resumeTopActivitiesLocked();
18616        }
18617        EventLogTags.writeAmSwitchUser(newUserId);
18618        getUserManagerLocked().userForeground(newUserId);
18619        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18620    }
18621
18622    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18623        completeSwitchAndInitalize(uss, newUserId, false, true);
18624    }
18625
18626    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18627            boolean clearInitializing, boolean clearSwitching) {
18628        boolean unfrozen = false;
18629        synchronized (this) {
18630            if (clearInitializing) {
18631                uss.initializing = false;
18632                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18633            }
18634            if (clearSwitching) {
18635                uss.switching = false;
18636            }
18637            if (!uss.switching && !uss.initializing) {
18638                mWindowManager.stopFreezingScreen();
18639                unfrozen = true;
18640            }
18641        }
18642        if (unfrozen) {
18643            final int N = mUserSwitchObservers.beginBroadcast();
18644            for (int i=0; i<N; i++) {
18645                try {
18646                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18647                } catch (RemoteException e) {
18648                }
18649            }
18650            mUserSwitchObservers.finishBroadcast();
18651        }
18652    }
18653
18654    void scheduleStartProfilesLocked() {
18655        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18656            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18657                    DateUtils.SECOND_IN_MILLIS);
18658        }
18659    }
18660
18661    void startProfilesLocked() {
18662        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18663        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18664                mCurrentUserId, false /* enabledOnly */);
18665        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18666        for (UserInfo user : profiles) {
18667            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18668                    && user.id != mCurrentUserId) {
18669                toStart.add(user);
18670            }
18671        }
18672        final int n = toStart.size();
18673        int i = 0;
18674        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18675            startUserInBackground(toStart.get(i).id);
18676        }
18677        if (i < n) {
18678            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18679        }
18680    }
18681
18682    void finishUserBoot(UserStartedState uss) {
18683        synchronized (this) {
18684            if (uss.mState == UserStartedState.STATE_BOOTING
18685                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18686                uss.mState = UserStartedState.STATE_RUNNING;
18687                final int userId = uss.mHandle.getIdentifier();
18688                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18689                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18690                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18691                broadcastIntentLocked(null, null, intent,
18692                        null, null, 0, null, null,
18693                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18694                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18695            }
18696        }
18697    }
18698
18699    void finishUserSwitch(UserStartedState uss) {
18700        synchronized (this) {
18701            finishUserBoot(uss);
18702
18703            startProfilesLocked();
18704
18705            int num = mUserLru.size();
18706            int i = 0;
18707            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18708                Integer oldUserId = mUserLru.get(i);
18709                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18710                if (oldUss == null) {
18711                    // Shouldn't happen, but be sane if it does.
18712                    mUserLru.remove(i);
18713                    num--;
18714                    continue;
18715                }
18716                if (oldUss.mState == UserStartedState.STATE_STOPPING
18717                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18718                    // This user is already stopping, doesn't count.
18719                    num--;
18720                    i++;
18721                    continue;
18722                }
18723                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18724                    // Owner and current can't be stopped, but count as running.
18725                    i++;
18726                    continue;
18727                }
18728                // This is a user to be stopped.
18729                stopUserLocked(oldUserId, null);
18730                num--;
18731                i++;
18732            }
18733        }
18734    }
18735
18736    @Override
18737    public int stopUser(final int userId, final IStopUserCallback callback) {
18738        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18739                != PackageManager.PERMISSION_GRANTED) {
18740            String msg = "Permission Denial: switchUser() from pid="
18741                    + Binder.getCallingPid()
18742                    + ", uid=" + Binder.getCallingUid()
18743                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18744            Slog.w(TAG, msg);
18745            throw new SecurityException(msg);
18746        }
18747        if (userId <= 0) {
18748            throw new IllegalArgumentException("Can't stop primary user " + userId);
18749        }
18750        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18751        synchronized (this) {
18752            return stopUserLocked(userId, callback);
18753        }
18754    }
18755
18756    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18757        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18758        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18759            return ActivityManager.USER_OP_IS_CURRENT;
18760        }
18761
18762        final UserStartedState uss = mStartedUsers.get(userId);
18763        if (uss == null) {
18764            // User is not started, nothing to do...  but we do need to
18765            // callback if requested.
18766            if (callback != null) {
18767                mHandler.post(new Runnable() {
18768                    @Override
18769                    public void run() {
18770                        try {
18771                            callback.userStopped(userId);
18772                        } catch (RemoteException e) {
18773                        }
18774                    }
18775                });
18776            }
18777            return ActivityManager.USER_OP_SUCCESS;
18778        }
18779
18780        if (callback != null) {
18781            uss.mStopCallbacks.add(callback);
18782        }
18783
18784        if (uss.mState != UserStartedState.STATE_STOPPING
18785                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18786            uss.mState = UserStartedState.STATE_STOPPING;
18787            updateStartedUserArrayLocked();
18788
18789            long ident = Binder.clearCallingIdentity();
18790            try {
18791                // We are going to broadcast ACTION_USER_STOPPING and then
18792                // once that is done send a final ACTION_SHUTDOWN and then
18793                // stop the user.
18794                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18795                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18796                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18797                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18798                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18799                // This is the result receiver for the final shutdown broadcast.
18800                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18801                    @Override
18802                    public void performReceive(Intent intent, int resultCode, String data,
18803                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18804                        finishUserStop(uss);
18805                    }
18806                };
18807                // This is the result receiver for the initial stopping broadcast.
18808                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18809                    @Override
18810                    public void performReceive(Intent intent, int resultCode, String data,
18811                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18812                        // On to the next.
18813                        synchronized (ActivityManagerService.this) {
18814                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18815                                // Whoops, we are being started back up.  Abort, abort!
18816                                return;
18817                            }
18818                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18819                        }
18820                        mBatteryStatsService.noteEvent(
18821                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18822                                Integer.toString(userId), userId);
18823                        mSystemServiceManager.stopUser(userId);
18824                        broadcastIntentLocked(null, null, shutdownIntent,
18825                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18826                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18827                    }
18828                };
18829                // Kick things off.
18830                broadcastIntentLocked(null, null, stoppingIntent,
18831                        null, stoppingReceiver, 0, null, null,
18832                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18833                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18834            } finally {
18835                Binder.restoreCallingIdentity(ident);
18836            }
18837        }
18838
18839        return ActivityManager.USER_OP_SUCCESS;
18840    }
18841
18842    void finishUserStop(UserStartedState uss) {
18843        final int userId = uss.mHandle.getIdentifier();
18844        boolean stopped;
18845        ArrayList<IStopUserCallback> callbacks;
18846        synchronized (this) {
18847            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18848            if (mStartedUsers.get(userId) != uss) {
18849                stopped = false;
18850            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18851                stopped = false;
18852            } else {
18853                stopped = true;
18854                // User can no longer run.
18855                mStartedUsers.remove(userId);
18856                mUserLru.remove(Integer.valueOf(userId));
18857                updateStartedUserArrayLocked();
18858
18859                // Clean up all state and processes associated with the user.
18860                // Kill all the processes for the user.
18861                forceStopUserLocked(userId, "finish user");
18862            }
18863
18864            // Explicitly remove the old information in mRecentTasks.
18865            removeRecentTasksForUserLocked(userId);
18866        }
18867
18868        for (int i=0; i<callbacks.size(); i++) {
18869            try {
18870                if (stopped) callbacks.get(i).userStopped(userId);
18871                else callbacks.get(i).userStopAborted(userId);
18872            } catch (RemoteException e) {
18873            }
18874        }
18875
18876        if (stopped) {
18877            mSystemServiceManager.cleanupUser(userId);
18878            synchronized (this) {
18879                mStackSupervisor.removeUserLocked(userId);
18880            }
18881        }
18882    }
18883
18884    @Override
18885    public UserInfo getCurrentUser() {
18886        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18887                != PackageManager.PERMISSION_GRANTED) && (
18888                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18889                != PackageManager.PERMISSION_GRANTED)) {
18890            String msg = "Permission Denial: getCurrentUser() from pid="
18891                    + Binder.getCallingPid()
18892                    + ", uid=" + Binder.getCallingUid()
18893                    + " requires " + INTERACT_ACROSS_USERS;
18894            Slog.w(TAG, msg);
18895            throw new SecurityException(msg);
18896        }
18897        synchronized (this) {
18898            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18899            return getUserManagerLocked().getUserInfo(userId);
18900        }
18901    }
18902
18903    int getCurrentUserIdLocked() {
18904        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18905    }
18906
18907    @Override
18908    public boolean isUserRunning(int userId, boolean orStopped) {
18909        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18910                != PackageManager.PERMISSION_GRANTED) {
18911            String msg = "Permission Denial: isUserRunning() from pid="
18912                    + Binder.getCallingPid()
18913                    + ", uid=" + Binder.getCallingUid()
18914                    + " requires " + INTERACT_ACROSS_USERS;
18915            Slog.w(TAG, msg);
18916            throw new SecurityException(msg);
18917        }
18918        synchronized (this) {
18919            return isUserRunningLocked(userId, orStopped);
18920        }
18921    }
18922
18923    boolean isUserRunningLocked(int userId, boolean orStopped) {
18924        UserStartedState state = mStartedUsers.get(userId);
18925        if (state == null) {
18926            return false;
18927        }
18928        if (orStopped) {
18929            return true;
18930        }
18931        return state.mState != UserStartedState.STATE_STOPPING
18932                && state.mState != UserStartedState.STATE_SHUTDOWN;
18933    }
18934
18935    @Override
18936    public int[] getRunningUserIds() {
18937        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18938                != PackageManager.PERMISSION_GRANTED) {
18939            String msg = "Permission Denial: isUserRunning() from pid="
18940                    + Binder.getCallingPid()
18941                    + ", uid=" + Binder.getCallingUid()
18942                    + " requires " + INTERACT_ACROSS_USERS;
18943            Slog.w(TAG, msg);
18944            throw new SecurityException(msg);
18945        }
18946        synchronized (this) {
18947            return mStartedUserArray;
18948        }
18949    }
18950
18951    private void updateStartedUserArrayLocked() {
18952        int num = 0;
18953        for (int i=0; i<mStartedUsers.size();  i++) {
18954            UserStartedState uss = mStartedUsers.valueAt(i);
18955            // This list does not include stopping users.
18956            if (uss.mState != UserStartedState.STATE_STOPPING
18957                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18958                num++;
18959            }
18960        }
18961        mStartedUserArray = new int[num];
18962        num = 0;
18963        for (int i=0; i<mStartedUsers.size();  i++) {
18964            UserStartedState uss = mStartedUsers.valueAt(i);
18965            if (uss.mState != UserStartedState.STATE_STOPPING
18966                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18967                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18968                num++;
18969            }
18970        }
18971    }
18972
18973    @Override
18974    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18975        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18976                != PackageManager.PERMISSION_GRANTED) {
18977            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18978                    + Binder.getCallingPid()
18979                    + ", uid=" + Binder.getCallingUid()
18980                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18981            Slog.w(TAG, msg);
18982            throw new SecurityException(msg);
18983        }
18984
18985        mUserSwitchObservers.register(observer);
18986    }
18987
18988    @Override
18989    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18990        mUserSwitchObservers.unregister(observer);
18991    }
18992
18993    private boolean userExists(int userId) {
18994        if (userId == 0) {
18995            return true;
18996        }
18997        UserManagerService ums = getUserManagerLocked();
18998        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18999    }
19000
19001    int[] getUsersLocked() {
19002        UserManagerService ums = getUserManagerLocked();
19003        return ums != null ? ums.getUserIds() : new int[] { 0 };
19004    }
19005
19006    UserManagerService getUserManagerLocked() {
19007        if (mUserManager == null) {
19008            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19009            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19010        }
19011        return mUserManager;
19012    }
19013
19014    private int applyUserId(int uid, int userId) {
19015        return UserHandle.getUid(userId, uid);
19016    }
19017
19018    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19019        if (info == null) return null;
19020        ApplicationInfo newInfo = new ApplicationInfo(info);
19021        newInfo.uid = applyUserId(info.uid, userId);
19022        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19023                + info.packageName;
19024        return newInfo;
19025    }
19026
19027    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19028        if (aInfo == null
19029                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19030            return aInfo;
19031        }
19032
19033        ActivityInfo info = new ActivityInfo(aInfo);
19034        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19035        return info;
19036    }
19037
19038    private final class LocalService extends ActivityManagerInternal {
19039        @Override
19040        public void goingToSleep() {
19041            ActivityManagerService.this.goingToSleep();
19042        }
19043
19044        @Override
19045        public void wakingUp() {
19046            ActivityManagerService.this.wakingUp();
19047        }
19048
19049        @Override
19050        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19051                String processName, String abiOverride, int uid, Runnable crashHandler) {
19052            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19053                    processName, abiOverride, uid, crashHandler);
19054        }
19055    }
19056
19057    /**
19058     * An implementation of IAppTask, that allows an app to manage its own tasks via
19059     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19060     * only the process that calls getAppTasks() can call the AppTask methods.
19061     */
19062    class AppTaskImpl extends IAppTask.Stub {
19063        private int mTaskId;
19064        private int mCallingUid;
19065
19066        public AppTaskImpl(int taskId, int callingUid) {
19067            mTaskId = taskId;
19068            mCallingUid = callingUid;
19069        }
19070
19071        private void checkCaller() {
19072            if (mCallingUid != Binder.getCallingUid()) {
19073                throw new SecurityException("Caller " + mCallingUid
19074                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19075            }
19076        }
19077
19078        @Override
19079        public void finishAndRemoveTask() {
19080            checkCaller();
19081
19082            synchronized (ActivityManagerService.this) {
19083                long origId = Binder.clearCallingIdentity();
19084                try {
19085                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19086                    if (tr == null) {
19087                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19088                    }
19089                    // Only kill the process if we are not a new document
19090                    int flags = tr.getBaseIntent().getFlags();
19091                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
19092                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
19093                    removeTaskByIdLocked(mTaskId,
19094                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
19095                } finally {
19096                    Binder.restoreCallingIdentity(origId);
19097                }
19098            }
19099        }
19100
19101        @Override
19102        public ActivityManager.RecentTaskInfo getTaskInfo() {
19103            checkCaller();
19104
19105            synchronized (ActivityManagerService.this) {
19106                long origId = Binder.clearCallingIdentity();
19107                try {
19108                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19109                    if (tr == null) {
19110                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19111                    }
19112                    return createRecentTaskInfoFromTaskRecord(tr);
19113                } finally {
19114                    Binder.restoreCallingIdentity(origId);
19115                }
19116            }
19117        }
19118
19119        @Override
19120        public void moveToFront() {
19121            checkCaller();
19122
19123            final TaskRecord tr;
19124            synchronized (ActivityManagerService.this) {
19125                tr = recentTaskForIdLocked(mTaskId);
19126                if (tr == null) {
19127                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19128                }
19129                if (tr.getRootActivity() != null) {
19130                    moveTaskToFrontLocked(tr.taskId, 0, null);
19131                    return;
19132                }
19133            }
19134
19135            startActivityFromRecentsInner(tr.taskId, null);
19136        }
19137
19138        @Override
19139        public int startActivity(IBinder whoThread, String callingPackage,
19140                Intent intent, String resolvedType, Bundle options) {
19141            checkCaller();
19142
19143            int callingUser = UserHandle.getCallingUserId();
19144            TaskRecord tr;
19145            IApplicationThread appThread;
19146            synchronized (ActivityManagerService.this) {
19147                tr = recentTaskForIdLocked(mTaskId);
19148                if (tr == null) {
19149                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19150                }
19151                appThread = ApplicationThreadNative.asInterface(whoThread);
19152                if (appThread == null) {
19153                    throw new IllegalArgumentException("Bad app thread " + appThread);
19154                }
19155            }
19156            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19157                    resolvedType, null, null, null, null, 0, 0, null, null,
19158                    null, options, callingUser, null, tr);
19159        }
19160
19161        @Override
19162        public void setExcludeFromRecents(boolean exclude) {
19163            checkCaller();
19164
19165            synchronized (ActivityManagerService.this) {
19166                long origId = Binder.clearCallingIdentity();
19167                try {
19168                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19169                    if (tr == null) {
19170                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19171                    }
19172                    Intent intent = tr.getBaseIntent();
19173                    if (exclude) {
19174                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19175                    } else {
19176                        intent.setFlags(intent.getFlags()
19177                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19178                    }
19179                } finally {
19180                    Binder.restoreCallingIdentity(origId);
19181                }
19182            }
19183        }
19184    }
19185}
19186