ActivityManagerService.java revision 192679a7d37d268854f4b17876c702625f9475eb
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33
34import android.Manifest;
35import android.app.AppOpsManager;
36import android.app.ApplicationThreadNative;
37import android.app.IActivityContainer;
38import android.app.IActivityContainerCallback;
39import android.app.IAppTask;
40import android.app.ProfilerInfo;
41import android.app.admin.DevicePolicyManager;
42import android.app.usage.UsageEvents;
43import android.app.usage.UsageStatsManagerInternal;
44import android.appwidget.AppWidgetManager;
45import android.content.res.Resources;
46import android.graphics.Bitmap;
47import android.graphics.Point;
48import android.graphics.Rect;
49import android.os.BatteryStats;
50import android.os.PersistableBundle;
51import android.service.voice.IVoiceInteractionSession;
52import android.util.ArrayMap;
53import android.util.ArraySet;
54import android.util.SparseIntArray;
55
56import com.android.internal.R;
57import com.android.internal.annotations.GuardedBy;
58import com.android.internal.app.IAppOpsService;
59import com.android.internal.app.IVoiceInteractor;
60import com.android.internal.app.ProcessMap;
61import com.android.internal.app.ProcessStats;
62import com.android.internal.content.PackageMonitor;
63import com.android.internal.os.BackgroundThread;
64import com.android.internal.os.BatteryStatsImpl;
65import com.android.internal.os.ProcessCpuTracker;
66import com.android.internal.os.TransferPipe;
67import com.android.internal.os.Zygote;
68import com.android.internal.util.FastPrintWriter;
69import com.android.internal.util.FastXmlSerializer;
70import com.android.internal.util.MemInfoReader;
71import com.android.internal.util.Preconditions;
72import com.android.server.AppOpsService;
73import com.android.server.AttributeCache;
74import com.android.server.IntentResolver;
75import com.android.server.LocalServices;
76import com.android.server.ServiceThread;
77import com.android.server.SystemService;
78import com.android.server.SystemServiceManager;
79import com.android.server.Watchdog;
80import com.android.server.am.ActivityStack.ActivityState;
81import com.android.server.firewall.IntentFirewall;
82import com.android.server.pm.UserManagerService;
83import com.android.server.wm.AppTransition;
84import com.android.server.wm.WindowManagerService;
85import com.google.android.collect.Lists;
86import com.google.android.collect.Maps;
87
88import libcore.io.IoUtils;
89
90import org.xmlpull.v1.XmlPullParser;
91import org.xmlpull.v1.XmlPullParserException;
92import org.xmlpull.v1.XmlSerializer;
93
94import android.app.Activity;
95import android.app.ActivityManager;
96import android.app.ActivityManager.RunningTaskInfo;
97import android.app.ActivityManager.StackInfo;
98import android.app.ActivityManagerInternal;
99import android.app.ActivityManagerNative;
100import android.app.ActivityOptions;
101import android.app.ActivityThread;
102import android.app.AlertDialog;
103import android.app.AppGlobals;
104import android.app.ApplicationErrorReport;
105import android.app.Dialog;
106import android.app.IActivityController;
107import android.app.IApplicationThread;
108import android.app.IInstrumentationWatcher;
109import android.app.INotificationManager;
110import android.app.IProcessObserver;
111import android.app.IServiceConnection;
112import android.app.IStopUserCallback;
113import android.app.IUiAutomationConnection;
114import android.app.IUserSwitchObserver;
115import android.app.Instrumentation;
116import android.app.Notification;
117import android.app.NotificationManager;
118import android.app.PendingIntent;
119import android.app.backup.IBackupManager;
120import android.content.ActivityNotFoundException;
121import android.content.BroadcastReceiver;
122import android.content.ClipData;
123import android.content.ComponentCallbacks2;
124import android.content.ComponentName;
125import android.content.ContentProvider;
126import android.content.ContentResolver;
127import android.content.Context;
128import android.content.DialogInterface;
129import android.content.IContentProvider;
130import android.content.IIntentReceiver;
131import android.content.IIntentSender;
132import android.content.Intent;
133import android.content.IntentFilter;
134import android.content.IntentSender;
135import android.content.pm.ActivityInfo;
136import android.content.pm.ApplicationInfo;
137import android.content.pm.ConfigurationInfo;
138import android.content.pm.IPackageDataObserver;
139import android.content.pm.IPackageManager;
140import android.content.pm.InstrumentationInfo;
141import android.content.pm.PackageInfo;
142import android.content.pm.PackageManager;
143import android.content.pm.ParceledListSlice;
144import android.content.pm.UserInfo;
145import android.content.pm.PackageManager.NameNotFoundException;
146import android.content.pm.PathPermission;
147import android.content.pm.ProviderInfo;
148import android.content.pm.ResolveInfo;
149import android.content.pm.ServiceInfo;
150import android.content.res.CompatibilityInfo;
151import android.content.res.Configuration;
152import android.net.Proxy;
153import android.net.ProxyInfo;
154import android.net.Uri;
155import android.os.Binder;
156import android.os.Build;
157import android.os.Bundle;
158import android.os.Debug;
159import android.os.DropBoxManager;
160import android.os.Environment;
161import android.os.FactoryTest;
162import android.os.FileObserver;
163import android.os.FileUtils;
164import android.os.Handler;
165import android.os.IBinder;
166import android.os.IPermissionController;
167import android.os.IRemoteCallback;
168import android.os.IUserManager;
169import android.os.Looper;
170import android.os.Message;
171import android.os.Parcel;
172import android.os.ParcelFileDescriptor;
173import android.os.Process;
174import android.os.RemoteCallbackList;
175import android.os.RemoteException;
176import android.os.SELinux;
177import android.os.ServiceManager;
178import android.os.StrictMode;
179import android.os.SystemClock;
180import android.os.SystemProperties;
181import android.os.UpdateLock;
182import android.os.UserHandle;
183import android.provider.Settings;
184import android.text.format.DateUtils;
185import android.text.format.Time;
186import android.util.AtomicFile;
187import android.util.EventLog;
188import android.util.Log;
189import android.util.Pair;
190import android.util.PrintWriterPrinter;
191import android.util.Slog;
192import android.util.SparseArray;
193import android.util.TimeUtils;
194import android.util.Xml;
195import android.view.Gravity;
196import android.view.LayoutInflater;
197import android.view.View;
198import android.view.WindowManager;
199import dalvik.system.VMRuntime;
200
201import java.io.BufferedInputStream;
202import java.io.BufferedOutputStream;
203import java.io.DataInputStream;
204import java.io.DataOutputStream;
205import java.io.File;
206import java.io.FileDescriptor;
207import java.io.FileInputStream;
208import java.io.FileNotFoundException;
209import java.io.FileOutputStream;
210import java.io.IOException;
211import java.io.InputStreamReader;
212import java.io.PrintWriter;
213import java.io.StringWriter;
214import java.lang.ref.WeakReference;
215import java.util.ArrayList;
216import java.util.Arrays;
217import java.util.Collections;
218import java.util.Comparator;
219import java.util.HashMap;
220import java.util.HashSet;
221import java.util.Iterator;
222import java.util.List;
223import java.util.Locale;
224import java.util.Map;
225import java.util.Set;
226import java.util.concurrent.atomic.AtomicBoolean;
227import java.util.concurrent.atomic.AtomicLong;
228
229public final class ActivityManagerService extends ActivityManagerNative
230        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
231
232    private static final String USER_DATA_DIR = "/data/user/";
233    // File that stores last updated system version and called preboot receivers
234    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
235
236    static final String TAG = "ActivityManager";
237    static final String TAG_MU = "ActivityManagerServiceMU";
238    static final boolean DEBUG = false;
239    static final boolean localLOGV = DEBUG;
240    static final boolean DEBUG_BACKUP = localLOGV || false;
241    static final boolean DEBUG_BROADCAST = localLOGV || false;
242    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
243    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
244    static final boolean DEBUG_CLEANUP = localLOGV || false;
245    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
246    static final boolean DEBUG_FOCUS = false;
247    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
248    static final boolean DEBUG_MU = localLOGV || false;
249    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
250    static final boolean DEBUG_LRU = localLOGV || false;
251    static final boolean DEBUG_PAUSE = localLOGV || false;
252    static final boolean DEBUG_POWER = localLOGV || false;
253    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
254    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
255    static final boolean DEBUG_PROCESSES = localLOGV || false;
256    static final boolean DEBUG_PROVIDER = localLOGV || false;
257    static final boolean DEBUG_RESULTS = localLOGV || false;
258    static final boolean DEBUG_SERVICE = localLOGV || false;
259    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
260    static final boolean DEBUG_STACK = localLOGV || false;
261    static final boolean DEBUG_SWITCH = localLOGV || false;
262    static final boolean DEBUG_TASKS = localLOGV || false;
263    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
264    static final boolean DEBUG_TRANSITION = localLOGV || false;
265    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
266    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
267    static final boolean DEBUG_VISBILITY = localLOGV || false;
268    static final boolean DEBUG_PSS = localLOGV || false;
269    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
270    static final boolean DEBUG_RECENTS = localLOGV || false;
271    static final boolean VALIDATE_TOKENS = false;
272    static final boolean SHOW_ACTIVITY_START_TIME = true;
273
274    // Control over CPU and battery monitoring.
275    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
276    static final boolean MONITOR_CPU_USAGE = true;
277    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
278    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
279    static final boolean MONITOR_THREAD_CPU_USAGE = false;
280
281    // The flags that are set for all calls we make to the package manager.
282    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
283
284    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
285
286    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
287
288    // Maximum number recent bitmaps to keep in memory.
289    static final int MAX_RECENT_BITMAPS = 5;
290
291    // Amount of time after a call to stopAppSwitches() during which we will
292    // prevent further untrusted switches from happening.
293    static final long APP_SWITCH_DELAY_TIME = 5*1000;
294
295    // How long we wait for a launched process to attach to the activity manager
296    // before we decide it's never going to come up for real.
297    static final int PROC_START_TIMEOUT = 10*1000;
298
299    // How long we wait for a launched process to attach to the activity manager
300    // before we decide it's never going to come up for real, when the process was
301    // started with a wrapper for instrumentation (such as Valgrind) because it
302    // could take much longer than usual.
303    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
304
305    // How long to wait after going idle before forcing apps to GC.
306    static final int GC_TIMEOUT = 5*1000;
307
308    // The minimum amount of time between successive GC requests for a process.
309    static final int GC_MIN_INTERVAL = 60*1000;
310
311    // The minimum amount of time between successive PSS requests for a process.
312    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
313
314    // The minimum amount of time between successive PSS requests for a process
315    // when the request is due to the memory state being lowered.
316    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
317
318    // The rate at which we check for apps using excessive power -- 15 mins.
319    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
320
321    // The minimum sample duration we will allow before deciding we have
322    // enough data on wake locks to start killing things.
323    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
324
325    // The minimum sample duration we will allow before deciding we have
326    // enough data on CPU usage to start killing things.
327    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
328
329    // How long we allow a receiver to run before giving up on it.
330    static final int BROADCAST_FG_TIMEOUT = 10*1000;
331    static final int BROADCAST_BG_TIMEOUT = 60*1000;
332
333    // How long we wait until we timeout on key dispatching.
334    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
335
336    // How long we wait until we timeout on key dispatching during instrumentation.
337    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
338
339    // Amount of time we wait for observers to handle a user switch before
340    // giving up on them and unfreezing the screen.
341    static final int USER_SWITCH_TIMEOUT = 2*1000;
342
343    // Maximum number of users we allow to be running at a time.
344    static final int MAX_RUNNING_USERS = 3;
345
346    // How long to wait in getAssistContextExtras for the activity and foreground services
347    // to respond with the result.
348    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
349
350    // Maximum number of persisted Uri grants a package is allowed
351    static final int MAX_PERSISTED_URI_GRANTS = 128;
352
353    static final int MY_PID = Process.myPid();
354
355    static final String[] EMPTY_STRING_ARRAY = new String[0];
356
357    // How many bytes to write into the dropbox log before truncating
358    static final int DROPBOX_MAX_SIZE = 256 * 1024;
359
360    // Access modes for handleIncomingUser.
361    static final int ALLOW_NON_FULL = 0;
362    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
363    static final int ALLOW_FULL_ONLY = 2;
364
365    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
366
367    /** All system services */
368    SystemServiceManager mSystemServiceManager;
369
370    /** Run all ActivityStacks through this */
371    ActivityStackSupervisor mStackSupervisor;
372
373    public IntentFirewall mIntentFirewall;
374
375    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
376    // default actuion automatically.  Important for devices without direct input
377    // devices.
378    private boolean mShowDialogs = true;
379
380    BroadcastQueue mFgBroadcastQueue;
381    BroadcastQueue mBgBroadcastQueue;
382    // Convenient for easy iteration over the queues. Foreground is first
383    // so that dispatch of foreground broadcasts gets precedence.
384    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
385
386    BroadcastQueue broadcastQueueForIntent(Intent intent) {
387        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
388        if (DEBUG_BACKGROUND_BROADCAST) {
389            Slog.i(TAG, "Broadcast intent " + intent + " on "
390                    + (isFg ? "foreground" : "background")
391                    + " queue");
392        }
393        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
394    }
395
396    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
397        for (BroadcastQueue queue : mBroadcastQueues) {
398            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
399            if (r != null) {
400                return r;
401            }
402        }
403        return null;
404    }
405
406    /**
407     * Activity we have told the window manager to have key focus.
408     */
409    ActivityRecord mFocusedActivity = null;
410
411    /**
412     * List of intents that were used to start the most recent tasks.
413     */
414    ArrayList<TaskRecord> mRecentTasks;
415    ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>();
416
417    /**
418     * For addAppTask: cached of the last activity component that was added.
419     */
420    ComponentName mLastAddedTaskComponent;
421
422    /**
423     * For addAppTask: cached of the last activity uid that was added.
424     */
425    int mLastAddedTaskUid;
426
427    /**
428     * For addAppTask: cached of the last ActivityInfo that was added.
429     */
430    ActivityInfo mLastAddedTaskActivity;
431
432    public class PendingAssistExtras extends Binder implements Runnable {
433        public final ActivityRecord activity;
434        public boolean haveResult = false;
435        public Bundle result = null;
436        public PendingAssistExtras(ActivityRecord _activity) {
437            activity = _activity;
438        }
439        @Override
440        public void run() {
441            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
442            synchronized (this) {
443                haveResult = true;
444                notifyAll();
445            }
446        }
447    }
448
449    final ArrayList<PendingAssistExtras> mPendingAssistExtras
450            = new ArrayList<PendingAssistExtras>();
451
452    /**
453     * Process management.
454     */
455    final ProcessList mProcessList = new ProcessList();
456
457    /**
458     * All of the applications we currently have running organized by name.
459     * The keys are strings of the application package name (as
460     * returned by the package manager), and the keys are ApplicationRecord
461     * objects.
462     */
463    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
464
465    /**
466     * Tracking long-term execution of processes to look for abuse and other
467     * bad app behavior.
468     */
469    final ProcessStatsService mProcessStats;
470
471    /**
472     * The currently running isolated processes.
473     */
474    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
475
476    /**
477     * Counter for assigning isolated process uids, to avoid frequently reusing the
478     * same ones.
479     */
480    int mNextIsolatedProcessUid = 0;
481
482    /**
483     * The currently running heavy-weight process, if any.
484     */
485    ProcessRecord mHeavyWeightProcess = null;
486
487    /**
488     * The last time that various processes have crashed.
489     */
490    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
491
492    /**
493     * Information about a process that is currently marked as bad.
494     */
495    static final class BadProcessInfo {
496        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
497            this.time = time;
498            this.shortMsg = shortMsg;
499            this.longMsg = longMsg;
500            this.stack = stack;
501        }
502
503        final long time;
504        final String shortMsg;
505        final String longMsg;
506        final String stack;
507    }
508
509    /**
510     * Set of applications that we consider to be bad, and will reject
511     * incoming broadcasts from (which the user has no control over).
512     * Processes are added to this set when they have crashed twice within
513     * a minimum amount of time; they are removed from it when they are
514     * later restarted (hopefully due to some user action).  The value is the
515     * time it was added to the list.
516     */
517    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
518
519    /**
520     * All of the processes we currently have running organized by pid.
521     * The keys are the pid running the application.
522     *
523     * <p>NOTE: This object is protected by its own lock, NOT the global
524     * activity manager lock!
525     */
526    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
527
528    /**
529     * All of the processes that have been forced to be foreground.  The key
530     * is the pid of the caller who requested it (we hold a death
531     * link on it).
532     */
533    abstract class ForegroundToken implements IBinder.DeathRecipient {
534        int pid;
535        IBinder token;
536    }
537    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
538
539    /**
540     * List of records for processes that someone had tried to start before the
541     * system was ready.  We don't start them at that point, but ensure they
542     * are started by the time booting is complete.
543     */
544    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
545
546    /**
547     * List of persistent applications that are in the process
548     * of being started.
549     */
550    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
551
552    /**
553     * Processes that are being forcibly torn down.
554     */
555    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
556
557    /**
558     * List of running applications, sorted by recent usage.
559     * The first entry in the list is the least recently used.
560     */
561    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
562
563    /**
564     * Where in mLruProcesses that the processes hosting activities start.
565     */
566    int mLruProcessActivityStart = 0;
567
568    /**
569     * Where in mLruProcesses that the processes hosting services start.
570     * This is after (lower index) than mLruProcessesActivityStart.
571     */
572    int mLruProcessServiceStart = 0;
573
574    /**
575     * List of processes that should gc as soon as things are idle.
576     */
577    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
578
579    /**
580     * Processes we want to collect PSS data from.
581     */
582    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
583
584    /**
585     * Last time we requested PSS data of all processes.
586     */
587    long mLastFullPssTime = SystemClock.uptimeMillis();
588
589    /**
590     * If set, the next time we collect PSS data we should do a full collection
591     * with data from native processes and the kernel.
592     */
593    boolean mFullPssPending = false;
594
595    /**
596     * This is the process holding what we currently consider to be
597     * the "home" activity.
598     */
599    ProcessRecord mHomeProcess;
600
601    /**
602     * This is the process holding the activity the user last visited that
603     * is in a different process from the one they are currently in.
604     */
605    ProcessRecord mPreviousProcess;
606
607    /**
608     * The time at which the previous process was last visible.
609     */
610    long mPreviousProcessVisibleTime;
611
612    /**
613     * Which uses have been started, so are allowed to run code.
614     */
615    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
616
617    /**
618     * LRU list of history of current users.  Most recently current is at the end.
619     */
620    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
621
622    /**
623     * Constant array of the users that are currently started.
624     */
625    int[] mStartedUserArray = new int[] { 0 };
626
627    /**
628     * Registered observers of the user switching mechanics.
629     */
630    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
631            = new RemoteCallbackList<IUserSwitchObserver>();
632
633    /**
634     * Currently active user switch.
635     */
636    Object mCurUserSwitchCallback;
637
638    /**
639     * Packages that the user has asked to have run in screen size
640     * compatibility mode instead of filling the screen.
641     */
642    final CompatModePackages mCompatModePackages;
643
644    /**
645     * Set of IntentSenderRecord objects that are currently active.
646     */
647    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
648            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
649
650    /**
651     * Fingerprints (hashCode()) of stack traces that we've
652     * already logged DropBox entries for.  Guarded by itself.  If
653     * something (rogue user app) forces this over
654     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
655     */
656    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
657    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
658
659    /**
660     * Strict Mode background batched logging state.
661     *
662     * The string buffer is guarded by itself, and its lock is also
663     * used to determine if another batched write is already
664     * in-flight.
665     */
666    private final StringBuilder mStrictModeBuffer = new StringBuilder();
667
668    /**
669     * Keeps track of all IIntentReceivers that have been registered for
670     * broadcasts.  Hash keys are the receiver IBinder, hash value is
671     * a ReceiverList.
672     */
673    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
674            new HashMap<IBinder, ReceiverList>();
675
676    /**
677     * Resolver for broadcast intents to registered receivers.
678     * Holds BroadcastFilter (subclass of IntentFilter).
679     */
680    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
681            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
682        @Override
683        protected boolean allowFilterResult(
684                BroadcastFilter filter, List<BroadcastFilter> dest) {
685            IBinder target = filter.receiverList.receiver.asBinder();
686            for (int i=dest.size()-1; i>=0; i--) {
687                if (dest.get(i).receiverList.receiver.asBinder() == target) {
688                    return false;
689                }
690            }
691            return true;
692        }
693
694        @Override
695        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
696            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
697                    || userId == filter.owningUserId) {
698                return super.newResult(filter, match, userId);
699            }
700            return null;
701        }
702
703        @Override
704        protected BroadcastFilter[] newArray(int size) {
705            return new BroadcastFilter[size];
706        }
707
708        @Override
709        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
710            return packageName.equals(filter.packageName);
711        }
712    };
713
714    /**
715     * State of all active sticky broadcasts per user.  Keys are the action of the
716     * sticky Intent, values are an ArrayList of all broadcasted intents with
717     * that action (which should usually be one).  The SparseArray is keyed
718     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
719     * for stickies that are sent to all users.
720     */
721    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
722            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
723
724    final ActiveServices mServices;
725
726    /**
727     * Backup/restore process management
728     */
729    String mBackupAppName = null;
730    BackupRecord mBackupTarget = null;
731
732    final ProviderMap mProviderMap;
733
734    /**
735     * List of content providers who have clients waiting for them.  The
736     * application is currently being launched and the provider will be
737     * removed from this list once it is published.
738     */
739    final ArrayList<ContentProviderRecord> mLaunchingProviders
740            = new ArrayList<ContentProviderRecord>();
741
742    /**
743     * File storing persisted {@link #mGrantedUriPermissions}.
744     */
745    private final AtomicFile mGrantFile;
746
747    /** XML constants used in {@link #mGrantFile} */
748    private static final String TAG_URI_GRANTS = "uri-grants";
749    private static final String TAG_URI_GRANT = "uri-grant";
750    private static final String ATTR_USER_HANDLE = "userHandle";
751    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
752    private static final String ATTR_TARGET_USER_ID = "targetUserId";
753    private static final String ATTR_SOURCE_PKG = "sourcePkg";
754    private static final String ATTR_TARGET_PKG = "targetPkg";
755    private static final String ATTR_URI = "uri";
756    private static final String ATTR_MODE_FLAGS = "modeFlags";
757    private static final String ATTR_CREATED_TIME = "createdTime";
758    private static final String ATTR_PREFIX = "prefix";
759
760    /**
761     * Global set of specific {@link Uri} permissions that have been granted.
762     * This optimized lookup structure maps from {@link UriPermission#targetUid}
763     * to {@link UriPermission#uri} to {@link UriPermission}.
764     */
765    @GuardedBy("this")
766    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
767            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
768
769    public static class GrantUri {
770        public final int sourceUserId;
771        public final Uri uri;
772        public boolean prefix;
773
774        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
775            this.sourceUserId = sourceUserId;
776            this.uri = uri;
777            this.prefix = prefix;
778        }
779
780        @Override
781        public int hashCode() {
782            return toString().hashCode();
783        }
784
785        @Override
786        public boolean equals(Object o) {
787            if (o instanceof GrantUri) {
788                GrantUri other = (GrantUri) o;
789                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
790                        && prefix == other.prefix;
791            }
792            return false;
793        }
794
795        @Override
796        public String toString() {
797            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
798            if (prefix) result += " [prefix]";
799            return result;
800        }
801
802        public String toSafeString() {
803            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
804            if (prefix) result += " [prefix]";
805            return result;
806        }
807
808        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
809            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
810                    ContentProvider.getUriWithoutUserId(uri), false);
811        }
812    }
813
814    CoreSettingsObserver mCoreSettingsObserver;
815
816    /**
817     * Thread-local storage used to carry caller permissions over through
818     * indirect content-provider access.
819     */
820    private class Identity {
821        public int pid;
822        public int uid;
823
824        Identity(int _pid, int _uid) {
825            pid = _pid;
826            uid = _uid;
827        }
828    }
829
830    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
831
832    /**
833     * All information we have collected about the runtime performance of
834     * any user id that can impact battery performance.
835     */
836    final BatteryStatsService mBatteryStatsService;
837
838    /**
839     * Information about component usage
840     */
841    UsageStatsManagerInternal mUsageStatsService;
842
843    /**
844     * Information about and control over application operations
845     */
846    final AppOpsService mAppOpsService;
847
848    /**
849     * Save recent tasks information across reboots.
850     */
851    final TaskPersister mTaskPersister;
852
853    /**
854     * Current configuration information.  HistoryRecord objects are given
855     * a reference to this object to indicate which configuration they are
856     * currently running in, so this object must be kept immutable.
857     */
858    Configuration mConfiguration = new Configuration();
859
860    /**
861     * Current sequencing integer of the configuration, for skipping old
862     * configurations.
863     */
864    int mConfigurationSeq = 0;
865
866    /**
867     * Hardware-reported OpenGLES version.
868     */
869    final int GL_ES_VERSION;
870
871    /**
872     * List of initialization arguments to pass to all processes when binding applications to them.
873     * For example, references to the commonly used services.
874     */
875    HashMap<String, IBinder> mAppBindArgs;
876
877    /**
878     * Temporary to avoid allocations.  Protected by main lock.
879     */
880    final StringBuilder mStringBuilder = new StringBuilder(256);
881
882    /**
883     * Used to control how we initialize the service.
884     */
885    ComponentName mTopComponent;
886    String mTopAction = Intent.ACTION_MAIN;
887    String mTopData;
888    boolean mProcessesReady = false;
889    boolean mSystemReady = false;
890    boolean mBooting = false;
891    boolean mWaitingUpdate = false;
892    boolean mDidUpdate = false;
893    boolean mOnBattery = false;
894    boolean mLaunchWarningShown = false;
895
896    Context mContext;
897
898    int mFactoryTest;
899
900    boolean mCheckedForSetup;
901
902    /**
903     * The time at which we will allow normal application switches again,
904     * after a call to {@link #stopAppSwitches()}.
905     */
906    long mAppSwitchesAllowedTime;
907
908    /**
909     * This is set to true after the first switch after mAppSwitchesAllowedTime
910     * is set; any switches after that will clear the time.
911     */
912    boolean mDidAppSwitch;
913
914    /**
915     * Last time (in realtime) at which we checked for power usage.
916     */
917    long mLastPowerCheckRealtime;
918
919    /**
920     * Last time (in uptime) at which we checked for power usage.
921     */
922    long mLastPowerCheckUptime;
923
924    /**
925     * Set while we are wanting to sleep, to prevent any
926     * activities from being started/resumed.
927     */
928    private boolean mSleeping = false;
929
930    /**
931     * Set while we are running a voice interaction.  This overrides
932     * sleeping while it is active.
933     */
934    private boolean mRunningVoice = false;
935
936    /**
937     * State of external calls telling us if the device is asleep.
938     */
939    private boolean mWentToSleep = false;
940
941    /**
942     * State of external call telling us if the lock screen is shown.
943     */
944    private boolean mLockScreenShown = false;
945
946    /**
947     * Set if we are shutting down the system, similar to sleeping.
948     */
949    boolean mShuttingDown = false;
950
951    /**
952     * Current sequence id for oom_adj computation traversal.
953     */
954    int mAdjSeq = 0;
955
956    /**
957     * Current sequence id for process LRU updating.
958     */
959    int mLruSeq = 0;
960
961    /**
962     * Keep track of the non-cached/empty process we last found, to help
963     * determine how to distribute cached/empty processes next time.
964     */
965    int mNumNonCachedProcs = 0;
966
967    /**
968     * Keep track of the number of cached hidden procs, to balance oom adj
969     * distribution between those and empty procs.
970     */
971    int mNumCachedHiddenProcs = 0;
972
973    /**
974     * Keep track of the number of service processes we last found, to
975     * determine on the next iteration which should be B services.
976     */
977    int mNumServiceProcs = 0;
978    int mNewNumAServiceProcs = 0;
979    int mNewNumServiceProcs = 0;
980
981    /**
982     * Allow the current computed overall memory level of the system to go down?
983     * This is set to false when we are killing processes for reasons other than
984     * memory management, so that the now smaller process list will not be taken as
985     * an indication that memory is tighter.
986     */
987    boolean mAllowLowerMemLevel = false;
988
989    /**
990     * The last computed memory level, for holding when we are in a state that
991     * processes are going away for other reasons.
992     */
993    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
994
995    /**
996     * The last total number of process we have, to determine if changes actually look
997     * like a shrinking number of process due to lower RAM.
998     */
999    int mLastNumProcesses;
1000
1001    /**
1002     * The uptime of the last time we performed idle maintenance.
1003     */
1004    long mLastIdleTime = SystemClock.uptimeMillis();
1005
1006    /**
1007     * Total time spent with RAM that has been added in the past since the last idle time.
1008     */
1009    long mLowRamTimeSinceLastIdle = 0;
1010
1011    /**
1012     * If RAM is currently low, when that horrible situation started.
1013     */
1014    long mLowRamStartTime = 0;
1015
1016    /**
1017     * For reporting to battery stats the current top application.
1018     */
1019    private String mCurResumedPackage = null;
1020    private int mCurResumedUid = -1;
1021
1022    /**
1023     * For reporting to battery stats the apps currently running foreground
1024     * service.  The ProcessMap is package/uid tuples; each of these contain
1025     * an array of the currently foreground processes.
1026     */
1027    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1028            = new ProcessMap<ArrayList<ProcessRecord>>();
1029
1030    /**
1031     * This is set if we had to do a delayed dexopt of an app before launching
1032     * it, to increase the ANR timeouts in that case.
1033     */
1034    boolean mDidDexOpt;
1035
1036    /**
1037     * Set if the systemServer made a call to enterSafeMode.
1038     */
1039    boolean mSafeMode;
1040
1041    String mDebugApp = null;
1042    boolean mWaitForDebugger = false;
1043    boolean mDebugTransient = false;
1044    String mOrigDebugApp = null;
1045    boolean mOrigWaitForDebugger = false;
1046    boolean mAlwaysFinishActivities = false;
1047    IActivityController mController = null;
1048    String mProfileApp = null;
1049    ProcessRecord mProfileProc = null;
1050    String mProfileFile;
1051    ParcelFileDescriptor mProfileFd;
1052    int mSamplingInterval = 0;
1053    boolean mAutoStopProfiler = false;
1054    int mProfileType = 0;
1055    String mOpenGlTraceApp = null;
1056
1057    static class ProcessChangeItem {
1058        static final int CHANGE_ACTIVITIES = 1<<0;
1059        static final int CHANGE_PROCESS_STATE = 1<<1;
1060        int changes;
1061        int uid;
1062        int pid;
1063        int processState;
1064        boolean foregroundActivities;
1065    }
1066
1067    final RemoteCallbackList<IProcessObserver> mProcessObservers
1068            = new RemoteCallbackList<IProcessObserver>();
1069    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1070
1071    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1072            = new ArrayList<ProcessChangeItem>();
1073    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1074            = new ArrayList<ProcessChangeItem>();
1075
1076    /**
1077     * Runtime CPU use collection thread.  This object's lock is used to
1078     * protect all related state.
1079     */
1080    final Thread mProcessCpuThread;
1081
1082    /**
1083     * Used to collect process stats when showing not responding dialog.
1084     * Protected by mProcessCpuThread.
1085     */
1086    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1087            MONITOR_THREAD_CPU_USAGE);
1088    final AtomicLong mLastCpuTime = new AtomicLong(0);
1089    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1090
1091    long mLastWriteTime = 0;
1092
1093    /**
1094     * Used to retain an update lock when the foreground activity is in
1095     * immersive mode.
1096     */
1097    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1098
1099    /**
1100     * Set to true after the system has finished booting.
1101     */
1102    boolean mBooted = false;
1103
1104    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1105    int mProcessLimitOverride = -1;
1106
1107    WindowManagerService mWindowManager;
1108
1109    final ActivityThread mSystemThread;
1110
1111    // Holds the current foreground user's id
1112    int mCurrentUserId = 0;
1113    // Holds the target user's id during a user switch
1114    int mTargetUserId = UserHandle.USER_NULL;
1115    // If there are multiple profiles for the current user, their ids are here
1116    // Currently only the primary user can have managed profiles
1117    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1118
1119    /**
1120     * Mapping from each known user ID to the profile group ID it is associated with.
1121     */
1122    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1123
1124    private UserManagerService mUserManager;
1125
1126    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1127        final ProcessRecord mApp;
1128        final int mPid;
1129        final IApplicationThread mAppThread;
1130
1131        AppDeathRecipient(ProcessRecord app, int pid,
1132                IApplicationThread thread) {
1133            if (localLOGV) Slog.v(
1134                TAG, "New death recipient " + this
1135                + " for thread " + thread.asBinder());
1136            mApp = app;
1137            mPid = pid;
1138            mAppThread = thread;
1139        }
1140
1141        @Override
1142        public void binderDied() {
1143            if (localLOGV) Slog.v(
1144                TAG, "Death received in " + this
1145                + " for thread " + mAppThread.asBinder());
1146            synchronized(ActivityManagerService.this) {
1147                appDiedLocked(mApp, mPid, mAppThread);
1148            }
1149        }
1150    }
1151
1152    static final int SHOW_ERROR_MSG = 1;
1153    static final int SHOW_NOT_RESPONDING_MSG = 2;
1154    static final int SHOW_FACTORY_ERROR_MSG = 3;
1155    static final int UPDATE_CONFIGURATION_MSG = 4;
1156    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1157    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1158    static final int SERVICE_TIMEOUT_MSG = 12;
1159    static final int UPDATE_TIME_ZONE = 13;
1160    static final int SHOW_UID_ERROR_MSG = 14;
1161    static final int IM_FEELING_LUCKY_MSG = 15;
1162    static final int PROC_START_TIMEOUT_MSG = 20;
1163    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1164    static final int KILL_APPLICATION_MSG = 22;
1165    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1166    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1167    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1168    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1169    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1170    static final int CLEAR_DNS_CACHE_MSG = 28;
1171    static final int UPDATE_HTTP_PROXY_MSG = 29;
1172    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1173    static final int DISPATCH_PROCESSES_CHANGED = 31;
1174    static final int DISPATCH_PROCESS_DIED = 32;
1175    static final int REPORT_MEM_USAGE_MSG = 33;
1176    static final int REPORT_USER_SWITCH_MSG = 34;
1177    static final int CONTINUE_USER_SWITCH_MSG = 35;
1178    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1179    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1180    static final int PERSIST_URI_GRANTS_MSG = 38;
1181    static final int REQUEST_ALL_PSS_MSG = 39;
1182    static final int START_PROFILES_MSG = 40;
1183    static final int UPDATE_TIME = 41;
1184    static final int SYSTEM_USER_START_MSG = 42;
1185    static final int SYSTEM_USER_CURRENT_MSG = 43;
1186    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1187    static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45;
1188    static final int START_USER_SWITCH_MSG = 46;
1189
1190    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1191    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1192    static final int FIRST_COMPAT_MODE_MSG = 300;
1193    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1194
1195    AlertDialog mUidAlert;
1196    CompatModeDialog mCompatModeDialog;
1197    long mLastMemUsageReportTime = 0;
1198
1199    private LockToAppRequestDialog mLockToAppRequest;
1200
1201    /**
1202     * Flag whether the current user is a "monkey", i.e. whether
1203     * the UI is driven by a UI automation tool.
1204     */
1205    private boolean mUserIsMonkey;
1206
1207    /** Flag whether the device has a Recents UI */
1208    boolean mHasRecents;
1209
1210    /** The dimensions of the thumbnails in the Recents UI. */
1211    int mThumbnailWidth;
1212    int mThumbnailHeight;
1213
1214    final ServiceThread mHandlerThread;
1215    final MainHandler mHandler;
1216
1217    final class MainHandler extends Handler {
1218        public MainHandler(Looper looper) {
1219            super(looper, null, true);
1220        }
1221
1222        @Override
1223        public void handleMessage(Message msg) {
1224            switch (msg.what) {
1225            case SHOW_ERROR_MSG: {
1226                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1227                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1228                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1229                synchronized (ActivityManagerService.this) {
1230                    ProcessRecord proc = (ProcessRecord)data.get("app");
1231                    AppErrorResult res = (AppErrorResult) data.get("result");
1232                    if (proc != null && proc.crashDialog != null) {
1233                        Slog.e(TAG, "App already has crash dialog: " + proc);
1234                        if (res != null) {
1235                            res.set(0);
1236                        }
1237                        return;
1238                    }
1239                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1240                            >= Process.FIRST_APPLICATION_UID
1241                            && proc.pid != MY_PID);
1242                    for (int userId : mCurrentProfileIds) {
1243                        isBackground &= (proc.userId != userId);
1244                    }
1245                    if (isBackground && !showBackground) {
1246                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1247                        if (res != null) {
1248                            res.set(0);
1249                        }
1250                        return;
1251                    }
1252                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1253                        Dialog d = new AppErrorDialog(mContext,
1254                                ActivityManagerService.this, res, proc);
1255                        d.show();
1256                        proc.crashDialog = d;
1257                    } else {
1258                        // The device is asleep, so just pretend that the user
1259                        // saw a crash dialog and hit "force quit".
1260                        if (res != null) {
1261                            res.set(0);
1262                        }
1263                    }
1264                }
1265
1266                ensureBootCompleted();
1267            } break;
1268            case SHOW_NOT_RESPONDING_MSG: {
1269                synchronized (ActivityManagerService.this) {
1270                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1271                    ProcessRecord proc = (ProcessRecord)data.get("app");
1272                    if (proc != null && proc.anrDialog != null) {
1273                        Slog.e(TAG, "App already has anr dialog: " + proc);
1274                        return;
1275                    }
1276
1277                    Intent intent = new Intent("android.intent.action.ANR");
1278                    if (!mProcessesReady) {
1279                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1280                                | Intent.FLAG_RECEIVER_FOREGROUND);
1281                    }
1282                    broadcastIntentLocked(null, null, intent,
1283                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1284                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1285
1286                    if (mShowDialogs) {
1287                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1288                                mContext, proc, (ActivityRecord)data.get("activity"),
1289                                msg.arg1 != 0);
1290                        d.show();
1291                        proc.anrDialog = d;
1292                    } else {
1293                        // Just kill the app if there is no dialog to be shown.
1294                        killAppAtUsersRequest(proc, null);
1295                    }
1296                }
1297
1298                ensureBootCompleted();
1299            } break;
1300            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1301                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1302                synchronized (ActivityManagerService.this) {
1303                    ProcessRecord proc = (ProcessRecord) data.get("app");
1304                    if (proc == null) {
1305                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1306                        break;
1307                    }
1308                    if (proc.crashDialog != null) {
1309                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1310                        return;
1311                    }
1312                    AppErrorResult res = (AppErrorResult) data.get("result");
1313                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1314                        Dialog d = new StrictModeViolationDialog(mContext,
1315                                ActivityManagerService.this, res, proc);
1316                        d.show();
1317                        proc.crashDialog = d;
1318                    } else {
1319                        // The device is asleep, so just pretend that the user
1320                        // saw a crash dialog and hit "force quit".
1321                        res.set(0);
1322                    }
1323                }
1324                ensureBootCompleted();
1325            } break;
1326            case SHOW_FACTORY_ERROR_MSG: {
1327                Dialog d = new FactoryErrorDialog(
1328                    mContext, msg.getData().getCharSequence("msg"));
1329                d.show();
1330                ensureBootCompleted();
1331            } break;
1332            case UPDATE_CONFIGURATION_MSG: {
1333                final ContentResolver resolver = mContext.getContentResolver();
1334                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1335            } break;
1336            case GC_BACKGROUND_PROCESSES_MSG: {
1337                synchronized (ActivityManagerService.this) {
1338                    performAppGcsIfAppropriateLocked();
1339                }
1340            } break;
1341            case WAIT_FOR_DEBUGGER_MSG: {
1342                synchronized (ActivityManagerService.this) {
1343                    ProcessRecord app = (ProcessRecord)msg.obj;
1344                    if (msg.arg1 != 0) {
1345                        if (!app.waitedForDebugger) {
1346                            Dialog d = new AppWaitingForDebuggerDialog(
1347                                    ActivityManagerService.this,
1348                                    mContext, app);
1349                            app.waitDialog = d;
1350                            app.waitedForDebugger = true;
1351                            d.show();
1352                        }
1353                    } else {
1354                        if (app.waitDialog != null) {
1355                            app.waitDialog.dismiss();
1356                            app.waitDialog = null;
1357                        }
1358                    }
1359                }
1360            } break;
1361            case SERVICE_TIMEOUT_MSG: {
1362                if (mDidDexOpt) {
1363                    mDidDexOpt = false;
1364                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1365                    nmsg.obj = msg.obj;
1366                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1367                    return;
1368                }
1369                mServices.serviceTimeout((ProcessRecord)msg.obj);
1370            } break;
1371            case UPDATE_TIME_ZONE: {
1372                synchronized (ActivityManagerService.this) {
1373                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1374                        ProcessRecord r = mLruProcesses.get(i);
1375                        if (r.thread != null) {
1376                            try {
1377                                r.thread.updateTimeZone();
1378                            } catch (RemoteException ex) {
1379                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1380                            }
1381                        }
1382                    }
1383                }
1384            } break;
1385            case CLEAR_DNS_CACHE_MSG: {
1386                synchronized (ActivityManagerService.this) {
1387                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1388                        ProcessRecord r = mLruProcesses.get(i);
1389                        if (r.thread != null) {
1390                            try {
1391                                r.thread.clearDnsCache();
1392                            } catch (RemoteException ex) {
1393                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1394                            }
1395                        }
1396                    }
1397                }
1398            } break;
1399            case UPDATE_HTTP_PROXY_MSG: {
1400                ProxyInfo proxy = (ProxyInfo)msg.obj;
1401                String host = "";
1402                String port = "";
1403                String exclList = "";
1404                Uri pacFileUrl = Uri.EMPTY;
1405                if (proxy != null) {
1406                    host = proxy.getHost();
1407                    port = Integer.toString(proxy.getPort());
1408                    exclList = proxy.getExclusionListAsString();
1409                    pacFileUrl = proxy.getPacFileUrl();
1410                }
1411                synchronized (ActivityManagerService.this) {
1412                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1413                        ProcessRecord r = mLruProcesses.get(i);
1414                        if (r.thread != null) {
1415                            try {
1416                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1417                            } catch (RemoteException ex) {
1418                                Slog.w(TAG, "Failed to update http proxy for: " +
1419                                        r.info.processName);
1420                            }
1421                        }
1422                    }
1423                }
1424            } break;
1425            case SHOW_UID_ERROR_MSG: {
1426                String title = "System UIDs Inconsistent";
1427                String text = "UIDs on the system are inconsistent, you need to wipe your"
1428                        + " data partition or your device will be unstable.";
1429                Log.e(TAG, title + ": " + text);
1430                if (mShowDialogs) {
1431                    // XXX This is a temporary dialog, no need to localize.
1432                    AlertDialog d = new BaseErrorDialog(mContext);
1433                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1434                    d.setCancelable(false);
1435                    d.setTitle(title);
1436                    d.setMessage(text);
1437                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1438                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1439                    mUidAlert = d;
1440                    d.show();
1441                }
1442            } break;
1443            case IM_FEELING_LUCKY_MSG: {
1444                if (mUidAlert != null) {
1445                    mUidAlert.dismiss();
1446                    mUidAlert = null;
1447                }
1448            } break;
1449            case PROC_START_TIMEOUT_MSG: {
1450                if (mDidDexOpt) {
1451                    mDidDexOpt = false;
1452                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1453                    nmsg.obj = msg.obj;
1454                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1455                    return;
1456                }
1457                ProcessRecord app = (ProcessRecord)msg.obj;
1458                synchronized (ActivityManagerService.this) {
1459                    processStartTimedOutLocked(app);
1460                }
1461            } break;
1462            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1463                synchronized (ActivityManagerService.this) {
1464                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1465                }
1466            } break;
1467            case KILL_APPLICATION_MSG: {
1468                synchronized (ActivityManagerService.this) {
1469                    int appid = msg.arg1;
1470                    boolean restart = (msg.arg2 == 1);
1471                    Bundle bundle = (Bundle)msg.obj;
1472                    String pkg = bundle.getString("pkg");
1473                    String reason = bundle.getString("reason");
1474                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1475                            false, UserHandle.USER_ALL, reason);
1476                }
1477            } break;
1478            case FINALIZE_PENDING_INTENT_MSG: {
1479                ((PendingIntentRecord)msg.obj).completeFinalize();
1480            } break;
1481            case POST_HEAVY_NOTIFICATION_MSG: {
1482                INotificationManager inm = NotificationManager.getService();
1483                if (inm == null) {
1484                    return;
1485                }
1486
1487                ActivityRecord root = (ActivityRecord)msg.obj;
1488                ProcessRecord process = root.app;
1489                if (process == null) {
1490                    return;
1491                }
1492
1493                try {
1494                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1495                    String text = mContext.getString(R.string.heavy_weight_notification,
1496                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1497                    Notification notification = new Notification();
1498                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1499                    notification.when = 0;
1500                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1501                    notification.tickerText = text;
1502                    notification.defaults = 0; // please be quiet
1503                    notification.sound = null;
1504                    notification.vibrate = null;
1505                    notification.color = mContext.getResources().getColor(
1506                            com.android.internal.R.color.system_notification_accent_color);
1507                    notification.setLatestEventInfo(context, text,
1508                            mContext.getText(R.string.heavy_weight_notification_detail),
1509                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1510                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1511                                    new UserHandle(root.userId)));
1512
1513                    try {
1514                        int[] outId = new int[1];
1515                        inm.enqueueNotificationWithTag("android", "android", null,
1516                                R.string.heavy_weight_notification,
1517                                notification, outId, root.userId);
1518                    } catch (RuntimeException e) {
1519                        Slog.w(ActivityManagerService.TAG,
1520                                "Error showing notification for heavy-weight app", e);
1521                    } catch (RemoteException e) {
1522                    }
1523                } catch (NameNotFoundException e) {
1524                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1525                }
1526            } break;
1527            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1528                INotificationManager inm = NotificationManager.getService();
1529                if (inm == null) {
1530                    return;
1531                }
1532                try {
1533                    inm.cancelNotificationWithTag("android", null,
1534                            R.string.heavy_weight_notification,  msg.arg1);
1535                } catch (RuntimeException e) {
1536                    Slog.w(ActivityManagerService.TAG,
1537                            "Error canceling notification for service", e);
1538                } catch (RemoteException e) {
1539                }
1540            } break;
1541            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1542                synchronized (ActivityManagerService.this) {
1543                    checkExcessivePowerUsageLocked(true);
1544                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1545                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1546                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1547                }
1548            } break;
1549            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1550                synchronized (ActivityManagerService.this) {
1551                    ActivityRecord ar = (ActivityRecord)msg.obj;
1552                    if (mCompatModeDialog != null) {
1553                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1554                                ar.info.applicationInfo.packageName)) {
1555                            return;
1556                        }
1557                        mCompatModeDialog.dismiss();
1558                        mCompatModeDialog = null;
1559                    }
1560                    if (ar != null && false) {
1561                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1562                                ar.packageName)) {
1563                            int mode = mCompatModePackages.computeCompatModeLocked(
1564                                    ar.info.applicationInfo);
1565                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1566                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1567                                mCompatModeDialog = new CompatModeDialog(
1568                                        ActivityManagerService.this, mContext,
1569                                        ar.info.applicationInfo);
1570                                mCompatModeDialog.show();
1571                            }
1572                        }
1573                    }
1574                }
1575                break;
1576            }
1577            case DISPATCH_PROCESSES_CHANGED: {
1578                dispatchProcessesChanged();
1579                break;
1580            }
1581            case DISPATCH_PROCESS_DIED: {
1582                final int pid = msg.arg1;
1583                final int uid = msg.arg2;
1584                dispatchProcessDied(pid, uid);
1585                break;
1586            }
1587            case REPORT_MEM_USAGE_MSG: {
1588                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1589                Thread thread = new Thread() {
1590                    @Override public void run() {
1591                        final SparseArray<ProcessMemInfo> infoMap
1592                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1593                        for (int i=0, N=memInfos.size(); i<N; i++) {
1594                            ProcessMemInfo mi = memInfos.get(i);
1595                            infoMap.put(mi.pid, mi);
1596                        }
1597                        updateCpuStatsNow();
1598                        synchronized (mProcessCpuThread) {
1599                            final int N = mProcessCpuTracker.countStats();
1600                            for (int i=0; i<N; i++) {
1601                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1602                                if (st.vsize > 0) {
1603                                    long pss = Debug.getPss(st.pid, null);
1604                                    if (pss > 0) {
1605                                        if (infoMap.indexOfKey(st.pid) < 0) {
1606                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1607                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1608                                            mi.pss = pss;
1609                                            memInfos.add(mi);
1610                                        }
1611                                    }
1612                                }
1613                            }
1614                        }
1615
1616                        long totalPss = 0;
1617                        for (int i=0, N=memInfos.size(); i<N; i++) {
1618                            ProcessMemInfo mi = memInfos.get(i);
1619                            if (mi.pss == 0) {
1620                                mi.pss = Debug.getPss(mi.pid, null);
1621                            }
1622                            totalPss += mi.pss;
1623                        }
1624                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1625                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1626                                if (lhs.oomAdj != rhs.oomAdj) {
1627                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1628                                }
1629                                if (lhs.pss != rhs.pss) {
1630                                    return lhs.pss < rhs.pss ? 1 : -1;
1631                                }
1632                                return 0;
1633                            }
1634                        });
1635
1636                        StringBuilder tag = new StringBuilder(128);
1637                        StringBuilder stack = new StringBuilder(128);
1638                        tag.append("Low on memory -- ");
1639                        appendMemBucket(tag, totalPss, "total", false);
1640                        appendMemBucket(stack, totalPss, "total", true);
1641
1642                        StringBuilder logBuilder = new StringBuilder(1024);
1643                        logBuilder.append("Low on memory:\n");
1644
1645                        boolean firstLine = true;
1646                        int lastOomAdj = Integer.MIN_VALUE;
1647                        for (int i=0, N=memInfos.size(); i<N; i++) {
1648                            ProcessMemInfo mi = memInfos.get(i);
1649
1650                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1651                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1652                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1653                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1654                                if (lastOomAdj != mi.oomAdj) {
1655                                    lastOomAdj = mi.oomAdj;
1656                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1657                                        tag.append(" / ");
1658                                    }
1659                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1660                                        if (firstLine) {
1661                                            stack.append(":");
1662                                            firstLine = false;
1663                                        }
1664                                        stack.append("\n\t at ");
1665                                    } else {
1666                                        stack.append("$");
1667                                    }
1668                                } else {
1669                                    tag.append(" ");
1670                                    stack.append("$");
1671                                }
1672                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1673                                    appendMemBucket(tag, mi.pss, mi.name, false);
1674                                }
1675                                appendMemBucket(stack, mi.pss, mi.name, true);
1676                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1677                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1678                                    stack.append("(");
1679                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1680                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1681                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1682                                            stack.append(":");
1683                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1684                                        }
1685                                    }
1686                                    stack.append(")");
1687                                }
1688                            }
1689
1690                            logBuilder.append("  ");
1691                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1692                            logBuilder.append(' ');
1693                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1694                            logBuilder.append(' ');
1695                            ProcessList.appendRamKb(logBuilder, mi.pss);
1696                            logBuilder.append(" kB: ");
1697                            logBuilder.append(mi.name);
1698                            logBuilder.append(" (");
1699                            logBuilder.append(mi.pid);
1700                            logBuilder.append(") ");
1701                            logBuilder.append(mi.adjType);
1702                            logBuilder.append('\n');
1703                            if (mi.adjReason != null) {
1704                                logBuilder.append("                      ");
1705                                logBuilder.append(mi.adjReason);
1706                                logBuilder.append('\n');
1707                            }
1708                        }
1709
1710                        logBuilder.append("           ");
1711                        ProcessList.appendRamKb(logBuilder, totalPss);
1712                        logBuilder.append(" kB: TOTAL\n");
1713
1714                        long[] infos = new long[Debug.MEMINFO_COUNT];
1715                        Debug.getMemInfo(infos);
1716                        logBuilder.append("  MemInfo: ");
1717                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1718                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1719                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1720                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1721                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1722                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1723                            logBuilder.append("  ZRAM: ");
1724                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1725                            logBuilder.append(" kB RAM, ");
1726                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1727                            logBuilder.append(" kB swap total, ");
1728                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1729                            logBuilder.append(" kB swap free\n");
1730                        }
1731                        Slog.i(TAG, logBuilder.toString());
1732
1733                        StringBuilder dropBuilder = new StringBuilder(1024);
1734                        /*
1735                        StringWriter oomSw = new StringWriter();
1736                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1737                        StringWriter catSw = new StringWriter();
1738                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1739                        String[] emptyArgs = new String[] { };
1740                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1741                        oomPw.flush();
1742                        String oomString = oomSw.toString();
1743                        */
1744                        dropBuilder.append(stack);
1745                        dropBuilder.append('\n');
1746                        dropBuilder.append('\n');
1747                        dropBuilder.append(logBuilder);
1748                        dropBuilder.append('\n');
1749                        /*
1750                        dropBuilder.append(oomString);
1751                        dropBuilder.append('\n');
1752                        */
1753                        StringWriter catSw = new StringWriter();
1754                        synchronized (ActivityManagerService.this) {
1755                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1756                            String[] emptyArgs = new String[] { };
1757                            catPw.println();
1758                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1759                            catPw.println();
1760                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1761                                    false, false, null);
1762                            catPw.println();
1763                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1764                            catPw.flush();
1765                        }
1766                        dropBuilder.append(catSw.toString());
1767                        addErrorToDropBox("lowmem", null, "system_server", null,
1768                                null, tag.toString(), dropBuilder.toString(), null, null);
1769                        //Slog.i(TAG, "Sent to dropbox:");
1770                        //Slog.i(TAG, dropBuilder.toString());
1771                        synchronized (ActivityManagerService.this) {
1772                            long now = SystemClock.uptimeMillis();
1773                            if (mLastMemUsageReportTime < now) {
1774                                mLastMemUsageReportTime = now;
1775                            }
1776                        }
1777                    }
1778                };
1779                thread.start();
1780                break;
1781            }
1782            case START_USER_SWITCH_MSG: {
1783                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1784                break;
1785            }
1786            case REPORT_USER_SWITCH_MSG: {
1787                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1788                break;
1789            }
1790            case CONTINUE_USER_SWITCH_MSG: {
1791                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1792                break;
1793            }
1794            case USER_SWITCH_TIMEOUT_MSG: {
1795                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1796                break;
1797            }
1798            case IMMERSIVE_MODE_LOCK_MSG: {
1799                final boolean nextState = (msg.arg1 != 0);
1800                if (mUpdateLock.isHeld() != nextState) {
1801                    if (DEBUG_IMMERSIVE) {
1802                        final ActivityRecord r = (ActivityRecord) msg.obj;
1803                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1804                    }
1805                    if (nextState) {
1806                        mUpdateLock.acquire();
1807                    } else {
1808                        mUpdateLock.release();
1809                    }
1810                }
1811                break;
1812            }
1813            case PERSIST_URI_GRANTS_MSG: {
1814                writeGrantedUriPermissions();
1815                break;
1816            }
1817            case REQUEST_ALL_PSS_MSG: {
1818                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1819                break;
1820            }
1821            case START_PROFILES_MSG: {
1822                synchronized (ActivityManagerService.this) {
1823                    startProfilesLocked();
1824                }
1825                break;
1826            }
1827            case UPDATE_TIME: {
1828                synchronized (ActivityManagerService.this) {
1829                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1830                        ProcessRecord r = mLruProcesses.get(i);
1831                        if (r.thread != null) {
1832                            try {
1833                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1834                            } catch (RemoteException ex) {
1835                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1836                            }
1837                        }
1838                    }
1839                }
1840                break;
1841            }
1842            case SYSTEM_USER_START_MSG: {
1843                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1844                        Integer.toString(msg.arg1), msg.arg1);
1845                mSystemServiceManager.startUser(msg.arg1);
1846                break;
1847            }
1848            case SYSTEM_USER_CURRENT_MSG: {
1849                mBatteryStatsService.noteEvent(
1850                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1851                        Integer.toString(msg.arg2), msg.arg2);
1852                mBatteryStatsService.noteEvent(
1853                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1854                        Integer.toString(msg.arg1), msg.arg1);
1855                mSystemServiceManager.switchUser(msg.arg1);
1856                mLockToAppRequest.clearPrompt();
1857                break;
1858            }
1859            case ENTER_ANIMATION_COMPLETE_MSG: {
1860                synchronized (ActivityManagerService.this) {
1861                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1862                    if (r != null && r.app != null && r.app.thread != null) {
1863                        try {
1864                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1865                        } catch (RemoteException e) {
1866                        }
1867                    }
1868                }
1869                break;
1870            }
1871            case ENABLE_SCREEN_AFTER_BOOT_MSG: {
1872                enableScreenAfterBoot();
1873                break;
1874            }
1875            }
1876        }
1877    };
1878
1879    static final int COLLECT_PSS_BG_MSG = 1;
1880
1881    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1882        @Override
1883        public void handleMessage(Message msg) {
1884            switch (msg.what) {
1885            case COLLECT_PSS_BG_MSG: {
1886                long start = SystemClock.uptimeMillis();
1887                MemInfoReader memInfo = null;
1888                synchronized (ActivityManagerService.this) {
1889                    if (mFullPssPending) {
1890                        mFullPssPending = false;
1891                        memInfo = new MemInfoReader();
1892                    }
1893                }
1894                if (memInfo != null) {
1895                    updateCpuStatsNow();
1896                    long nativeTotalPss = 0;
1897                    synchronized (mProcessCpuThread) {
1898                        final int N = mProcessCpuTracker.countStats();
1899                        for (int j=0; j<N; j++) {
1900                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1901                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1902                                // This is definitely an application process; skip it.
1903                                continue;
1904                            }
1905                            synchronized (mPidsSelfLocked) {
1906                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1907                                    // This is one of our own processes; skip it.
1908                                    continue;
1909                                }
1910                            }
1911                            nativeTotalPss += Debug.getPss(st.pid, null);
1912                        }
1913                    }
1914                    memInfo.readMemInfo();
1915                    synchronized (this) {
1916                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1917                                + (SystemClock.uptimeMillis()-start) + "ms");
1918                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1919                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1920                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1921                                        +memInfo.getSlabSizeKb(),
1922                                nativeTotalPss);
1923                    }
1924                }
1925
1926                int i=0, num=0;
1927                long[] tmp = new long[1];
1928                do {
1929                    ProcessRecord proc;
1930                    int procState;
1931                    int pid;
1932                    synchronized (ActivityManagerService.this) {
1933                        if (i >= mPendingPssProcesses.size()) {
1934                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1935                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1936                            mPendingPssProcesses.clear();
1937                            return;
1938                        }
1939                        proc = mPendingPssProcesses.get(i);
1940                        procState = proc.pssProcState;
1941                        if (proc.thread != null && procState == proc.setProcState) {
1942                            pid = proc.pid;
1943                        } else {
1944                            proc = null;
1945                            pid = 0;
1946                        }
1947                        i++;
1948                    }
1949                    if (proc != null) {
1950                        long pss = Debug.getPss(pid, tmp);
1951                        synchronized (ActivityManagerService.this) {
1952                            if (proc.thread != null && proc.setProcState == procState
1953                                    && proc.pid == pid) {
1954                                num++;
1955                                proc.lastPssTime = SystemClock.uptimeMillis();
1956                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1957                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1958                                        + ": " + pss + " lastPss=" + proc.lastPss
1959                                        + " state=" + ProcessList.makeProcStateString(procState));
1960                                if (proc.initialIdlePss == 0) {
1961                                    proc.initialIdlePss = pss;
1962                                }
1963                                proc.lastPss = pss;
1964                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1965                                    proc.lastCachedPss = pss;
1966                                }
1967                            }
1968                        }
1969                    }
1970                } while (true);
1971            }
1972            }
1973        }
1974    };
1975
1976    /**
1977     * Monitor for package changes and update our internal state.
1978     */
1979    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1980        @Override
1981        public void onPackageRemoved(String packageName, int uid) {
1982            // Remove all tasks with activities in the specified package from the list of recent tasks
1983            synchronized (ActivityManagerService.this) {
1984                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1985                    TaskRecord tr = mRecentTasks.get(i);
1986                    ComponentName cn = tr.intent.getComponent();
1987                    if (cn != null && cn.getPackageName().equals(packageName)) {
1988                        // If the package name matches, remove the task and kill the process
1989                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1990                    }
1991                }
1992            }
1993        }
1994
1995        @Override
1996        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1997            onPackageModified(packageName);
1998            return true;
1999        }
2000
2001        @Override
2002        public void onPackageModified(String packageName) {
2003            final PackageManager pm = mContext.getPackageManager();
2004            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
2005                    new ArrayList<Pair<Intent, Integer>>();
2006            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
2007            // Copy the list of recent tasks so that we don't hold onto the lock on
2008            // ActivityManagerService for long periods while checking if components exist.
2009            synchronized (ActivityManagerService.this) {
2010                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2011                    TaskRecord tr = mRecentTasks.get(i);
2012                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
2013                }
2014            }
2015            // Check the recent tasks and filter out all tasks with components that no longer exist.
2016            Intent tmpI = new Intent();
2017            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
2018                Pair<Intent, Integer> p = recentTaskIntents.get(i);
2019                ComponentName cn = p.first.getComponent();
2020                if (cn != null && cn.getPackageName().equals(packageName)) {
2021                    try {
2022                        // Add the task to the list to remove if the component no longer exists
2023                        tmpI.setComponent(cn);
2024                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
2025                            tasksToRemove.add(p.second);
2026                        }
2027                    } catch (Exception e) {}
2028                }
2029            }
2030            // Prune all the tasks with removed components from the list of recent tasks
2031            synchronized (ActivityManagerService.this) {
2032                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
2033                    // Remove the task but don't kill the process (since other components in that
2034                    // package may still be running and in the background)
2035                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
2036                }
2037            }
2038        }
2039
2040        @Override
2041        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2042            // Force stop the specified packages
2043            if (packages != null) {
2044                for (String pkg : packages) {
2045                    synchronized (ActivityManagerService.this) {
2046                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2047                                "finished booting")) {
2048                            return true;
2049                        }
2050                    }
2051                }
2052            }
2053            return false;
2054        }
2055    };
2056
2057    public void setSystemProcess() {
2058        try {
2059            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2060            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2061            ServiceManager.addService("meminfo", new MemBinder(this));
2062            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2063            ServiceManager.addService("dbinfo", new DbBinder(this));
2064            if (MONITOR_CPU_USAGE) {
2065                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2066            }
2067            ServiceManager.addService("permission", new PermissionController(this));
2068
2069            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2070                    "android", STOCK_PM_FLAGS);
2071            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2072
2073            synchronized (this) {
2074                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2075                app.persistent = true;
2076                app.pid = MY_PID;
2077                app.maxAdj = ProcessList.SYSTEM_ADJ;
2078                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2079                mProcessNames.put(app.processName, app.uid, app);
2080                synchronized (mPidsSelfLocked) {
2081                    mPidsSelfLocked.put(app.pid, app);
2082                }
2083                updateLruProcessLocked(app, false, null);
2084                updateOomAdjLocked();
2085            }
2086        } catch (PackageManager.NameNotFoundException e) {
2087            throw new RuntimeException(
2088                    "Unable to find android system package", e);
2089        }
2090    }
2091
2092    public void setWindowManager(WindowManagerService wm) {
2093        mWindowManager = wm;
2094        mStackSupervisor.setWindowManager(wm);
2095    }
2096
2097    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2098        mUsageStatsService = usageStatsManager;
2099    }
2100
2101    public void startObservingNativeCrashes() {
2102        final NativeCrashListener ncl = new NativeCrashListener(this);
2103        ncl.start();
2104    }
2105
2106    public IAppOpsService getAppOpsService() {
2107        return mAppOpsService;
2108    }
2109
2110    static class MemBinder extends Binder {
2111        ActivityManagerService mActivityManagerService;
2112        MemBinder(ActivityManagerService activityManagerService) {
2113            mActivityManagerService = activityManagerService;
2114        }
2115
2116        @Override
2117        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2118            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2119                    != PackageManager.PERMISSION_GRANTED) {
2120                pw.println("Permission Denial: can't dump meminfo from from pid="
2121                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2122                        + " without permission " + android.Manifest.permission.DUMP);
2123                return;
2124            }
2125
2126            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2127        }
2128    }
2129
2130    static class GraphicsBinder extends Binder {
2131        ActivityManagerService mActivityManagerService;
2132        GraphicsBinder(ActivityManagerService activityManagerService) {
2133            mActivityManagerService = activityManagerService;
2134        }
2135
2136        @Override
2137        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2138            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2139                    != PackageManager.PERMISSION_GRANTED) {
2140                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2141                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2142                        + " without permission " + android.Manifest.permission.DUMP);
2143                return;
2144            }
2145
2146            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2147        }
2148    }
2149
2150    static class DbBinder extends Binder {
2151        ActivityManagerService mActivityManagerService;
2152        DbBinder(ActivityManagerService activityManagerService) {
2153            mActivityManagerService = activityManagerService;
2154        }
2155
2156        @Override
2157        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2158            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2159                    != PackageManager.PERMISSION_GRANTED) {
2160                pw.println("Permission Denial: can't dump dbinfo from from pid="
2161                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2162                        + " without permission " + android.Manifest.permission.DUMP);
2163                return;
2164            }
2165
2166            mActivityManagerService.dumpDbInfo(fd, pw, args);
2167        }
2168    }
2169
2170    static class CpuBinder extends Binder {
2171        ActivityManagerService mActivityManagerService;
2172        CpuBinder(ActivityManagerService activityManagerService) {
2173            mActivityManagerService = activityManagerService;
2174        }
2175
2176        @Override
2177        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2178            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2179                    != PackageManager.PERMISSION_GRANTED) {
2180                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2181                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2182                        + " without permission " + android.Manifest.permission.DUMP);
2183                return;
2184            }
2185
2186            synchronized (mActivityManagerService.mProcessCpuThread) {
2187                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2188                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2189                        SystemClock.uptimeMillis()));
2190            }
2191        }
2192    }
2193
2194    public static final class Lifecycle extends SystemService {
2195        private final ActivityManagerService mService;
2196
2197        public Lifecycle(Context context) {
2198            super(context);
2199            mService = new ActivityManagerService(context);
2200        }
2201
2202        @Override
2203        public void onStart() {
2204            mService.start();
2205        }
2206
2207        public ActivityManagerService getService() {
2208            return mService;
2209        }
2210    }
2211
2212    // Note: This method is invoked on the main thread but may need to attach various
2213    // handlers to other threads.  So take care to be explicit about the looper.
2214    public ActivityManagerService(Context systemContext) {
2215        mContext = systemContext;
2216        mFactoryTest = FactoryTest.getMode();
2217        mSystemThread = ActivityThread.currentActivityThread();
2218
2219        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2220
2221        mHandlerThread = new ServiceThread(TAG,
2222                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2223        mHandlerThread.start();
2224        mHandler = new MainHandler(mHandlerThread.getLooper());
2225
2226        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2227                "foreground", BROADCAST_FG_TIMEOUT, false);
2228        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2229                "background", BROADCAST_BG_TIMEOUT, true);
2230        mBroadcastQueues[0] = mFgBroadcastQueue;
2231        mBroadcastQueues[1] = mBgBroadcastQueue;
2232
2233        mServices = new ActiveServices(this);
2234        mProviderMap = new ProviderMap(this);
2235
2236        // TODO: Move creation of battery stats service outside of activity manager service.
2237        File dataDir = Environment.getDataDirectory();
2238        File systemDir = new File(dataDir, "system");
2239        systemDir.mkdirs();
2240        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2241        mBatteryStatsService.getActiveStatistics().readLocked();
2242        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2243        mOnBattery = DEBUG_POWER ? true
2244                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2245        mBatteryStatsService.getActiveStatistics().setCallback(this);
2246
2247        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2248
2249        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2250
2251        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2252
2253        // User 0 is the first and only user that runs at boot.
2254        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2255        mUserLru.add(Integer.valueOf(0));
2256        updateStartedUserArrayLocked();
2257
2258        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2259            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2260
2261        mConfiguration.setToDefaults();
2262        mConfiguration.setLocale(Locale.getDefault());
2263
2264        mConfigurationSeq = mConfiguration.seq = 1;
2265        mProcessCpuTracker.init();
2266
2267        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2268        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2269        mStackSupervisor = new ActivityStackSupervisor(this);
2270        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2271
2272        mProcessCpuThread = new Thread("CpuTracker") {
2273            @Override
2274            public void run() {
2275                while (true) {
2276                    try {
2277                        try {
2278                            synchronized(this) {
2279                                final long now = SystemClock.uptimeMillis();
2280                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2281                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2282                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2283                                //        + ", write delay=" + nextWriteDelay);
2284                                if (nextWriteDelay < nextCpuDelay) {
2285                                    nextCpuDelay = nextWriteDelay;
2286                                }
2287                                if (nextCpuDelay > 0) {
2288                                    mProcessCpuMutexFree.set(true);
2289                                    this.wait(nextCpuDelay);
2290                                }
2291                            }
2292                        } catch (InterruptedException e) {
2293                        }
2294                        updateCpuStatsNow();
2295                    } catch (Exception e) {
2296                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2297                    }
2298                }
2299            }
2300        };
2301
2302        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2303
2304        Watchdog.getInstance().addMonitor(this);
2305        Watchdog.getInstance().addThread(mHandler);
2306    }
2307
2308    public void setSystemServiceManager(SystemServiceManager mgr) {
2309        mSystemServiceManager = mgr;
2310    }
2311
2312    private void start() {
2313        Process.removeAllProcessGroups();
2314        mProcessCpuThread.start();
2315
2316        mBatteryStatsService.publish(mContext);
2317        mAppOpsService.publish(mContext);
2318        Slog.d("AppOps", "AppOpsService published");
2319        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2320    }
2321
2322    public void initPowerManagement() {
2323        mStackSupervisor.initPowerManagement();
2324        mBatteryStatsService.initPowerManagement();
2325    }
2326
2327    @Override
2328    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2329            throws RemoteException {
2330        if (code == SYSPROPS_TRANSACTION) {
2331            // We need to tell all apps about the system property change.
2332            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2333            synchronized(this) {
2334                final int NP = mProcessNames.getMap().size();
2335                for (int ip=0; ip<NP; ip++) {
2336                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2337                    final int NA = apps.size();
2338                    for (int ia=0; ia<NA; ia++) {
2339                        ProcessRecord app = apps.valueAt(ia);
2340                        if (app.thread != null) {
2341                            procs.add(app.thread.asBinder());
2342                        }
2343                    }
2344                }
2345            }
2346
2347            int N = procs.size();
2348            for (int i=0; i<N; i++) {
2349                Parcel data2 = Parcel.obtain();
2350                try {
2351                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2352                } catch (RemoteException e) {
2353                }
2354                data2.recycle();
2355            }
2356        }
2357        try {
2358            return super.onTransact(code, data, reply, flags);
2359        } catch (RuntimeException e) {
2360            // The activity manager only throws security exceptions, so let's
2361            // log all others.
2362            if (!(e instanceof SecurityException)) {
2363                Slog.wtf(TAG, "Activity Manager Crash", e);
2364            }
2365            throw e;
2366        }
2367    }
2368
2369    void updateCpuStats() {
2370        final long now = SystemClock.uptimeMillis();
2371        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2372            return;
2373        }
2374        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2375            synchronized (mProcessCpuThread) {
2376                mProcessCpuThread.notify();
2377            }
2378        }
2379    }
2380
2381    void updateCpuStatsNow() {
2382        synchronized (mProcessCpuThread) {
2383            mProcessCpuMutexFree.set(false);
2384            final long now = SystemClock.uptimeMillis();
2385            boolean haveNewCpuStats = false;
2386
2387            if (MONITOR_CPU_USAGE &&
2388                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2389                mLastCpuTime.set(now);
2390                haveNewCpuStats = true;
2391                mProcessCpuTracker.update();
2392                //Slog.i(TAG, mProcessCpu.printCurrentState());
2393                //Slog.i(TAG, "Total CPU usage: "
2394                //        + mProcessCpu.getTotalCpuPercent() + "%");
2395
2396                // Slog the cpu usage if the property is set.
2397                if ("true".equals(SystemProperties.get("events.cpu"))) {
2398                    int user = mProcessCpuTracker.getLastUserTime();
2399                    int system = mProcessCpuTracker.getLastSystemTime();
2400                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2401                    int irq = mProcessCpuTracker.getLastIrqTime();
2402                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2403                    int idle = mProcessCpuTracker.getLastIdleTime();
2404
2405                    int total = user + system + iowait + irq + softIrq + idle;
2406                    if (total == 0) total = 1;
2407
2408                    EventLog.writeEvent(EventLogTags.CPU,
2409                            ((user+system+iowait+irq+softIrq) * 100) / total,
2410                            (user * 100) / total,
2411                            (system * 100) / total,
2412                            (iowait * 100) / total,
2413                            (irq * 100) / total,
2414                            (softIrq * 100) / total);
2415                }
2416            }
2417
2418            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2419            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2420            synchronized(bstats) {
2421                synchronized(mPidsSelfLocked) {
2422                    if (haveNewCpuStats) {
2423                        if (mOnBattery) {
2424                            int perc = bstats.startAddingCpuLocked();
2425                            int totalUTime = 0;
2426                            int totalSTime = 0;
2427                            final int N = mProcessCpuTracker.countStats();
2428                            for (int i=0; i<N; i++) {
2429                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2430                                if (!st.working) {
2431                                    continue;
2432                                }
2433                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2434                                int otherUTime = (st.rel_utime*perc)/100;
2435                                int otherSTime = (st.rel_stime*perc)/100;
2436                                totalUTime += otherUTime;
2437                                totalSTime += otherSTime;
2438                                if (pr != null) {
2439                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2440                                    if (ps == null || !ps.isActive()) {
2441                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2442                                                pr.info.uid, pr.processName);
2443                                    }
2444                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2445                                            st.rel_stime-otherSTime);
2446                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2447                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2448                                } else {
2449                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2450                                    if (ps == null || !ps.isActive()) {
2451                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2452                                                bstats.mapUid(st.uid), st.name);
2453                                    }
2454                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2455                                            st.rel_stime-otherSTime);
2456                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2457                                }
2458                            }
2459                            bstats.finishAddingCpuLocked(perc, totalUTime,
2460                                    totalSTime, cpuSpeedTimes);
2461                        }
2462                    }
2463                }
2464
2465                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2466                    mLastWriteTime = now;
2467                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2468                }
2469            }
2470        }
2471    }
2472
2473    @Override
2474    public void batteryNeedsCpuUpdate() {
2475        updateCpuStatsNow();
2476    }
2477
2478    @Override
2479    public void batteryPowerChanged(boolean onBattery) {
2480        // When plugging in, update the CPU stats first before changing
2481        // the plug state.
2482        updateCpuStatsNow();
2483        synchronized (this) {
2484            synchronized(mPidsSelfLocked) {
2485                mOnBattery = DEBUG_POWER ? true : onBattery;
2486            }
2487        }
2488    }
2489
2490    /**
2491     * Initialize the application bind args. These are passed to each
2492     * process when the bindApplication() IPC is sent to the process. They're
2493     * lazily setup to make sure the services are running when they're asked for.
2494     */
2495    private HashMap<String, IBinder> getCommonServicesLocked() {
2496        if (mAppBindArgs == null) {
2497            mAppBindArgs = new HashMap<String, IBinder>();
2498
2499            // Setup the application init args
2500            mAppBindArgs.put("package", ServiceManager.getService("package"));
2501            mAppBindArgs.put("window", ServiceManager.getService("window"));
2502            mAppBindArgs.put(Context.ALARM_SERVICE,
2503                    ServiceManager.getService(Context.ALARM_SERVICE));
2504        }
2505        return mAppBindArgs;
2506    }
2507
2508    final void setFocusedActivityLocked(ActivityRecord r) {
2509        if (mFocusedActivity != r) {
2510            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2511            mFocusedActivity = r;
2512            if (r.task != null && r.task.voiceInteractor != null) {
2513                startRunningVoiceLocked();
2514            } else {
2515                finishRunningVoiceLocked();
2516            }
2517            mStackSupervisor.setFocusedStack(r);
2518            if (r != null) {
2519                mWindowManager.setFocusedApp(r.appToken, true);
2520            }
2521            applyUpdateLockStateLocked(r);
2522        }
2523    }
2524
2525    final void clearFocusedActivity(ActivityRecord r) {
2526        if (mFocusedActivity == r) {
2527            mFocusedActivity = null;
2528        }
2529    }
2530
2531    @Override
2532    public void setFocusedStack(int stackId) {
2533        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2534        synchronized (ActivityManagerService.this) {
2535            ActivityStack stack = mStackSupervisor.getStack(stackId);
2536            if (stack != null) {
2537                ActivityRecord r = stack.topRunningActivityLocked(null);
2538                if (r != null) {
2539                    setFocusedActivityLocked(r);
2540                }
2541            }
2542        }
2543    }
2544
2545    @Override
2546    public void notifyActivityDrawn(IBinder token) {
2547        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2548        synchronized (this) {
2549            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2550            if (r != null) {
2551                r.task.stack.notifyActivityDrawnLocked(r);
2552            }
2553        }
2554    }
2555
2556    final void applyUpdateLockStateLocked(ActivityRecord r) {
2557        // Modifications to the UpdateLock state are done on our handler, outside
2558        // the activity manager's locks.  The new state is determined based on the
2559        // state *now* of the relevant activity record.  The object is passed to
2560        // the handler solely for logging detail, not to be consulted/modified.
2561        final boolean nextState = r != null && r.immersive;
2562        mHandler.sendMessage(
2563                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2564    }
2565
2566    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2567        Message msg = Message.obtain();
2568        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2569        msg.obj = r.task.askedCompatMode ? null : r;
2570        mHandler.sendMessage(msg);
2571    }
2572
2573    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2574            String what, Object obj, ProcessRecord srcApp) {
2575        app.lastActivityTime = now;
2576
2577        if (app.activities.size() > 0) {
2578            // Don't want to touch dependent processes that are hosting activities.
2579            return index;
2580        }
2581
2582        int lrui = mLruProcesses.lastIndexOf(app);
2583        if (lrui < 0) {
2584            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2585                    + what + " " + obj + " from " + srcApp);
2586            return index;
2587        }
2588
2589        if (lrui >= index) {
2590            // Don't want to cause this to move dependent processes *back* in the
2591            // list as if they were less frequently used.
2592            return index;
2593        }
2594
2595        if (lrui >= mLruProcessActivityStart) {
2596            // Don't want to touch dependent processes that are hosting activities.
2597            return index;
2598        }
2599
2600        mLruProcesses.remove(lrui);
2601        if (index > 0) {
2602            index--;
2603        }
2604        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2605                + " in LRU list: " + app);
2606        mLruProcesses.add(index, app);
2607        return index;
2608    }
2609
2610    final void removeLruProcessLocked(ProcessRecord app) {
2611        int lrui = mLruProcesses.lastIndexOf(app);
2612        if (lrui >= 0) {
2613            if (lrui <= mLruProcessActivityStart) {
2614                mLruProcessActivityStart--;
2615            }
2616            if (lrui <= mLruProcessServiceStart) {
2617                mLruProcessServiceStart--;
2618            }
2619            mLruProcesses.remove(lrui);
2620        }
2621    }
2622
2623    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2624            ProcessRecord client) {
2625        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2626                || app.treatLikeActivity;
2627        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2628        if (!activityChange && hasActivity) {
2629            // The process has activities, so we are only allowing activity-based adjustments
2630            // to move it.  It should be kept in the front of the list with other
2631            // processes that have activities, and we don't want those to change their
2632            // order except due to activity operations.
2633            return;
2634        }
2635
2636        mLruSeq++;
2637        final long now = SystemClock.uptimeMillis();
2638        app.lastActivityTime = now;
2639
2640        // First a quick reject: if the app is already at the position we will
2641        // put it, then there is nothing to do.
2642        if (hasActivity) {
2643            final int N = mLruProcesses.size();
2644            if (N > 0 && mLruProcesses.get(N-1) == app) {
2645                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2646                return;
2647            }
2648        } else {
2649            if (mLruProcessServiceStart > 0
2650                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2651                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2652                return;
2653            }
2654        }
2655
2656        int lrui = mLruProcesses.lastIndexOf(app);
2657
2658        if (app.persistent && lrui >= 0) {
2659            // We don't care about the position of persistent processes, as long as
2660            // they are in the list.
2661            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2662            return;
2663        }
2664
2665        /* In progress: compute new position first, so we can avoid doing work
2666           if the process is not actually going to move.  Not yet working.
2667        int addIndex;
2668        int nextIndex;
2669        boolean inActivity = false, inService = false;
2670        if (hasActivity) {
2671            // Process has activities, put it at the very tipsy-top.
2672            addIndex = mLruProcesses.size();
2673            nextIndex = mLruProcessServiceStart;
2674            inActivity = true;
2675        } else if (hasService) {
2676            // Process has services, put it at the top of the service list.
2677            addIndex = mLruProcessActivityStart;
2678            nextIndex = mLruProcessServiceStart;
2679            inActivity = true;
2680            inService = true;
2681        } else  {
2682            // Process not otherwise of interest, it goes to the top of the non-service area.
2683            addIndex = mLruProcessServiceStart;
2684            if (client != null) {
2685                int clientIndex = mLruProcesses.lastIndexOf(client);
2686                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2687                        + app);
2688                if (clientIndex >= 0 && addIndex > clientIndex) {
2689                    addIndex = clientIndex;
2690                }
2691            }
2692            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2693        }
2694
2695        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2696                + mLruProcessActivityStart + "): " + app);
2697        */
2698
2699        if (lrui >= 0) {
2700            if (lrui < mLruProcessActivityStart) {
2701                mLruProcessActivityStart--;
2702            }
2703            if (lrui < mLruProcessServiceStart) {
2704                mLruProcessServiceStart--;
2705            }
2706            /*
2707            if (addIndex > lrui) {
2708                addIndex--;
2709            }
2710            if (nextIndex > lrui) {
2711                nextIndex--;
2712            }
2713            */
2714            mLruProcesses.remove(lrui);
2715        }
2716
2717        /*
2718        mLruProcesses.add(addIndex, app);
2719        if (inActivity) {
2720            mLruProcessActivityStart++;
2721        }
2722        if (inService) {
2723            mLruProcessActivityStart++;
2724        }
2725        */
2726
2727        int nextIndex;
2728        if (hasActivity) {
2729            final int N = mLruProcesses.size();
2730            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2731                // Process doesn't have activities, but has clients with
2732                // activities...  move it up, but one below the top (the top
2733                // should always have a real activity).
2734                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2735                mLruProcesses.add(N-1, app);
2736                // To keep it from spamming the LRU list (by making a bunch of clients),
2737                // we will push down any other entries owned by the app.
2738                final int uid = app.info.uid;
2739                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2740                    ProcessRecord subProc = mLruProcesses.get(i);
2741                    if (subProc.info.uid == uid) {
2742                        // We want to push this one down the list.  If the process after
2743                        // it is for the same uid, however, don't do so, because we don't
2744                        // want them internally to be re-ordered.
2745                        if (mLruProcesses.get(i-1).info.uid != uid) {
2746                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2747                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2748                            ProcessRecord tmp = mLruProcesses.get(i);
2749                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2750                            mLruProcesses.set(i-1, tmp);
2751                            i--;
2752                        }
2753                    } else {
2754                        // A gap, we can stop here.
2755                        break;
2756                    }
2757                }
2758            } else {
2759                // Process has activities, put it at the very tipsy-top.
2760                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2761                mLruProcesses.add(app);
2762            }
2763            nextIndex = mLruProcessServiceStart;
2764        } else if (hasService) {
2765            // Process has services, put it at the top of the service list.
2766            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2767            mLruProcesses.add(mLruProcessActivityStart, app);
2768            nextIndex = mLruProcessServiceStart;
2769            mLruProcessActivityStart++;
2770        } else  {
2771            // Process not otherwise of interest, it goes to the top of the non-service area.
2772            int index = mLruProcessServiceStart;
2773            if (client != null) {
2774                // If there is a client, don't allow the process to be moved up higher
2775                // in the list than that client.
2776                int clientIndex = mLruProcesses.lastIndexOf(client);
2777                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2778                        + " when updating " + app);
2779                if (clientIndex <= lrui) {
2780                    // Don't allow the client index restriction to push it down farther in the
2781                    // list than it already is.
2782                    clientIndex = lrui;
2783                }
2784                if (clientIndex >= 0 && index > clientIndex) {
2785                    index = clientIndex;
2786                }
2787            }
2788            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2789            mLruProcesses.add(index, app);
2790            nextIndex = index-1;
2791            mLruProcessActivityStart++;
2792            mLruProcessServiceStart++;
2793        }
2794
2795        // If the app is currently using a content provider or service,
2796        // bump those processes as well.
2797        for (int j=app.connections.size()-1; j>=0; j--) {
2798            ConnectionRecord cr = app.connections.valueAt(j);
2799            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2800                    && cr.binding.service.app != null
2801                    && cr.binding.service.app.lruSeq != mLruSeq
2802                    && !cr.binding.service.app.persistent) {
2803                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2804                        "service connection", cr, app);
2805            }
2806        }
2807        for (int j=app.conProviders.size()-1; j>=0; j--) {
2808            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2809            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2810                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2811                        "provider reference", cpr, app);
2812            }
2813        }
2814    }
2815
2816    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2817        if (uid == Process.SYSTEM_UID) {
2818            // The system gets to run in any process.  If there are multiple
2819            // processes with the same uid, just pick the first (this
2820            // should never happen).
2821            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2822            if (procs == null) return null;
2823            final int N = procs.size();
2824            for (int i = 0; i < N; i++) {
2825                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2826            }
2827        }
2828        ProcessRecord proc = mProcessNames.get(processName, uid);
2829        if (false && proc != null && !keepIfLarge
2830                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2831                && proc.lastCachedPss >= 4000) {
2832            // Turn this condition on to cause killing to happen regularly, for testing.
2833            if (proc.baseProcessTracker != null) {
2834                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2835            }
2836            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2837        } else if (proc != null && !keepIfLarge
2838                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2839                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2840            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2841            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2842                if (proc.baseProcessTracker != null) {
2843                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2844                }
2845                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2846            }
2847        }
2848        return proc;
2849    }
2850
2851    void ensurePackageDexOpt(String packageName) {
2852        IPackageManager pm = AppGlobals.getPackageManager();
2853        try {
2854            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2855                mDidDexOpt = true;
2856            }
2857        } catch (RemoteException e) {
2858        }
2859    }
2860
2861    boolean isNextTransitionForward() {
2862        int transit = mWindowManager.getPendingAppTransition();
2863        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2864                || transit == AppTransition.TRANSIT_TASK_OPEN
2865                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2866    }
2867
2868    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2869            String processName, String abiOverride, int uid, Runnable crashHandler) {
2870        synchronized(this) {
2871            ApplicationInfo info = new ApplicationInfo();
2872            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2873            // For isolated processes, the former contains the parent's uid and the latter the
2874            // actual uid of the isolated process.
2875            // In the special case introduced by this method (which is, starting an isolated
2876            // process directly from the SystemServer without an actual parent app process) the
2877            // closest thing to a parent's uid is SYSTEM_UID.
2878            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2879            // the |isolated| logic in the ProcessRecord constructor.
2880            info.uid = Process.SYSTEM_UID;
2881            info.processName = processName;
2882            info.className = entryPoint;
2883            info.packageName = "android";
2884            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2885                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2886                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2887                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2888                    crashHandler);
2889            return proc != null ? proc.pid : 0;
2890        }
2891    }
2892
2893    final ProcessRecord startProcessLocked(String processName,
2894            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2895            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2896            boolean isolated, boolean keepIfLarge) {
2897        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2898                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2899                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2900                null /* crashHandler */);
2901    }
2902
2903    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2904            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2905            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2906            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2907        long startTime = SystemClock.elapsedRealtime();
2908        ProcessRecord app;
2909        if (!isolated) {
2910            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2911            checkTime(startTime, "startProcess: after getProcessRecord");
2912        } else {
2913            // If this is an isolated process, it can't re-use an existing process.
2914            app = null;
2915        }
2916        // We don't have to do anything more if:
2917        // (1) There is an existing application record; and
2918        // (2) The caller doesn't think it is dead, OR there is no thread
2919        //     object attached to it so we know it couldn't have crashed; and
2920        // (3) There is a pid assigned to it, so it is either starting or
2921        //     already running.
2922        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2923                + " app=" + app + " knownToBeDead=" + knownToBeDead
2924                + " thread=" + (app != null ? app.thread : null)
2925                + " pid=" + (app != null ? app.pid : -1));
2926        if (app != null && app.pid > 0) {
2927            if (!knownToBeDead || app.thread == null) {
2928                // We already have the app running, or are waiting for it to
2929                // come up (we have a pid but not yet its thread), so keep it.
2930                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2931                // If this is a new package in the process, add the package to the list
2932                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2933                checkTime(startTime, "startProcess: done, added package to proc");
2934                return app;
2935            }
2936
2937            // An application record is attached to a previous process,
2938            // clean it up now.
2939            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2940            checkTime(startTime, "startProcess: bad proc running, killing");
2941            Process.killProcessGroup(app.info.uid, app.pid);
2942            handleAppDiedLocked(app, true, true);
2943            checkTime(startTime, "startProcess: done killing old proc");
2944        }
2945
2946        String hostingNameStr = hostingName != null
2947                ? hostingName.flattenToShortString() : null;
2948
2949        if (!isolated) {
2950            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2951                // If we are in the background, then check to see if this process
2952                // is bad.  If so, we will just silently fail.
2953                if (mBadProcesses.get(info.processName, info.uid) != null) {
2954                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2955                            + "/" + info.processName);
2956                    return null;
2957                }
2958            } else {
2959                // When the user is explicitly starting a process, then clear its
2960                // crash count so that we won't make it bad until they see at
2961                // least one crash dialog again, and make the process good again
2962                // if it had been bad.
2963                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2964                        + "/" + info.processName);
2965                mProcessCrashTimes.remove(info.processName, info.uid);
2966                if (mBadProcesses.get(info.processName, info.uid) != null) {
2967                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2968                            UserHandle.getUserId(info.uid), info.uid,
2969                            info.processName);
2970                    mBadProcesses.remove(info.processName, info.uid);
2971                    if (app != null) {
2972                        app.bad = false;
2973                    }
2974                }
2975            }
2976        }
2977
2978        if (app == null) {
2979            checkTime(startTime, "startProcess: creating new process record");
2980            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2981            app.crashHandler = crashHandler;
2982            if (app == null) {
2983                Slog.w(TAG, "Failed making new process record for "
2984                        + processName + "/" + info.uid + " isolated=" + isolated);
2985                return null;
2986            }
2987            mProcessNames.put(processName, app.uid, app);
2988            if (isolated) {
2989                mIsolatedProcesses.put(app.uid, app);
2990            }
2991            checkTime(startTime, "startProcess: done creating new process record");
2992        } else {
2993            // If this is a new package in the process, add the package to the list
2994            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2995            checkTime(startTime, "startProcess: added package to existing proc");
2996        }
2997
2998        // If the system is not ready yet, then hold off on starting this
2999        // process until it is.
3000        if (!mProcessesReady
3001                && !isAllowedWhileBooting(info)
3002                && !allowWhileBooting) {
3003            if (!mProcessesOnHold.contains(app)) {
3004                mProcessesOnHold.add(app);
3005            }
3006            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
3007            checkTime(startTime, "startProcess: returning with proc on hold");
3008            return app;
3009        }
3010
3011        checkTime(startTime, "startProcess: stepping in to startProcess");
3012        startProcessLocked(
3013                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3014        checkTime(startTime, "startProcess: done starting proc!");
3015        return (app.pid != 0) ? app : null;
3016    }
3017
3018    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3019        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3020    }
3021
3022    private final void startProcessLocked(ProcessRecord app,
3023            String hostingType, String hostingNameStr) {
3024        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3025                null /* entryPoint */, null /* entryPointArgs */);
3026    }
3027
3028    private final void startProcessLocked(ProcessRecord app, String hostingType,
3029            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3030        long startTime = SystemClock.elapsedRealtime();
3031        if (app.pid > 0 && app.pid != MY_PID) {
3032            checkTime(startTime, "startProcess: removing from pids map");
3033            synchronized (mPidsSelfLocked) {
3034                mPidsSelfLocked.remove(app.pid);
3035                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3036            }
3037            checkTime(startTime, "startProcess: done removing from pids map");
3038            app.setPid(0);
3039        }
3040
3041        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3042                "startProcessLocked removing on hold: " + app);
3043        mProcessesOnHold.remove(app);
3044
3045        checkTime(startTime, "startProcess: starting to update cpu stats");
3046        updateCpuStats();
3047        checkTime(startTime, "startProcess: done updating cpu stats");
3048
3049        try {
3050            int uid = app.uid;
3051
3052            int[] gids = null;
3053            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3054            if (!app.isolated) {
3055                int[] permGids = null;
3056                try {
3057                    checkTime(startTime, "startProcess: getting gids from package manager");
3058                    final PackageManager pm = mContext.getPackageManager();
3059                    permGids = pm.getPackageGids(app.info.packageName);
3060
3061                    if (Environment.isExternalStorageEmulated()) {
3062                        checkTime(startTime, "startProcess: checking external storage perm");
3063                        if (pm.checkPermission(
3064                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3065                                app.info.packageName) == PERMISSION_GRANTED) {
3066                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3067                        } else {
3068                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3069                        }
3070                    }
3071                } catch (PackageManager.NameNotFoundException e) {
3072                    Slog.w(TAG, "Unable to retrieve gids", e);
3073                }
3074
3075                /*
3076                 * Add shared application and profile GIDs so applications can share some
3077                 * resources like shared libraries and access user-wide resources
3078                 */
3079                if (permGids == null) {
3080                    gids = new int[2];
3081                } else {
3082                    gids = new int[permGids.length + 2];
3083                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3084                }
3085                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3086                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3087            }
3088            checkTime(startTime, "startProcess: building args");
3089            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3090                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3091                        && mTopComponent != null
3092                        && app.processName.equals(mTopComponent.getPackageName())) {
3093                    uid = 0;
3094                }
3095                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3096                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3097                    uid = 0;
3098                }
3099            }
3100            int debugFlags = 0;
3101            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3102                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3103                // Also turn on CheckJNI for debuggable apps. It's quite
3104                // awkward to turn on otherwise.
3105                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3106            }
3107            // Run the app in safe mode if its manifest requests so or the
3108            // system is booted in safe mode.
3109            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3110                mSafeMode == true) {
3111                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3112            }
3113            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3114                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3115            }
3116            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3117                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3118            }
3119            if ("1".equals(SystemProperties.get("debug.assert"))) {
3120                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3121            }
3122
3123            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3124            if (requiredAbi == null) {
3125                requiredAbi = Build.SUPPORTED_ABIS[0];
3126            }
3127
3128            String instructionSet = null;
3129            if (app.info.primaryCpuAbi != null) {
3130                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3131            }
3132
3133            // Start the process.  It will either succeed and return a result containing
3134            // the PID of the new process, or else throw a RuntimeException.
3135            boolean isActivityProcess = (entryPoint == null);
3136            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3137            checkTime(startTime, "startProcess: asking zygote to start proc");
3138            Process.ProcessStartResult startResult = Process.start(entryPoint,
3139                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3140                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3141                    entryPointArgs);
3142            checkTime(startTime, "startProcess: returned from zygote!");
3143
3144            if (app.isolated) {
3145                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3146            }
3147            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3148            checkTime(startTime, "startProcess: done updating battery stats");
3149
3150            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3151                    UserHandle.getUserId(uid), startResult.pid, uid,
3152                    app.processName, hostingType,
3153                    hostingNameStr != null ? hostingNameStr : "");
3154
3155            if (app.persistent) {
3156                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3157            }
3158
3159            checkTime(startTime, "startProcess: building log message");
3160            StringBuilder buf = mStringBuilder;
3161            buf.setLength(0);
3162            buf.append("Start proc ");
3163            buf.append(app.processName);
3164            if (!isActivityProcess) {
3165                buf.append(" [");
3166                buf.append(entryPoint);
3167                buf.append("]");
3168            }
3169            buf.append(" for ");
3170            buf.append(hostingType);
3171            if (hostingNameStr != null) {
3172                buf.append(" ");
3173                buf.append(hostingNameStr);
3174            }
3175            buf.append(": pid=");
3176            buf.append(startResult.pid);
3177            buf.append(" uid=");
3178            buf.append(uid);
3179            buf.append(" gids={");
3180            if (gids != null) {
3181                for (int gi=0; gi<gids.length; gi++) {
3182                    if (gi != 0) buf.append(", ");
3183                    buf.append(gids[gi]);
3184
3185                }
3186            }
3187            buf.append("}");
3188            if (requiredAbi != null) {
3189                buf.append(" abi=");
3190                buf.append(requiredAbi);
3191            }
3192            Slog.i(TAG, buf.toString());
3193            app.setPid(startResult.pid);
3194            app.usingWrapper = startResult.usingWrapper;
3195            app.removed = false;
3196            app.killedByAm = false;
3197            checkTime(startTime, "startProcess: starting to update pids map");
3198            synchronized (mPidsSelfLocked) {
3199                this.mPidsSelfLocked.put(startResult.pid, app);
3200                if (isActivityProcess) {
3201                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3202                    msg.obj = app;
3203                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3204                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3205                }
3206            }
3207            checkTime(startTime, "startProcess: done updating pids map");
3208        } catch (RuntimeException e) {
3209            // XXX do better error recovery.
3210            app.setPid(0);
3211            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3212            if (app.isolated) {
3213                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3214            }
3215            Slog.e(TAG, "Failure starting process " + app.processName, e);
3216        }
3217    }
3218
3219    void updateUsageStats(ActivityRecord component, boolean resumed) {
3220        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3221        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3222        if (resumed) {
3223            if (mUsageStatsService != null) {
3224                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3225                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3226            }
3227            synchronized (stats) {
3228                stats.noteActivityResumedLocked(component.app.uid);
3229            }
3230        } else {
3231            if (mUsageStatsService != null) {
3232                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3233                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3234            }
3235            synchronized (stats) {
3236                stats.noteActivityPausedLocked(component.app.uid);
3237            }
3238        }
3239    }
3240
3241    Intent getHomeIntent() {
3242        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3243        intent.setComponent(mTopComponent);
3244        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3245            intent.addCategory(Intent.CATEGORY_HOME);
3246        }
3247        return intent;
3248    }
3249
3250    boolean startHomeActivityLocked(int userId) {
3251        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3252                && mTopAction == null) {
3253            // We are running in factory test mode, but unable to find
3254            // the factory test app, so just sit around displaying the
3255            // error message and don't try to start anything.
3256            return false;
3257        }
3258        Intent intent = getHomeIntent();
3259        ActivityInfo aInfo =
3260            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3261        if (aInfo != null) {
3262            intent.setComponent(new ComponentName(
3263                    aInfo.applicationInfo.packageName, aInfo.name));
3264            // Don't do this if the home app is currently being
3265            // instrumented.
3266            aInfo = new ActivityInfo(aInfo);
3267            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3268            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3269                    aInfo.applicationInfo.uid, true);
3270            if (app == null || app.instrumentationClass == null) {
3271                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3272                mStackSupervisor.startHomeActivity(intent, aInfo);
3273            }
3274        }
3275
3276        return true;
3277    }
3278
3279    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3280        ActivityInfo ai = null;
3281        ComponentName comp = intent.getComponent();
3282        try {
3283            if (comp != null) {
3284                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3285            } else {
3286                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3287                        intent,
3288                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3289                            flags, userId);
3290
3291                if (info != null) {
3292                    ai = info.activityInfo;
3293                }
3294            }
3295        } catch (RemoteException e) {
3296            // ignore
3297        }
3298
3299        return ai;
3300    }
3301
3302    /**
3303     * Starts the "new version setup screen" if appropriate.
3304     */
3305    void startSetupActivityLocked() {
3306        // Only do this once per boot.
3307        if (mCheckedForSetup) {
3308            return;
3309        }
3310
3311        // We will show this screen if the current one is a different
3312        // version than the last one shown, and we are not running in
3313        // low-level factory test mode.
3314        final ContentResolver resolver = mContext.getContentResolver();
3315        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3316                Settings.Global.getInt(resolver,
3317                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3318            mCheckedForSetup = true;
3319
3320            // See if we should be showing the platform update setup UI.
3321            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3322            List<ResolveInfo> ris = mContext.getPackageManager()
3323                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3324
3325            // We don't allow third party apps to replace this.
3326            ResolveInfo ri = null;
3327            for (int i=0; ris != null && i<ris.size(); i++) {
3328                if ((ris.get(i).activityInfo.applicationInfo.flags
3329                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3330                    ri = ris.get(i);
3331                    break;
3332                }
3333            }
3334
3335            if (ri != null) {
3336                String vers = ri.activityInfo.metaData != null
3337                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3338                        : null;
3339                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3340                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3341                            Intent.METADATA_SETUP_VERSION);
3342                }
3343                String lastVers = Settings.Secure.getString(
3344                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3345                if (vers != null && !vers.equals(lastVers)) {
3346                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3347                    intent.setComponent(new ComponentName(
3348                            ri.activityInfo.packageName, ri.activityInfo.name));
3349                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3350                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null,
3351                            null);
3352                }
3353            }
3354        }
3355    }
3356
3357    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3358        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3359    }
3360
3361    void enforceNotIsolatedCaller(String caller) {
3362        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3363            throw new SecurityException("Isolated process not allowed to call " + caller);
3364        }
3365    }
3366
3367    @Override
3368    public int getFrontActivityScreenCompatMode() {
3369        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3370        synchronized (this) {
3371            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3372        }
3373    }
3374
3375    @Override
3376    public void setFrontActivityScreenCompatMode(int mode) {
3377        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3378                "setFrontActivityScreenCompatMode");
3379        synchronized (this) {
3380            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3381        }
3382    }
3383
3384    @Override
3385    public int getPackageScreenCompatMode(String packageName) {
3386        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3387        synchronized (this) {
3388            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3389        }
3390    }
3391
3392    @Override
3393    public void setPackageScreenCompatMode(String packageName, int mode) {
3394        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3395                "setPackageScreenCompatMode");
3396        synchronized (this) {
3397            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3398        }
3399    }
3400
3401    @Override
3402    public boolean getPackageAskScreenCompat(String packageName) {
3403        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3404        synchronized (this) {
3405            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3406        }
3407    }
3408
3409    @Override
3410    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3411        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3412                "setPackageAskScreenCompat");
3413        synchronized (this) {
3414            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3415        }
3416    }
3417
3418    private void dispatchProcessesChanged() {
3419        int N;
3420        synchronized (this) {
3421            N = mPendingProcessChanges.size();
3422            if (mActiveProcessChanges.length < N) {
3423                mActiveProcessChanges = new ProcessChangeItem[N];
3424            }
3425            mPendingProcessChanges.toArray(mActiveProcessChanges);
3426            mAvailProcessChanges.addAll(mPendingProcessChanges);
3427            mPendingProcessChanges.clear();
3428            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3429        }
3430
3431        int i = mProcessObservers.beginBroadcast();
3432        while (i > 0) {
3433            i--;
3434            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3435            if (observer != null) {
3436                try {
3437                    for (int j=0; j<N; j++) {
3438                        ProcessChangeItem item = mActiveProcessChanges[j];
3439                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3440                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3441                                    + item.pid + " uid=" + item.uid + ": "
3442                                    + item.foregroundActivities);
3443                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3444                                    item.foregroundActivities);
3445                        }
3446                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3447                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3448                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3449                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3450                        }
3451                    }
3452                } catch (RemoteException e) {
3453                }
3454            }
3455        }
3456        mProcessObservers.finishBroadcast();
3457    }
3458
3459    private void dispatchProcessDied(int pid, int uid) {
3460        int i = mProcessObservers.beginBroadcast();
3461        while (i > 0) {
3462            i--;
3463            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3464            if (observer != null) {
3465                try {
3466                    observer.onProcessDied(pid, uid);
3467                } catch (RemoteException e) {
3468                }
3469            }
3470        }
3471        mProcessObservers.finishBroadcast();
3472    }
3473
3474    @Override
3475    public final int startActivity(IApplicationThread caller, String callingPackage,
3476            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3477            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3478        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3479            resultWho, requestCode, startFlags, profilerInfo, options,
3480            UserHandle.getCallingUserId());
3481    }
3482
3483    @Override
3484    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3485            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3486            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3487        enforceNotIsolatedCaller("startActivity");
3488        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3489                false, ALLOW_FULL_ONLY, "startActivity", null);
3490        // TODO: Switch to user app stacks here.
3491        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3492                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3493                profilerInfo, null, null, options, userId, null, null);
3494    }
3495
3496    @Override
3497    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3498            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3499            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3500
3501        // This is very dangerous -- it allows you to perform a start activity (including
3502        // permission grants) as any app that may launch one of your own activities.  So
3503        // we will only allow this to be done from activities that are part of the core framework,
3504        // and then only when they are running as the system.
3505        final ActivityRecord sourceRecord;
3506        final int targetUid;
3507        final String targetPackage;
3508        synchronized (this) {
3509            if (resultTo == null) {
3510                throw new SecurityException("Must be called from an activity");
3511            }
3512            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3513            if (sourceRecord == null) {
3514                throw new SecurityException("Called with bad activity token: " + resultTo);
3515            }
3516            if (!sourceRecord.info.packageName.equals("android")) {
3517                throw new SecurityException(
3518                        "Must be called from an activity that is declared in the android package");
3519            }
3520            if (sourceRecord.app == null) {
3521                throw new SecurityException("Called without a process attached to activity");
3522            }
3523            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3524                // This is still okay, as long as this activity is running under the
3525                // uid of the original calling activity.
3526                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3527                    throw new SecurityException(
3528                            "Calling activity in uid " + sourceRecord.app.uid
3529                                    + " must be system uid or original calling uid "
3530                                    + sourceRecord.launchedFromUid);
3531                }
3532            }
3533            targetUid = sourceRecord.launchedFromUid;
3534            targetPackage = sourceRecord.launchedFromPackage;
3535        }
3536
3537        // TODO: Switch to user app stacks here.
3538        try {
3539            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3540                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3541                    null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null);
3542            return ret;
3543        } catch (SecurityException e) {
3544            // XXX need to figure out how to propagate to original app.
3545            // A SecurityException here is generally actually a fault of the original
3546            // calling activity (such as a fairly granting permissions), so propagate it
3547            // back to them.
3548            /*
3549            StringBuilder msg = new StringBuilder();
3550            msg.append("While launching");
3551            msg.append(intent.toString());
3552            msg.append(": ");
3553            msg.append(e.getMessage());
3554            */
3555            throw e;
3556        }
3557    }
3558
3559    @Override
3560    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3561            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3562            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3563        enforceNotIsolatedCaller("startActivityAndWait");
3564        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3565                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3566        WaitResult res = new WaitResult();
3567        // TODO: Switch to user app stacks here.
3568        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3569                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3570                options, userId, null, null);
3571        return res;
3572    }
3573
3574    @Override
3575    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3576            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3577            int startFlags, Configuration config, Bundle options, int userId) {
3578        enforceNotIsolatedCaller("startActivityWithConfig");
3579        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3580                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3581        // TODO: Switch to user app stacks here.
3582        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3583                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3584                null, null, config, options, userId, null, null);
3585        return ret;
3586    }
3587
3588    @Override
3589    public int startActivityIntentSender(IApplicationThread caller,
3590            IntentSender intent, Intent fillInIntent, String resolvedType,
3591            IBinder resultTo, String resultWho, int requestCode,
3592            int flagsMask, int flagsValues, Bundle options) {
3593        enforceNotIsolatedCaller("startActivityIntentSender");
3594        // Refuse possible leaked file descriptors
3595        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3596            throw new IllegalArgumentException("File descriptors passed in Intent");
3597        }
3598
3599        IIntentSender sender = intent.getTarget();
3600        if (!(sender instanceof PendingIntentRecord)) {
3601            throw new IllegalArgumentException("Bad PendingIntent object");
3602        }
3603
3604        PendingIntentRecord pir = (PendingIntentRecord)sender;
3605
3606        synchronized (this) {
3607            // If this is coming from the currently resumed activity, it is
3608            // effectively saying that app switches are allowed at this point.
3609            final ActivityStack stack = getFocusedStack();
3610            if (stack.mResumedActivity != null &&
3611                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3612                mAppSwitchesAllowedTime = 0;
3613            }
3614        }
3615        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3616                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3617        return ret;
3618    }
3619
3620    @Override
3621    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3622            Intent intent, String resolvedType, IVoiceInteractionSession session,
3623            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3624            Bundle options, int userId) {
3625        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3626                != PackageManager.PERMISSION_GRANTED) {
3627            String msg = "Permission Denial: startVoiceActivity() from pid="
3628                    + Binder.getCallingPid()
3629                    + ", uid=" + Binder.getCallingUid()
3630                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3631            Slog.w(TAG, msg);
3632            throw new SecurityException(msg);
3633        }
3634        if (session == null || interactor == null) {
3635            throw new NullPointerException("null session or interactor");
3636        }
3637        userId = handleIncomingUser(callingPid, callingUid, userId,
3638                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3639        // TODO: Switch to user app stacks here.
3640        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3641                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3642                null, options, userId, null, null);
3643    }
3644
3645    @Override
3646    public boolean startNextMatchingActivity(IBinder callingActivity,
3647            Intent intent, Bundle options) {
3648        // Refuse possible leaked file descriptors
3649        if (intent != null && intent.hasFileDescriptors() == true) {
3650            throw new IllegalArgumentException("File descriptors passed in Intent");
3651        }
3652
3653        synchronized (this) {
3654            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3655            if (r == null) {
3656                ActivityOptions.abort(options);
3657                return false;
3658            }
3659            if (r.app == null || r.app.thread == null) {
3660                // The caller is not running...  d'oh!
3661                ActivityOptions.abort(options);
3662                return false;
3663            }
3664            intent = new Intent(intent);
3665            // The caller is not allowed to change the data.
3666            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3667            // And we are resetting to find the next component...
3668            intent.setComponent(null);
3669
3670            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3671
3672            ActivityInfo aInfo = null;
3673            try {
3674                List<ResolveInfo> resolves =
3675                    AppGlobals.getPackageManager().queryIntentActivities(
3676                            intent, r.resolvedType,
3677                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3678                            UserHandle.getCallingUserId());
3679
3680                // Look for the original activity in the list...
3681                final int N = resolves != null ? resolves.size() : 0;
3682                for (int i=0; i<N; i++) {
3683                    ResolveInfo rInfo = resolves.get(i);
3684                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3685                            && rInfo.activityInfo.name.equals(r.info.name)) {
3686                        // We found the current one...  the next matching is
3687                        // after it.
3688                        i++;
3689                        if (i<N) {
3690                            aInfo = resolves.get(i).activityInfo;
3691                        }
3692                        if (debug) {
3693                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3694                                    + "/" + r.info.name);
3695                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3696                                    + "/" + aInfo.name);
3697                        }
3698                        break;
3699                    }
3700                }
3701            } catch (RemoteException e) {
3702            }
3703
3704            if (aInfo == null) {
3705                // Nobody who is next!
3706                ActivityOptions.abort(options);
3707                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3708                return false;
3709            }
3710
3711            intent.setComponent(new ComponentName(
3712                    aInfo.applicationInfo.packageName, aInfo.name));
3713            intent.setFlags(intent.getFlags()&~(
3714                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3715                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3716                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3717                    Intent.FLAG_ACTIVITY_NEW_TASK));
3718
3719            // Okay now we need to start the new activity, replacing the
3720            // currently running activity.  This is a little tricky because
3721            // we want to start the new one as if the current one is finished,
3722            // but not finish the current one first so that there is no flicker.
3723            // And thus...
3724            final boolean wasFinishing = r.finishing;
3725            r.finishing = true;
3726
3727            // Propagate reply information over to the new activity.
3728            final ActivityRecord resultTo = r.resultTo;
3729            final String resultWho = r.resultWho;
3730            final int requestCode = r.requestCode;
3731            r.resultTo = null;
3732            if (resultTo != null) {
3733                resultTo.removeResultsLocked(r, resultWho, requestCode);
3734            }
3735
3736            final long origId = Binder.clearCallingIdentity();
3737            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3738                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3739                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3740                    options, false, null, null, null);
3741            Binder.restoreCallingIdentity(origId);
3742
3743            r.finishing = wasFinishing;
3744            if (res != ActivityManager.START_SUCCESS) {
3745                return false;
3746            }
3747            return true;
3748        }
3749    }
3750
3751    @Override
3752    public final int startActivityFromRecents(int taskId, Bundle options) {
3753        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3754            String msg = "Permission Denial: startActivityFromRecents called without " +
3755                    START_TASKS_FROM_RECENTS;
3756            Slog.w(TAG, msg);
3757            throw new SecurityException(msg);
3758        }
3759        return startActivityFromRecentsInner(taskId, options);
3760    }
3761
3762    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3763        final TaskRecord task;
3764        final int callingUid;
3765        final String callingPackage;
3766        final Intent intent;
3767        final int userId;
3768        synchronized (this) {
3769            task = recentTaskForIdLocked(taskId);
3770            if (task == null) {
3771                throw new IllegalArgumentException("Task " + taskId + " not found.");
3772            }
3773            callingUid = task.mCallingUid;
3774            callingPackage = task.mCallingPackage;
3775            intent = task.intent;
3776            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3777            userId = task.userId;
3778        }
3779        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3780                options, userId, null, task);
3781    }
3782
3783    final int startActivityInPackage(int uid, String callingPackage,
3784            Intent intent, String resolvedType, IBinder resultTo,
3785            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3786            IActivityContainer container, TaskRecord inTask) {
3787
3788        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3789                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3790
3791        // TODO: Switch to user app stacks here.
3792        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3793                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3794                null, null, null, options, userId, container, inTask);
3795        return ret;
3796    }
3797
3798    @Override
3799    public final int startActivities(IApplicationThread caller, String callingPackage,
3800            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3801            int userId) {
3802        enforceNotIsolatedCaller("startActivities");
3803        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3804                false, ALLOW_FULL_ONLY, "startActivity", null);
3805        // TODO: Switch to user app stacks here.
3806        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3807                resolvedTypes, resultTo, options, userId);
3808        return ret;
3809    }
3810
3811    final int startActivitiesInPackage(int uid, String callingPackage,
3812            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3813            Bundle options, int userId) {
3814
3815        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3816                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3817        // TODO: Switch to user app stacks here.
3818        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3819                resultTo, options, userId);
3820        return ret;
3821    }
3822
3823    //explicitly remove thd old information in mRecentTasks when removing existing user.
3824    private void removeRecentTasksForUserLocked(int userId) {
3825        if(userId <= 0) {
3826            Slog.i(TAG, "Can't remove recent task on user " + userId);
3827            return;
3828        }
3829
3830        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3831            TaskRecord tr = mRecentTasks.get(i);
3832            if (tr.userId == userId) {
3833                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3834                        + " when finishing user" + userId);
3835                mRecentTasks.remove(i);
3836                tr.removedFromRecents(mTaskPersister);
3837            }
3838        }
3839
3840        // Remove tasks from persistent storage.
3841        mTaskPersister.wakeup(null, true);
3842    }
3843
3844    /**
3845     * Update the recent tasks lists: make sure tasks should still be here (their
3846     * applications / activities still exist), update their availability, fixup ordering
3847     * of affiliations.
3848     */
3849    void cleanupRecentTasksLocked(int userId) {
3850        if (mRecentTasks == null) {
3851            // Happens when called from the packagemanager broadcast before boot.
3852            return;
3853        }
3854
3855        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3856        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3857        final IPackageManager pm = AppGlobals.getPackageManager();
3858        final ActivityInfo dummyAct = new ActivityInfo();
3859        final ApplicationInfo dummyApp = new ApplicationInfo();
3860
3861        int N = mRecentTasks.size();
3862
3863        int[] users = userId == UserHandle.USER_ALL
3864                ? getUsersLocked() : new int[] { userId };
3865        for (int user : users) {
3866            for (int i = 0; i < N; i++) {
3867                TaskRecord task = mRecentTasks.get(i);
3868                if (task.userId != user) {
3869                    // Only look at tasks for the user ID of interest.
3870                    continue;
3871                }
3872                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3873                    // This situation is broken, and we should just get rid of it now.
3874                    mRecentTasks.remove(i);
3875                    task.removedFromRecents(mTaskPersister);
3876                    i--;
3877                    N--;
3878                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3879                    continue;
3880                }
3881                // Check whether this activity is currently available.
3882                if (task.realActivity != null) {
3883                    ActivityInfo ai = availActCache.get(task.realActivity);
3884                    if (ai == null) {
3885                        try {
3886                            ai = pm.getActivityInfo(task.realActivity,
3887                                    PackageManager.GET_UNINSTALLED_PACKAGES
3888                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3889                        } catch (RemoteException e) {
3890                            // Will never happen.
3891                            continue;
3892                        }
3893                        if (ai == null) {
3894                            ai = dummyAct;
3895                        }
3896                        availActCache.put(task.realActivity, ai);
3897                    }
3898                    if (ai == dummyAct) {
3899                        // This could be either because the activity no longer exists, or the
3900                        // app is temporarily gone.  For the former we want to remove the recents
3901                        // entry; for the latter we want to mark it as unavailable.
3902                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3903                        if (app == null) {
3904                            try {
3905                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3906                                        PackageManager.GET_UNINSTALLED_PACKAGES
3907                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3908                            } catch (RemoteException e) {
3909                                // Will never happen.
3910                                continue;
3911                            }
3912                            if (app == null) {
3913                                app = dummyApp;
3914                            }
3915                            availAppCache.put(task.realActivity.getPackageName(), app);
3916                        }
3917                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3918                            // Doesn't exist any more!  Good-bye.
3919                            mRecentTasks.remove(i);
3920                            task.removedFromRecents(mTaskPersister);
3921                            i--;
3922                            N--;
3923                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3924                            continue;
3925                        } else {
3926                            // Otherwise just not available for now.
3927                            if (task.isAvailable) {
3928                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3929                                        + task);
3930                            }
3931                            task.isAvailable = false;
3932                        }
3933                    } else {
3934                        if (!ai.enabled || !ai.applicationInfo.enabled
3935                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3936                            if (task.isAvailable) {
3937                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3938                                        + task + " (enabled=" + ai.enabled + "/"
3939                                        + ai.applicationInfo.enabled +  " flags="
3940                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3941                            }
3942                            task.isAvailable = false;
3943                        } else {
3944                            if (!task.isAvailable) {
3945                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3946                                        + task);
3947                            }
3948                            task.isAvailable = true;
3949                        }
3950                    }
3951                }
3952            }
3953        }
3954
3955        // Verify the affiliate chain for each task.
3956        for (int i = 0; i < N; ) {
3957            TaskRecord task = mRecentTasks.remove(i);
3958            if (mTmpRecents.contains(task)) {
3959                continue;
3960            }
3961            int affiliatedTaskId = task.mAffiliatedTaskId;
3962            while (true) {
3963                TaskRecord next = task.mNextAffiliate;
3964                if (next == null) {
3965                    break;
3966                }
3967                if (next.mAffiliatedTaskId != affiliatedTaskId) {
3968                    Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
3969                            next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
3970                    task.setNextAffiliate(null);
3971                    if (next.mPrevAffiliate == task) {
3972                        next.setPrevAffiliate(null);
3973                    }
3974                    break;
3975                }
3976                if (next.mPrevAffiliate != task) {
3977                    Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
3978                            next.mPrevAffiliate + " task=" + task);
3979                    next.setPrevAffiliate(null);
3980                    task.setNextAffiliate(null);
3981                    break;
3982                }
3983                if (!mRecentTasks.contains(next)) {
3984                    Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
3985                    task.setNextAffiliate(null);
3986                    // We know that next.mPrevAffiliate is always task, from above, so clear
3987                    // its previous affiliate.
3988                    next.setPrevAffiliate(null);
3989                    break;
3990                }
3991                task = next;
3992            }
3993            // task is now the end of the list
3994            do {
3995                mRecentTasks.remove(task);
3996                mRecentTasks.add(i++, task);
3997                mTmpRecents.add(task);
3998                task.inRecents = true;
3999            } while ((task = task.mPrevAffiliate) != null);
4000        }
4001        mTmpRecents.clear();
4002        // mRecentTasks is now in sorted, affiliated order.
4003    }
4004
4005    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
4006        int N = mRecentTasks.size();
4007        TaskRecord top = task;
4008        int topIndex = taskIndex;
4009        while (top.mNextAffiliate != null && topIndex > 0) {
4010            top = top.mNextAffiliate;
4011            topIndex--;
4012        }
4013        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
4014                + topIndex + " from intial " + taskIndex);
4015        // Find the end of the chain, doing a sanity check along the way.
4016        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
4017        int endIndex = topIndex;
4018        TaskRecord prev = top;
4019        while (endIndex < N) {
4020            TaskRecord cur = mRecentTasks.get(endIndex);
4021            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
4022                    + endIndex + " " + cur);
4023            if (cur == top) {
4024                // Verify start of the chain.
4025                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
4026                    Slog.wtf(TAG, "Bad chain @" + endIndex
4027                            + ": first task has next affiliate: " + prev);
4028                    sane = false;
4029                    break;
4030                }
4031            } else {
4032                // Verify middle of the chain's next points back to the one before.
4033                if (cur.mNextAffiliate != prev
4034                        || cur.mNextAffiliateTaskId != prev.taskId) {
4035                    Slog.wtf(TAG, "Bad chain @" + endIndex
4036                            + ": middle task " + cur + " @" + endIndex
4037                            + " has bad next affiliate "
4038                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4039                            + ", expected " + prev);
4040                    sane = false;
4041                    break;
4042                }
4043            }
4044            if (cur.mPrevAffiliateTaskId == -1) {
4045                // Chain ends here.
4046                if (cur.mPrevAffiliate != null) {
4047                    Slog.wtf(TAG, "Bad chain @" + endIndex
4048                            + ": last task " + cur + " has previous affiliate "
4049                            + cur.mPrevAffiliate);
4050                    sane = false;
4051                }
4052                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4053                break;
4054            } else {
4055                // Verify middle of the chain's prev points to a valid item.
4056                if (cur.mPrevAffiliate == null) {
4057                    Slog.wtf(TAG, "Bad chain @" + endIndex
4058                            + ": task " + cur + " has previous affiliate "
4059                            + cur.mPrevAffiliate + " but should be id "
4060                            + cur.mPrevAffiliate);
4061                    sane = false;
4062                    break;
4063                }
4064            }
4065            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4066                Slog.wtf(TAG, "Bad chain @" + endIndex
4067                        + ": task " + cur + " has affiliated id "
4068                        + cur.mAffiliatedTaskId + " but should be "
4069                        + task.mAffiliatedTaskId);
4070                sane = false;
4071                break;
4072            }
4073            prev = cur;
4074            endIndex++;
4075            if (endIndex >= N) {
4076                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4077                        + ": last task " + prev);
4078                sane = false;
4079                break;
4080            }
4081        }
4082        if (sane) {
4083            if (endIndex < taskIndex) {
4084                Slog.wtf(TAG, "Bad chain @" + endIndex
4085                        + ": did not extend to task " + task + " @" + taskIndex);
4086                sane = false;
4087            }
4088        }
4089        if (sane) {
4090            // All looks good, we can just move all of the affiliated tasks
4091            // to the top.
4092            for (int i=topIndex; i<=endIndex; i++) {
4093                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4094                        + " from " + i + " to " + (i-topIndex));
4095                TaskRecord cur = mRecentTasks.remove(i);
4096                mRecentTasks.add(i-topIndex, cur);
4097            }
4098            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4099                    + " to " + endIndex);
4100            return true;
4101        }
4102
4103        // Whoops, couldn't do it.
4104        return false;
4105    }
4106
4107    final void addRecentTaskLocked(TaskRecord task) {
4108        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4109                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4110
4111        int N = mRecentTasks.size();
4112        // Quick case: check if the top-most recent task is the same.
4113        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4114            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4115            return;
4116        }
4117        // Another quick case: check if this is part of a set of affiliated
4118        // tasks that are at the top.
4119        if (isAffiliated && N > 0 && task.inRecents
4120                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4121            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4122                    + " at top when adding " + task);
4123            return;
4124        }
4125        // Another quick case: never add voice sessions.
4126        if (task.voiceSession != null) {
4127            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4128            return;
4129        }
4130
4131        boolean needAffiliationFix = false;
4132
4133        // Slightly less quick case: the task is already in recents, so all we need
4134        // to do is move it.
4135        if (task.inRecents) {
4136            int taskIndex = mRecentTasks.indexOf(task);
4137            if (taskIndex >= 0) {
4138                if (!isAffiliated) {
4139                    // Simple case: this is not an affiliated task, so we just move it to the front.
4140                    mRecentTasks.remove(taskIndex);
4141                    mRecentTasks.add(0, task);
4142                    notifyTaskPersisterLocked(task, false);
4143                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4144                            + " from " + taskIndex);
4145                    return;
4146                } else {
4147                    // More complicated: need to keep all affiliated tasks together.
4148                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4149                        // All went well.
4150                        return;
4151                    }
4152
4153                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4154                    // everything and then go through our general path of adding a new task.
4155                    needAffiliationFix = true;
4156                }
4157            } else {
4158                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4159                needAffiliationFix = true;
4160            }
4161        }
4162
4163        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4164        trimRecentsForTask(task, true);
4165
4166        N = mRecentTasks.size();
4167        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4168            final TaskRecord tr = mRecentTasks.remove(N - 1);
4169            tr.removedFromRecents(mTaskPersister);
4170            N--;
4171        }
4172        task.inRecents = true;
4173        if (!isAffiliated || needAffiliationFix) {
4174            // If this is a simple non-affiliated task, or we had some failure trying to
4175            // handle it as part of an affilated task, then just place it at the top.
4176            mRecentTasks.add(0, task);
4177        } else if (isAffiliated) {
4178            // If this is a new affiliated task, then move all of the affiliated tasks
4179            // to the front and insert this new one.
4180            TaskRecord other = task.mNextAffiliate;
4181            if (other == null) {
4182                other = task.mPrevAffiliate;
4183            }
4184            if (other != null) {
4185                int otherIndex = mRecentTasks.indexOf(other);
4186                if (otherIndex >= 0) {
4187                    // Insert new task at appropriate location.
4188                    int taskIndex;
4189                    if (other == task.mNextAffiliate) {
4190                        // We found the index of our next affiliation, which is who is
4191                        // before us in the list, so add after that point.
4192                        taskIndex = otherIndex+1;
4193                    } else {
4194                        // We found the index of our previous affiliation, which is who is
4195                        // after us in the list, so add at their position.
4196                        taskIndex = otherIndex;
4197                    }
4198                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4199                            + taskIndex + ": " + task);
4200                    mRecentTasks.add(taskIndex, task);
4201
4202                    // Now move everything to the front.
4203                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4204                        // All went well.
4205                        return;
4206                    }
4207
4208                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4209                    // everything and then go through our general path of adding a new task.
4210                    needAffiliationFix = true;
4211                } else {
4212                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4213                            + other);
4214                    needAffiliationFix = true;
4215                }
4216            } else {
4217                if (DEBUG_RECENTS) Slog.d(TAG,
4218                        "addRecent: adding affiliated task without next/prev:" + task);
4219                needAffiliationFix = true;
4220            }
4221        }
4222        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4223
4224        if (needAffiliationFix) {
4225            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4226            cleanupRecentTasksLocked(task.userId);
4227        }
4228    }
4229
4230    /**
4231     * If needed, remove oldest existing entries in recents that are for the same kind
4232     * of task as the given one.
4233     */
4234    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4235        int N = mRecentTasks.size();
4236        final Intent intent = task.intent;
4237        final boolean document = intent != null && intent.isDocument();
4238
4239        int maxRecents = task.maxRecents - 1;
4240        for (int i=0; i<N; i++) {
4241            final TaskRecord tr = mRecentTasks.get(i);
4242            if (task != tr) {
4243                if (task.userId != tr.userId) {
4244                    continue;
4245                }
4246                if (i > MAX_RECENT_BITMAPS) {
4247                    tr.freeLastThumbnail();
4248                }
4249                final Intent trIntent = tr.intent;
4250                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4251                    (intent == null || !intent.filterEquals(trIntent))) {
4252                    continue;
4253                }
4254                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4255                if (document && trIsDocument) {
4256                    // These are the same document activity (not necessarily the same doc).
4257                    if (maxRecents > 0) {
4258                        --maxRecents;
4259                        continue;
4260                    }
4261                    // Hit the maximum number of documents for this task. Fall through
4262                    // and remove this document from recents.
4263                } else if (document || trIsDocument) {
4264                    // Only one of these is a document. Not the droid we're looking for.
4265                    continue;
4266                }
4267            }
4268
4269            if (!doTrim) {
4270                // If the caller is not actually asking for a trim, just tell them we reached
4271                // a point where the trim would happen.
4272                return i;
4273            }
4274
4275            // Either task and tr are the same or, their affinities match or their intents match
4276            // and neither of them is a document, or they are documents using the same activity
4277            // and their maxRecents has been reached.
4278            tr.disposeThumbnail();
4279            mRecentTasks.remove(i);
4280            if (task != tr) {
4281                tr.removedFromRecents(mTaskPersister);
4282            }
4283            i--;
4284            N--;
4285            if (task.intent == null) {
4286                // If the new recent task we are adding is not fully
4287                // specified, then replace it with the existing recent task.
4288                task = tr;
4289            }
4290            notifyTaskPersisterLocked(tr, false);
4291        }
4292
4293        return -1;
4294    }
4295
4296    @Override
4297    public void reportActivityFullyDrawn(IBinder token) {
4298        synchronized (this) {
4299            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4300            if (r == null) {
4301                return;
4302            }
4303            r.reportFullyDrawnLocked();
4304        }
4305    }
4306
4307    @Override
4308    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4309        synchronized (this) {
4310            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4311            if (r == null) {
4312                return;
4313            }
4314            final long origId = Binder.clearCallingIdentity();
4315            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4316            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4317                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4318            if (config != null) {
4319                r.frozenBeforeDestroy = true;
4320                if (!updateConfigurationLocked(config, r, false, false)) {
4321                    mStackSupervisor.resumeTopActivitiesLocked();
4322                }
4323            }
4324            Binder.restoreCallingIdentity(origId);
4325        }
4326    }
4327
4328    @Override
4329    public int getRequestedOrientation(IBinder token) {
4330        synchronized (this) {
4331            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4332            if (r == null) {
4333                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4334            }
4335            return mWindowManager.getAppOrientation(r.appToken);
4336        }
4337    }
4338
4339    /**
4340     * This is the internal entry point for handling Activity.finish().
4341     *
4342     * @param token The Binder token referencing the Activity we want to finish.
4343     * @param resultCode Result code, if any, from this Activity.
4344     * @param resultData Result data (Intent), if any, from this Activity.
4345     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4346     *            the root Activity in the task.
4347     *
4348     * @return Returns true if the activity successfully finished, or false if it is still running.
4349     */
4350    @Override
4351    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4352            boolean finishTask) {
4353        // Refuse possible leaked file descriptors
4354        if (resultData != null && resultData.hasFileDescriptors() == true) {
4355            throw new IllegalArgumentException("File descriptors passed in Intent");
4356        }
4357
4358        synchronized(this) {
4359            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4360            if (r == null) {
4361                return true;
4362            }
4363            // Keep track of the root activity of the task before we finish it
4364            TaskRecord tr = r.task;
4365            ActivityRecord rootR = tr.getRootActivity();
4366            // Do not allow task to finish in Lock Task mode.
4367            if (tr == mStackSupervisor.mLockTaskModeTask) {
4368                if (rootR == r) {
4369                    mStackSupervisor.showLockTaskToast();
4370                    return false;
4371                }
4372            }
4373            if (mController != null) {
4374                // Find the first activity that is not finishing.
4375                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4376                if (next != null) {
4377                    // ask watcher if this is allowed
4378                    boolean resumeOK = true;
4379                    try {
4380                        resumeOK = mController.activityResuming(next.packageName);
4381                    } catch (RemoteException e) {
4382                        mController = null;
4383                        Watchdog.getInstance().setActivityController(null);
4384                    }
4385
4386                    if (!resumeOK) {
4387                        return false;
4388                    }
4389                }
4390            }
4391            final long origId = Binder.clearCallingIdentity();
4392            try {
4393                boolean res;
4394                if (finishTask && r == rootR) {
4395                    // If requested, remove the task that is associated to this activity only if it
4396                    // was the root activity in the task.  The result code and data is ignored because
4397                    // we don't support returning them across task boundaries.
4398                    res = removeTaskByIdLocked(tr.taskId, 0);
4399                } else {
4400                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4401                            resultData, "app-request", true);
4402                }
4403                return res;
4404            } finally {
4405                Binder.restoreCallingIdentity(origId);
4406            }
4407        }
4408    }
4409
4410    @Override
4411    public final void finishHeavyWeightApp() {
4412        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4413                != PackageManager.PERMISSION_GRANTED) {
4414            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4415                    + Binder.getCallingPid()
4416                    + ", uid=" + Binder.getCallingUid()
4417                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4418            Slog.w(TAG, msg);
4419            throw new SecurityException(msg);
4420        }
4421
4422        synchronized(this) {
4423            if (mHeavyWeightProcess == null) {
4424                return;
4425            }
4426
4427            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4428                    mHeavyWeightProcess.activities);
4429            for (int i=0; i<activities.size(); i++) {
4430                ActivityRecord r = activities.get(i);
4431                if (!r.finishing) {
4432                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4433                            null, "finish-heavy", true);
4434                }
4435            }
4436
4437            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4438                    mHeavyWeightProcess.userId, 0));
4439            mHeavyWeightProcess = null;
4440        }
4441    }
4442
4443    @Override
4444    public void crashApplication(int uid, int initialPid, String packageName,
4445            String message) {
4446        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4447                != PackageManager.PERMISSION_GRANTED) {
4448            String msg = "Permission Denial: crashApplication() from pid="
4449                    + Binder.getCallingPid()
4450                    + ", uid=" + Binder.getCallingUid()
4451                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4452            Slog.w(TAG, msg);
4453            throw new SecurityException(msg);
4454        }
4455
4456        synchronized(this) {
4457            ProcessRecord proc = null;
4458
4459            // Figure out which process to kill.  We don't trust that initialPid
4460            // still has any relation to current pids, so must scan through the
4461            // list.
4462            synchronized (mPidsSelfLocked) {
4463                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4464                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4465                    if (p.uid != uid) {
4466                        continue;
4467                    }
4468                    if (p.pid == initialPid) {
4469                        proc = p;
4470                        break;
4471                    }
4472                    if (p.pkgList.containsKey(packageName)) {
4473                        proc = p;
4474                    }
4475                }
4476            }
4477
4478            if (proc == null) {
4479                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4480                        + " initialPid=" + initialPid
4481                        + " packageName=" + packageName);
4482                return;
4483            }
4484
4485            if (proc.thread != null) {
4486                if (proc.pid == Process.myPid()) {
4487                    Log.w(TAG, "crashApplication: trying to crash self!");
4488                    return;
4489                }
4490                long ident = Binder.clearCallingIdentity();
4491                try {
4492                    proc.thread.scheduleCrash(message);
4493                } catch (RemoteException e) {
4494                }
4495                Binder.restoreCallingIdentity(ident);
4496            }
4497        }
4498    }
4499
4500    @Override
4501    public final void finishSubActivity(IBinder token, String resultWho,
4502            int requestCode) {
4503        synchronized(this) {
4504            final long origId = Binder.clearCallingIdentity();
4505            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4506            if (r != null) {
4507                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4508            }
4509            Binder.restoreCallingIdentity(origId);
4510        }
4511    }
4512
4513    @Override
4514    public boolean finishActivityAffinity(IBinder token) {
4515        synchronized(this) {
4516            final long origId = Binder.clearCallingIdentity();
4517            try {
4518                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4519
4520                ActivityRecord rootR = r.task.getRootActivity();
4521                // Do not allow task to finish in Lock Task mode.
4522                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4523                    if (rootR == r) {
4524                        mStackSupervisor.showLockTaskToast();
4525                        return false;
4526                    }
4527                }
4528                boolean res = false;
4529                if (r != null) {
4530                    res = r.task.stack.finishActivityAffinityLocked(r);
4531                }
4532                return res;
4533            } finally {
4534                Binder.restoreCallingIdentity(origId);
4535            }
4536        }
4537    }
4538
4539    @Override
4540    public void finishVoiceTask(IVoiceInteractionSession session) {
4541        synchronized(this) {
4542            final long origId = Binder.clearCallingIdentity();
4543            try {
4544                mStackSupervisor.finishVoiceTask(session);
4545            } finally {
4546                Binder.restoreCallingIdentity(origId);
4547            }
4548        }
4549
4550    }
4551
4552    @Override
4553    public boolean releaseActivityInstance(IBinder token) {
4554        synchronized(this) {
4555            final long origId = Binder.clearCallingIdentity();
4556            try {
4557                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4558                if (r.task == null || r.task.stack == null) {
4559                    return false;
4560                }
4561                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4562            } finally {
4563                Binder.restoreCallingIdentity(origId);
4564            }
4565        }
4566    }
4567
4568    @Override
4569    public void releaseSomeActivities(IApplicationThread appInt) {
4570        synchronized(this) {
4571            final long origId = Binder.clearCallingIdentity();
4572            try {
4573                ProcessRecord app = getRecordForAppLocked(appInt);
4574                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4575            } finally {
4576                Binder.restoreCallingIdentity(origId);
4577            }
4578        }
4579    }
4580
4581    @Override
4582    public boolean willActivityBeVisible(IBinder token) {
4583        synchronized(this) {
4584            ActivityStack stack = ActivityRecord.getStackLocked(token);
4585            if (stack != null) {
4586                return stack.willActivityBeVisibleLocked(token);
4587            }
4588            return false;
4589        }
4590    }
4591
4592    @Override
4593    public void overridePendingTransition(IBinder token, String packageName,
4594            int enterAnim, int exitAnim) {
4595        synchronized(this) {
4596            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4597            if (self == null) {
4598                return;
4599            }
4600
4601            final long origId = Binder.clearCallingIdentity();
4602
4603            if (self.state == ActivityState.RESUMED
4604                    || self.state == ActivityState.PAUSING) {
4605                mWindowManager.overridePendingAppTransition(packageName,
4606                        enterAnim, exitAnim, null);
4607            }
4608
4609            Binder.restoreCallingIdentity(origId);
4610        }
4611    }
4612
4613    /**
4614     * Main function for removing an existing process from the activity manager
4615     * as a result of that process going away.  Clears out all connections
4616     * to the process.
4617     */
4618    private final void handleAppDiedLocked(ProcessRecord app,
4619            boolean restarting, boolean allowRestart) {
4620        int pid = app.pid;
4621        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4622        if (!restarting) {
4623            removeLruProcessLocked(app);
4624            if (pid > 0) {
4625                ProcessList.remove(pid);
4626            }
4627        }
4628
4629        if (mProfileProc == app) {
4630            clearProfilerLocked();
4631        }
4632
4633        // Remove this application's activities from active lists.
4634        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4635
4636        app.activities.clear();
4637
4638        if (app.instrumentationClass != null) {
4639            Slog.w(TAG, "Crash of app " + app.processName
4640                  + " running instrumentation " + app.instrumentationClass);
4641            Bundle info = new Bundle();
4642            info.putString("shortMsg", "Process crashed.");
4643            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4644        }
4645
4646        if (!restarting) {
4647            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4648                // If there was nothing to resume, and we are not already
4649                // restarting this process, but there is a visible activity that
4650                // is hosted by the process...  then make sure all visible
4651                // activities are running, taking care of restarting this
4652                // process.
4653                if (hasVisibleActivities) {
4654                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4655                }
4656            }
4657        }
4658    }
4659
4660    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4661        IBinder threadBinder = thread.asBinder();
4662        // Find the application record.
4663        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4664            ProcessRecord rec = mLruProcesses.get(i);
4665            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4666                return i;
4667            }
4668        }
4669        return -1;
4670    }
4671
4672    final ProcessRecord getRecordForAppLocked(
4673            IApplicationThread thread) {
4674        if (thread == null) {
4675            return null;
4676        }
4677
4678        int appIndex = getLRURecordIndexForAppLocked(thread);
4679        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4680    }
4681
4682    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4683        // If there are no longer any background processes running,
4684        // and the app that died was not running instrumentation,
4685        // then tell everyone we are now low on memory.
4686        boolean haveBg = false;
4687        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4688            ProcessRecord rec = mLruProcesses.get(i);
4689            if (rec.thread != null
4690                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4691                haveBg = true;
4692                break;
4693            }
4694        }
4695
4696        if (!haveBg) {
4697            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4698            if (doReport) {
4699                long now = SystemClock.uptimeMillis();
4700                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4701                    doReport = false;
4702                } else {
4703                    mLastMemUsageReportTime = now;
4704                }
4705            }
4706            final ArrayList<ProcessMemInfo> memInfos
4707                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4708            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4709            long now = SystemClock.uptimeMillis();
4710            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4711                ProcessRecord rec = mLruProcesses.get(i);
4712                if (rec == dyingProc || rec.thread == null) {
4713                    continue;
4714                }
4715                if (doReport) {
4716                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4717                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4718                }
4719                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4720                    // The low memory report is overriding any current
4721                    // state for a GC request.  Make sure to do
4722                    // heavy/important/visible/foreground processes first.
4723                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4724                        rec.lastRequestedGc = 0;
4725                    } else {
4726                        rec.lastRequestedGc = rec.lastLowMemory;
4727                    }
4728                    rec.reportLowMemory = true;
4729                    rec.lastLowMemory = now;
4730                    mProcessesToGc.remove(rec);
4731                    addProcessToGcListLocked(rec);
4732                }
4733            }
4734            if (doReport) {
4735                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4736                mHandler.sendMessage(msg);
4737            }
4738            scheduleAppGcsLocked();
4739        }
4740    }
4741
4742    final void appDiedLocked(ProcessRecord app) {
4743       appDiedLocked(app, app.pid, app.thread);
4744    }
4745
4746    final void appDiedLocked(ProcessRecord app, int pid,
4747            IApplicationThread thread) {
4748
4749        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4750        synchronized (stats) {
4751            stats.noteProcessDiedLocked(app.info.uid, pid);
4752        }
4753
4754        Process.killProcessGroup(app.info.uid, pid);
4755
4756        // Clean up already done if the process has been re-started.
4757        if (app.pid == pid && app.thread != null &&
4758                app.thread.asBinder() == thread.asBinder()) {
4759            boolean doLowMem = app.instrumentationClass == null;
4760            boolean doOomAdj = doLowMem;
4761            if (!app.killedByAm) {
4762                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4763                        + ") has died.");
4764                mAllowLowerMemLevel = true;
4765            } else {
4766                // Note that we always want to do oom adj to update our state with the
4767                // new number of procs.
4768                mAllowLowerMemLevel = false;
4769                doLowMem = false;
4770            }
4771            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4772            if (DEBUG_CLEANUP) Slog.v(
4773                TAG, "Dying app: " + app + ", pid: " + pid
4774                + ", thread: " + thread.asBinder());
4775            handleAppDiedLocked(app, false, true);
4776
4777            if (doOomAdj) {
4778                updateOomAdjLocked();
4779            }
4780            if (doLowMem) {
4781                doLowMemReportIfNeededLocked(app);
4782            }
4783        } else if (app.pid != pid) {
4784            // A new process has already been started.
4785            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4786                    + ") has died and restarted (pid " + app.pid + ").");
4787            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4788        } else if (DEBUG_PROCESSES) {
4789            Slog.d(TAG, "Received spurious death notification for thread "
4790                    + thread.asBinder());
4791        }
4792    }
4793
4794    /**
4795     * If a stack trace dump file is configured, dump process stack traces.
4796     * @param clearTraces causes the dump file to be erased prior to the new
4797     *    traces being written, if true; when false, the new traces will be
4798     *    appended to any existing file content.
4799     * @param firstPids of dalvik VM processes to dump stack traces for first
4800     * @param lastPids of dalvik VM processes to dump stack traces for last
4801     * @param nativeProcs optional list of native process names to dump stack crawls
4802     * @return file containing stack traces, or null if no dump file is configured
4803     */
4804    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4805            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4806        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4807        if (tracesPath == null || tracesPath.length() == 0) {
4808            return null;
4809        }
4810
4811        File tracesFile = new File(tracesPath);
4812        try {
4813            File tracesDir = tracesFile.getParentFile();
4814            if (!tracesDir.exists()) {
4815                tracesFile.mkdirs();
4816                if (!SELinux.restorecon(tracesDir)) {
4817                    return null;
4818                }
4819            }
4820            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4821
4822            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4823            tracesFile.createNewFile();
4824            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4825        } catch (IOException e) {
4826            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4827            return null;
4828        }
4829
4830        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4831        return tracesFile;
4832    }
4833
4834    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4835            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4836        // Use a FileObserver to detect when traces finish writing.
4837        // The order of traces is considered important to maintain for legibility.
4838        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4839            @Override
4840            public synchronized void onEvent(int event, String path) { notify(); }
4841        };
4842
4843        try {
4844            observer.startWatching();
4845
4846            // First collect all of the stacks of the most important pids.
4847            if (firstPids != null) {
4848                try {
4849                    int num = firstPids.size();
4850                    for (int i = 0; i < num; i++) {
4851                        synchronized (observer) {
4852                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4853                            observer.wait(200);  // Wait for write-close, give up after 200msec
4854                        }
4855                    }
4856                } catch (InterruptedException e) {
4857                    Log.wtf(TAG, e);
4858                }
4859            }
4860
4861            // Next collect the stacks of the native pids
4862            if (nativeProcs != null) {
4863                int[] pids = Process.getPidsForCommands(nativeProcs);
4864                if (pids != null) {
4865                    for (int pid : pids) {
4866                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4867                    }
4868                }
4869            }
4870
4871            // Lastly, measure CPU usage.
4872            if (processCpuTracker != null) {
4873                processCpuTracker.init();
4874                System.gc();
4875                processCpuTracker.update();
4876                try {
4877                    synchronized (processCpuTracker) {
4878                        processCpuTracker.wait(500); // measure over 1/2 second.
4879                    }
4880                } catch (InterruptedException e) {
4881                }
4882                processCpuTracker.update();
4883
4884                // We'll take the stack crawls of just the top apps using CPU.
4885                final int N = processCpuTracker.countWorkingStats();
4886                int numProcs = 0;
4887                for (int i=0; i<N && numProcs<5; i++) {
4888                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4889                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4890                        numProcs++;
4891                        try {
4892                            synchronized (observer) {
4893                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4894                                observer.wait(200);  // Wait for write-close, give up after 200msec
4895                            }
4896                        } catch (InterruptedException e) {
4897                            Log.wtf(TAG, e);
4898                        }
4899
4900                    }
4901                }
4902            }
4903        } finally {
4904            observer.stopWatching();
4905        }
4906    }
4907
4908    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4909        if (true || IS_USER_BUILD) {
4910            return;
4911        }
4912        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4913        if (tracesPath == null || tracesPath.length() == 0) {
4914            return;
4915        }
4916
4917        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4918        StrictMode.allowThreadDiskWrites();
4919        try {
4920            final File tracesFile = new File(tracesPath);
4921            final File tracesDir = tracesFile.getParentFile();
4922            final File tracesTmp = new File(tracesDir, "__tmp__");
4923            try {
4924                if (!tracesDir.exists()) {
4925                    tracesFile.mkdirs();
4926                    if (!SELinux.restorecon(tracesDir.getPath())) {
4927                        return;
4928                    }
4929                }
4930                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4931
4932                if (tracesFile.exists()) {
4933                    tracesTmp.delete();
4934                    tracesFile.renameTo(tracesTmp);
4935                }
4936                StringBuilder sb = new StringBuilder();
4937                Time tobj = new Time();
4938                tobj.set(System.currentTimeMillis());
4939                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4940                sb.append(": ");
4941                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4942                sb.append(" since ");
4943                sb.append(msg);
4944                FileOutputStream fos = new FileOutputStream(tracesFile);
4945                fos.write(sb.toString().getBytes());
4946                if (app == null) {
4947                    fos.write("\n*** No application process!".getBytes());
4948                }
4949                fos.close();
4950                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4951            } catch (IOException e) {
4952                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4953                return;
4954            }
4955
4956            if (app != null) {
4957                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4958                firstPids.add(app.pid);
4959                dumpStackTraces(tracesPath, firstPids, null, null, null);
4960            }
4961
4962            File lastTracesFile = null;
4963            File curTracesFile = null;
4964            for (int i=9; i>=0; i--) {
4965                String name = String.format(Locale.US, "slow%02d.txt", i);
4966                curTracesFile = new File(tracesDir, name);
4967                if (curTracesFile.exists()) {
4968                    if (lastTracesFile != null) {
4969                        curTracesFile.renameTo(lastTracesFile);
4970                    } else {
4971                        curTracesFile.delete();
4972                    }
4973                }
4974                lastTracesFile = curTracesFile;
4975            }
4976            tracesFile.renameTo(curTracesFile);
4977            if (tracesTmp.exists()) {
4978                tracesTmp.renameTo(tracesFile);
4979            }
4980        } finally {
4981            StrictMode.setThreadPolicy(oldPolicy);
4982        }
4983    }
4984
4985    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4986            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4987        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4988        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4989
4990        if (mController != null) {
4991            try {
4992                // 0 == continue, -1 = kill process immediately
4993                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4994                if (res < 0 && app.pid != MY_PID) {
4995                    app.kill("anr", true);
4996                }
4997            } catch (RemoteException e) {
4998                mController = null;
4999                Watchdog.getInstance().setActivityController(null);
5000            }
5001        }
5002
5003        long anrTime = SystemClock.uptimeMillis();
5004        if (MONITOR_CPU_USAGE) {
5005            updateCpuStatsNow();
5006        }
5007
5008        synchronized (this) {
5009            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5010            if (mShuttingDown) {
5011                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5012                return;
5013            } else if (app.notResponding) {
5014                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5015                return;
5016            } else if (app.crashing) {
5017                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5018                return;
5019            }
5020
5021            // In case we come through here for the same app before completing
5022            // this one, mark as anring now so we will bail out.
5023            app.notResponding = true;
5024
5025            // Log the ANR to the event log.
5026            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5027                    app.processName, app.info.flags, annotation);
5028
5029            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5030            firstPids.add(app.pid);
5031
5032            int parentPid = app.pid;
5033            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5034            if (parentPid != app.pid) firstPids.add(parentPid);
5035
5036            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5037
5038            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5039                ProcessRecord r = mLruProcesses.get(i);
5040                if (r != null && r.thread != null) {
5041                    int pid = r.pid;
5042                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5043                        if (r.persistent) {
5044                            firstPids.add(pid);
5045                        } else {
5046                            lastPids.put(pid, Boolean.TRUE);
5047                        }
5048                    }
5049                }
5050            }
5051        }
5052
5053        // Log the ANR to the main log.
5054        StringBuilder info = new StringBuilder();
5055        info.setLength(0);
5056        info.append("ANR in ").append(app.processName);
5057        if (activity != null && activity.shortComponentName != null) {
5058            info.append(" (").append(activity.shortComponentName).append(")");
5059        }
5060        info.append("\n");
5061        info.append("PID: ").append(app.pid).append("\n");
5062        if (annotation != null) {
5063            info.append("Reason: ").append(annotation).append("\n");
5064        }
5065        if (parent != null && parent != activity) {
5066            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5067        }
5068
5069        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5070
5071        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5072                NATIVE_STACKS_OF_INTEREST);
5073
5074        String cpuInfo = null;
5075        if (MONITOR_CPU_USAGE) {
5076            updateCpuStatsNow();
5077            synchronized (mProcessCpuThread) {
5078                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5079            }
5080            info.append(processCpuTracker.printCurrentLoad());
5081            info.append(cpuInfo);
5082        }
5083
5084        info.append(processCpuTracker.printCurrentState(anrTime));
5085
5086        Slog.e(TAG, info.toString());
5087        if (tracesFile == null) {
5088            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5089            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5090        }
5091
5092        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5093                cpuInfo, tracesFile, null);
5094
5095        if (mController != null) {
5096            try {
5097                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5098                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5099                if (res != 0) {
5100                    if (res < 0 && app.pid != MY_PID) {
5101                        app.kill("anr", true);
5102                    } else {
5103                        synchronized (this) {
5104                            mServices.scheduleServiceTimeoutLocked(app);
5105                        }
5106                    }
5107                    return;
5108                }
5109            } catch (RemoteException e) {
5110                mController = null;
5111                Watchdog.getInstance().setActivityController(null);
5112            }
5113        }
5114
5115        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5116        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5117                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5118
5119        synchronized (this) {
5120            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5121                app.kill("bg anr", true);
5122                return;
5123            }
5124
5125            // Set the app's notResponding state, and look up the errorReportReceiver
5126            makeAppNotRespondingLocked(app,
5127                    activity != null ? activity.shortComponentName : null,
5128                    annotation != null ? "ANR " + annotation : "ANR",
5129                    info.toString());
5130
5131            // Bring up the infamous App Not Responding dialog
5132            Message msg = Message.obtain();
5133            HashMap<String, Object> map = new HashMap<String, Object>();
5134            msg.what = SHOW_NOT_RESPONDING_MSG;
5135            msg.obj = map;
5136            msg.arg1 = aboveSystem ? 1 : 0;
5137            map.put("app", app);
5138            if (activity != null) {
5139                map.put("activity", activity);
5140            }
5141
5142            mHandler.sendMessage(msg);
5143        }
5144    }
5145
5146    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5147        if (!mLaunchWarningShown) {
5148            mLaunchWarningShown = true;
5149            mHandler.post(new Runnable() {
5150                @Override
5151                public void run() {
5152                    synchronized (ActivityManagerService.this) {
5153                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5154                        d.show();
5155                        mHandler.postDelayed(new Runnable() {
5156                            @Override
5157                            public void run() {
5158                                synchronized (ActivityManagerService.this) {
5159                                    d.dismiss();
5160                                    mLaunchWarningShown = false;
5161                                }
5162                            }
5163                        }, 4000);
5164                    }
5165                }
5166            });
5167        }
5168    }
5169
5170    @Override
5171    public boolean clearApplicationUserData(final String packageName,
5172            final IPackageDataObserver observer, int userId) {
5173        enforceNotIsolatedCaller("clearApplicationUserData");
5174        int uid = Binder.getCallingUid();
5175        int pid = Binder.getCallingPid();
5176        userId = handleIncomingUser(pid, uid,
5177                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5178        long callingId = Binder.clearCallingIdentity();
5179        try {
5180            IPackageManager pm = AppGlobals.getPackageManager();
5181            int pkgUid = -1;
5182            synchronized(this) {
5183                try {
5184                    pkgUid = pm.getPackageUid(packageName, userId);
5185                } catch (RemoteException e) {
5186                }
5187                if (pkgUid == -1) {
5188                    Slog.w(TAG, "Invalid packageName: " + packageName);
5189                    if (observer != null) {
5190                        try {
5191                            observer.onRemoveCompleted(packageName, false);
5192                        } catch (RemoteException e) {
5193                            Slog.i(TAG, "Observer no longer exists.");
5194                        }
5195                    }
5196                    return false;
5197                }
5198                if (uid == pkgUid || checkComponentPermission(
5199                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5200                        pid, uid, -1, true)
5201                        == PackageManager.PERMISSION_GRANTED) {
5202                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5203                } else {
5204                    throw new SecurityException("PID " + pid + " does not have permission "
5205                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5206                                    + " of package " + packageName);
5207                }
5208
5209                // Remove all tasks match the cleared application package and user
5210                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5211                    final TaskRecord tr = mRecentTasks.get(i);
5212                    final String taskPackageName =
5213                            tr.getBaseIntent().getComponent().getPackageName();
5214                    if (tr.userId != userId) continue;
5215                    if (!taskPackageName.equals(packageName)) continue;
5216                    removeTaskByIdLocked(tr.taskId, 0);
5217                }
5218            }
5219
5220            try {
5221                // Clear application user data
5222                pm.clearApplicationUserData(packageName, observer, userId);
5223
5224                synchronized(this) {
5225                    // Remove all permissions granted from/to this package
5226                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5227                }
5228
5229                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5230                        Uri.fromParts("package", packageName, null));
5231                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5232                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5233                        null, null, 0, null, null, null, false, false, userId);
5234            } catch (RemoteException e) {
5235            }
5236        } finally {
5237            Binder.restoreCallingIdentity(callingId);
5238        }
5239        return true;
5240    }
5241
5242    @Override
5243    public void killBackgroundProcesses(final String packageName, int userId) {
5244        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5245                != PackageManager.PERMISSION_GRANTED &&
5246                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5247                        != PackageManager.PERMISSION_GRANTED) {
5248            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5249                    + Binder.getCallingPid()
5250                    + ", uid=" + Binder.getCallingUid()
5251                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5252            Slog.w(TAG, msg);
5253            throw new SecurityException(msg);
5254        }
5255
5256        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5257                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5258        long callingId = Binder.clearCallingIdentity();
5259        try {
5260            IPackageManager pm = AppGlobals.getPackageManager();
5261            synchronized(this) {
5262                int appId = -1;
5263                try {
5264                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5265                } catch (RemoteException e) {
5266                }
5267                if (appId == -1) {
5268                    Slog.w(TAG, "Invalid packageName: " + packageName);
5269                    return;
5270                }
5271                killPackageProcessesLocked(packageName, appId, userId,
5272                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5273            }
5274        } finally {
5275            Binder.restoreCallingIdentity(callingId);
5276        }
5277    }
5278
5279    @Override
5280    public void killAllBackgroundProcesses() {
5281        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5282                != PackageManager.PERMISSION_GRANTED) {
5283            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5284                    + Binder.getCallingPid()
5285                    + ", uid=" + Binder.getCallingUid()
5286                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5287            Slog.w(TAG, msg);
5288            throw new SecurityException(msg);
5289        }
5290
5291        long callingId = Binder.clearCallingIdentity();
5292        try {
5293            synchronized(this) {
5294                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5295                final int NP = mProcessNames.getMap().size();
5296                for (int ip=0; ip<NP; ip++) {
5297                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5298                    final int NA = apps.size();
5299                    for (int ia=0; ia<NA; ia++) {
5300                        ProcessRecord app = apps.valueAt(ia);
5301                        if (app.persistent) {
5302                            // we don't kill persistent processes
5303                            continue;
5304                        }
5305                        if (app.removed) {
5306                            procs.add(app);
5307                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5308                            app.removed = true;
5309                            procs.add(app);
5310                        }
5311                    }
5312                }
5313
5314                int N = procs.size();
5315                for (int i=0; i<N; i++) {
5316                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5317                }
5318                mAllowLowerMemLevel = true;
5319                updateOomAdjLocked();
5320                doLowMemReportIfNeededLocked(null);
5321            }
5322        } finally {
5323            Binder.restoreCallingIdentity(callingId);
5324        }
5325    }
5326
5327    @Override
5328    public void forceStopPackage(final String packageName, int userId) {
5329        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5330                != PackageManager.PERMISSION_GRANTED) {
5331            String msg = "Permission Denial: forceStopPackage() from pid="
5332                    + Binder.getCallingPid()
5333                    + ", uid=" + Binder.getCallingUid()
5334                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5335            Slog.w(TAG, msg);
5336            throw new SecurityException(msg);
5337        }
5338        final int callingPid = Binder.getCallingPid();
5339        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5340                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5341        long callingId = Binder.clearCallingIdentity();
5342        try {
5343            IPackageManager pm = AppGlobals.getPackageManager();
5344            synchronized(this) {
5345                int[] users = userId == UserHandle.USER_ALL
5346                        ? getUsersLocked() : new int[] { userId };
5347                for (int user : users) {
5348                    int pkgUid = -1;
5349                    try {
5350                        pkgUid = pm.getPackageUid(packageName, user);
5351                    } catch (RemoteException e) {
5352                    }
5353                    if (pkgUid == -1) {
5354                        Slog.w(TAG, "Invalid packageName: " + packageName);
5355                        continue;
5356                    }
5357                    try {
5358                        pm.setPackageStoppedState(packageName, true, user);
5359                    } catch (RemoteException e) {
5360                    } catch (IllegalArgumentException e) {
5361                        Slog.w(TAG, "Failed trying to unstop package "
5362                                + packageName + ": " + e);
5363                    }
5364                    if (isUserRunningLocked(user, false)) {
5365                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5366                    }
5367                }
5368            }
5369        } finally {
5370            Binder.restoreCallingIdentity(callingId);
5371        }
5372    }
5373
5374    @Override
5375    public void addPackageDependency(String packageName) {
5376        synchronized (this) {
5377            int callingPid = Binder.getCallingPid();
5378            if (callingPid == Process.myPid()) {
5379                //  Yeah, um, no.
5380                Slog.w(TAG, "Can't addPackageDependency on system process");
5381                return;
5382            }
5383            ProcessRecord proc;
5384            synchronized (mPidsSelfLocked) {
5385                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5386            }
5387            if (proc != null) {
5388                if (proc.pkgDeps == null) {
5389                    proc.pkgDeps = new ArraySet<String>(1);
5390                }
5391                proc.pkgDeps.add(packageName);
5392            }
5393        }
5394    }
5395
5396    /*
5397     * The pkg name and app id have to be specified.
5398     */
5399    @Override
5400    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5401        if (pkg == null) {
5402            return;
5403        }
5404        // Make sure the uid is valid.
5405        if (appid < 0) {
5406            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5407            return;
5408        }
5409        int callerUid = Binder.getCallingUid();
5410        // Only the system server can kill an application
5411        if (callerUid == Process.SYSTEM_UID) {
5412            // Post an aysnc message to kill the application
5413            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5414            msg.arg1 = appid;
5415            msg.arg2 = 0;
5416            Bundle bundle = new Bundle();
5417            bundle.putString("pkg", pkg);
5418            bundle.putString("reason", reason);
5419            msg.obj = bundle;
5420            mHandler.sendMessage(msg);
5421        } else {
5422            throw new SecurityException(callerUid + " cannot kill pkg: " +
5423                    pkg);
5424        }
5425    }
5426
5427    @Override
5428    public void closeSystemDialogs(String reason) {
5429        enforceNotIsolatedCaller("closeSystemDialogs");
5430
5431        final int pid = Binder.getCallingPid();
5432        final int uid = Binder.getCallingUid();
5433        final long origId = Binder.clearCallingIdentity();
5434        try {
5435            synchronized (this) {
5436                // Only allow this from foreground processes, so that background
5437                // applications can't abuse it to prevent system UI from being shown.
5438                if (uid >= Process.FIRST_APPLICATION_UID) {
5439                    ProcessRecord proc;
5440                    synchronized (mPidsSelfLocked) {
5441                        proc = mPidsSelfLocked.get(pid);
5442                    }
5443                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5444                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5445                                + " from background process " + proc);
5446                        return;
5447                    }
5448                }
5449                closeSystemDialogsLocked(reason);
5450            }
5451        } finally {
5452            Binder.restoreCallingIdentity(origId);
5453        }
5454    }
5455
5456    void closeSystemDialogsLocked(String reason) {
5457        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5458        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5459                | Intent.FLAG_RECEIVER_FOREGROUND);
5460        if (reason != null) {
5461            intent.putExtra("reason", reason);
5462        }
5463        mWindowManager.closeSystemDialogs(reason);
5464
5465        mStackSupervisor.closeSystemDialogsLocked();
5466
5467        broadcastIntentLocked(null, null, intent, null,
5468                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5469                Process.SYSTEM_UID, UserHandle.USER_ALL);
5470    }
5471
5472    @Override
5473    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5474        enforceNotIsolatedCaller("getProcessMemoryInfo");
5475        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5476        for (int i=pids.length-1; i>=0; i--) {
5477            ProcessRecord proc;
5478            int oomAdj;
5479            synchronized (this) {
5480                synchronized (mPidsSelfLocked) {
5481                    proc = mPidsSelfLocked.get(pids[i]);
5482                    oomAdj = proc != null ? proc.setAdj : 0;
5483                }
5484            }
5485            infos[i] = new Debug.MemoryInfo();
5486            Debug.getMemoryInfo(pids[i], infos[i]);
5487            if (proc != null) {
5488                synchronized (this) {
5489                    if (proc.thread != null && proc.setAdj == oomAdj) {
5490                        // Record this for posterity if the process has been stable.
5491                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5492                                infos[i].getTotalUss(), false, proc.pkgList);
5493                    }
5494                }
5495            }
5496        }
5497        return infos;
5498    }
5499
5500    @Override
5501    public long[] getProcessPss(int[] pids) {
5502        enforceNotIsolatedCaller("getProcessPss");
5503        long[] pss = new long[pids.length];
5504        for (int i=pids.length-1; i>=0; i--) {
5505            ProcessRecord proc;
5506            int oomAdj;
5507            synchronized (this) {
5508                synchronized (mPidsSelfLocked) {
5509                    proc = mPidsSelfLocked.get(pids[i]);
5510                    oomAdj = proc != null ? proc.setAdj : 0;
5511                }
5512            }
5513            long[] tmpUss = new long[1];
5514            pss[i] = Debug.getPss(pids[i], tmpUss);
5515            if (proc != null) {
5516                synchronized (this) {
5517                    if (proc.thread != null && proc.setAdj == oomAdj) {
5518                        // Record this for posterity if the process has been stable.
5519                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5520                    }
5521                }
5522            }
5523        }
5524        return pss;
5525    }
5526
5527    @Override
5528    public void killApplicationProcess(String processName, int uid) {
5529        if (processName == null) {
5530            return;
5531        }
5532
5533        int callerUid = Binder.getCallingUid();
5534        // Only the system server can kill an application
5535        if (callerUid == Process.SYSTEM_UID) {
5536            synchronized (this) {
5537                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5538                if (app != null && app.thread != null) {
5539                    try {
5540                        app.thread.scheduleSuicide();
5541                    } catch (RemoteException e) {
5542                        // If the other end already died, then our work here is done.
5543                    }
5544                } else {
5545                    Slog.w(TAG, "Process/uid not found attempting kill of "
5546                            + processName + " / " + uid);
5547                }
5548            }
5549        } else {
5550            throw new SecurityException(callerUid + " cannot kill app process: " +
5551                    processName);
5552        }
5553    }
5554
5555    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5556        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5557                false, true, false, false, UserHandle.getUserId(uid), reason);
5558        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5559                Uri.fromParts("package", packageName, null));
5560        if (!mProcessesReady) {
5561            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5562                    | Intent.FLAG_RECEIVER_FOREGROUND);
5563        }
5564        intent.putExtra(Intent.EXTRA_UID, uid);
5565        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5566        broadcastIntentLocked(null, null, intent,
5567                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5568                false, false,
5569                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5570    }
5571
5572    private void forceStopUserLocked(int userId, String reason) {
5573        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5574        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5575        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5576                | Intent.FLAG_RECEIVER_FOREGROUND);
5577        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5578        broadcastIntentLocked(null, null, intent,
5579                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5580                false, false,
5581                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5582    }
5583
5584    private final boolean killPackageProcessesLocked(String packageName, int appId,
5585            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5586            boolean doit, boolean evenPersistent, String reason) {
5587        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5588
5589        // Remove all processes this package may have touched: all with the
5590        // same UID (except for the system or root user), and all whose name
5591        // matches the package name.
5592        final int NP = mProcessNames.getMap().size();
5593        for (int ip=0; ip<NP; ip++) {
5594            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5595            final int NA = apps.size();
5596            for (int ia=0; ia<NA; ia++) {
5597                ProcessRecord app = apps.valueAt(ia);
5598                if (app.persistent && !evenPersistent) {
5599                    // we don't kill persistent processes
5600                    continue;
5601                }
5602                if (app.removed) {
5603                    if (doit) {
5604                        procs.add(app);
5605                    }
5606                    continue;
5607                }
5608
5609                // Skip process if it doesn't meet our oom adj requirement.
5610                if (app.setAdj < minOomAdj) {
5611                    continue;
5612                }
5613
5614                // If no package is specified, we call all processes under the
5615                // give user id.
5616                if (packageName == null) {
5617                    if (app.userId != userId) {
5618                        continue;
5619                    }
5620                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5621                        continue;
5622                    }
5623                // Package has been specified, we want to hit all processes
5624                // that match it.  We need to qualify this by the processes
5625                // that are running under the specified app and user ID.
5626                } else {
5627                    final boolean isDep = app.pkgDeps != null
5628                            && app.pkgDeps.contains(packageName);
5629                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5630                        continue;
5631                    }
5632                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5633                        continue;
5634                    }
5635                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5636                        continue;
5637                    }
5638                }
5639
5640                // Process has passed all conditions, kill it!
5641                if (!doit) {
5642                    return true;
5643                }
5644                app.removed = true;
5645                procs.add(app);
5646            }
5647        }
5648
5649        int N = procs.size();
5650        for (int i=0; i<N; i++) {
5651            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5652        }
5653        updateOomAdjLocked();
5654        return N > 0;
5655    }
5656
5657    private final boolean forceStopPackageLocked(String name, int appId,
5658            boolean callerWillRestart, boolean purgeCache, boolean doit,
5659            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5660        int i;
5661        int N;
5662
5663        if (userId == UserHandle.USER_ALL && name == null) {
5664            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5665        }
5666
5667        if (appId < 0 && name != null) {
5668            try {
5669                appId = UserHandle.getAppId(
5670                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5671            } catch (RemoteException e) {
5672            }
5673        }
5674
5675        if (doit) {
5676            if (name != null) {
5677                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5678                        + " user=" + userId + ": " + reason);
5679            } else {
5680                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5681            }
5682
5683            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5684            for (int ip=pmap.size()-1; ip>=0; ip--) {
5685                SparseArray<Long> ba = pmap.valueAt(ip);
5686                for (i=ba.size()-1; i>=0; i--) {
5687                    boolean remove = false;
5688                    final int entUid = ba.keyAt(i);
5689                    if (name != null) {
5690                        if (userId == UserHandle.USER_ALL) {
5691                            if (UserHandle.getAppId(entUid) == appId) {
5692                                remove = true;
5693                            }
5694                        } else {
5695                            if (entUid == UserHandle.getUid(userId, appId)) {
5696                                remove = true;
5697                            }
5698                        }
5699                    } else if (UserHandle.getUserId(entUid) == userId) {
5700                        remove = true;
5701                    }
5702                    if (remove) {
5703                        ba.removeAt(i);
5704                    }
5705                }
5706                if (ba.size() == 0) {
5707                    pmap.removeAt(ip);
5708                }
5709            }
5710        }
5711
5712        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5713                -100, callerWillRestart, true, doit, evenPersistent,
5714                name == null ? ("stop user " + userId) : ("stop " + name));
5715
5716        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5717            if (!doit) {
5718                return true;
5719            }
5720            didSomething = true;
5721        }
5722
5723        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5724            if (!doit) {
5725                return true;
5726            }
5727            didSomething = true;
5728        }
5729
5730        if (name == null) {
5731            // Remove all sticky broadcasts from this user.
5732            mStickyBroadcasts.remove(userId);
5733        }
5734
5735        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5736        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5737                userId, providers)) {
5738            if (!doit) {
5739                return true;
5740            }
5741            didSomething = true;
5742        }
5743        N = providers.size();
5744        for (i=0; i<N; i++) {
5745            removeDyingProviderLocked(null, providers.get(i), true);
5746        }
5747
5748        // Remove transient permissions granted from/to this package/user
5749        removeUriPermissionsForPackageLocked(name, userId, false);
5750
5751        if (name == null || uninstalling) {
5752            // Remove pending intents.  For now we only do this when force
5753            // stopping users, because we have some problems when doing this
5754            // for packages -- app widgets are not currently cleaned up for
5755            // such packages, so they can be left with bad pending intents.
5756            if (mIntentSenderRecords.size() > 0) {
5757                Iterator<WeakReference<PendingIntentRecord>> it
5758                        = mIntentSenderRecords.values().iterator();
5759                while (it.hasNext()) {
5760                    WeakReference<PendingIntentRecord> wpir = it.next();
5761                    if (wpir == null) {
5762                        it.remove();
5763                        continue;
5764                    }
5765                    PendingIntentRecord pir = wpir.get();
5766                    if (pir == null) {
5767                        it.remove();
5768                        continue;
5769                    }
5770                    if (name == null) {
5771                        // Stopping user, remove all objects for the user.
5772                        if (pir.key.userId != userId) {
5773                            // Not the same user, skip it.
5774                            continue;
5775                        }
5776                    } else {
5777                        if (UserHandle.getAppId(pir.uid) != appId) {
5778                            // Different app id, skip it.
5779                            continue;
5780                        }
5781                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5782                            // Different user, skip it.
5783                            continue;
5784                        }
5785                        if (!pir.key.packageName.equals(name)) {
5786                            // Different package, skip it.
5787                            continue;
5788                        }
5789                    }
5790                    if (!doit) {
5791                        return true;
5792                    }
5793                    didSomething = true;
5794                    it.remove();
5795                    pir.canceled = true;
5796                    if (pir.key.activity != null) {
5797                        pir.key.activity.pendingResults.remove(pir.ref);
5798                    }
5799                }
5800            }
5801        }
5802
5803        if (doit) {
5804            if (purgeCache && name != null) {
5805                AttributeCache ac = AttributeCache.instance();
5806                if (ac != null) {
5807                    ac.removePackage(name);
5808                }
5809            }
5810            if (mBooted) {
5811                mStackSupervisor.resumeTopActivitiesLocked();
5812                mStackSupervisor.scheduleIdleLocked();
5813            }
5814        }
5815
5816        return didSomething;
5817    }
5818
5819    private final boolean removeProcessLocked(ProcessRecord app,
5820            boolean callerWillRestart, boolean allowRestart, String reason) {
5821        final String name = app.processName;
5822        final int uid = app.uid;
5823        if (DEBUG_PROCESSES) Slog.d(
5824            TAG, "Force removing proc " + app.toShortString() + " (" + name
5825            + "/" + uid + ")");
5826
5827        mProcessNames.remove(name, uid);
5828        mIsolatedProcesses.remove(app.uid);
5829        if (mHeavyWeightProcess == app) {
5830            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5831                    mHeavyWeightProcess.userId, 0));
5832            mHeavyWeightProcess = null;
5833        }
5834        boolean needRestart = false;
5835        if (app.pid > 0 && app.pid != MY_PID) {
5836            int pid = app.pid;
5837            synchronized (mPidsSelfLocked) {
5838                mPidsSelfLocked.remove(pid);
5839                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5840            }
5841            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5842            if (app.isolated) {
5843                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5844            }
5845            app.kill(reason, true);
5846            handleAppDiedLocked(app, true, allowRestart);
5847            removeLruProcessLocked(app);
5848
5849            if (app.persistent && !app.isolated) {
5850                if (!callerWillRestart) {
5851                    addAppLocked(app.info, false, null /* ABI override */);
5852                } else {
5853                    needRestart = true;
5854                }
5855            }
5856        } else {
5857            mRemovedProcesses.add(app);
5858        }
5859
5860        return needRestart;
5861    }
5862
5863    private final void processStartTimedOutLocked(ProcessRecord app) {
5864        final int pid = app.pid;
5865        boolean gone = false;
5866        synchronized (mPidsSelfLocked) {
5867            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5868            if (knownApp != null && knownApp.thread == null) {
5869                mPidsSelfLocked.remove(pid);
5870                gone = true;
5871            }
5872        }
5873
5874        if (gone) {
5875            Slog.w(TAG, "Process " + app + " failed to attach");
5876            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5877                    pid, app.uid, app.processName);
5878            mProcessNames.remove(app.processName, app.uid);
5879            mIsolatedProcesses.remove(app.uid);
5880            if (mHeavyWeightProcess == app) {
5881                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5882                        mHeavyWeightProcess.userId, 0));
5883                mHeavyWeightProcess = null;
5884            }
5885            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5886            if (app.isolated) {
5887                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5888            }
5889            // Take care of any launching providers waiting for this process.
5890            checkAppInLaunchingProvidersLocked(app, true);
5891            // Take care of any services that are waiting for the process.
5892            mServices.processStartTimedOutLocked(app);
5893            app.kill("start timeout", true);
5894            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5895                Slog.w(TAG, "Unattached app died before backup, skipping");
5896                try {
5897                    IBackupManager bm = IBackupManager.Stub.asInterface(
5898                            ServiceManager.getService(Context.BACKUP_SERVICE));
5899                    bm.agentDisconnected(app.info.packageName);
5900                } catch (RemoteException e) {
5901                    // Can't happen; the backup manager is local
5902                }
5903            }
5904            if (isPendingBroadcastProcessLocked(pid)) {
5905                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5906                skipPendingBroadcastLocked(pid);
5907            }
5908        } else {
5909            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5910        }
5911    }
5912
5913    private final boolean attachApplicationLocked(IApplicationThread thread,
5914            int pid) {
5915
5916        // Find the application record that is being attached...  either via
5917        // the pid if we are running in multiple processes, or just pull the
5918        // next app record if we are emulating process with anonymous threads.
5919        ProcessRecord app;
5920        if (pid != MY_PID && pid >= 0) {
5921            synchronized (mPidsSelfLocked) {
5922                app = mPidsSelfLocked.get(pid);
5923            }
5924        } else {
5925            app = null;
5926        }
5927
5928        if (app == null) {
5929            Slog.w(TAG, "No pending application record for pid " + pid
5930                    + " (IApplicationThread " + thread + "); dropping process");
5931            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5932            if (pid > 0 && pid != MY_PID) {
5933                Process.killProcessQuiet(pid);
5934                //TODO: Process.killProcessGroup(app.info.uid, pid);
5935            } else {
5936                try {
5937                    thread.scheduleExit();
5938                } catch (Exception e) {
5939                    // Ignore exceptions.
5940                }
5941            }
5942            return false;
5943        }
5944
5945        // If this application record is still attached to a previous
5946        // process, clean it up now.
5947        if (app.thread != null) {
5948            handleAppDiedLocked(app, true, true);
5949        }
5950
5951        // Tell the process all about itself.
5952
5953        if (localLOGV) Slog.v(
5954                TAG, "Binding process pid " + pid + " to record " + app);
5955
5956        final String processName = app.processName;
5957        try {
5958            AppDeathRecipient adr = new AppDeathRecipient(
5959                    app, pid, thread);
5960            thread.asBinder().linkToDeath(adr, 0);
5961            app.deathRecipient = adr;
5962        } catch (RemoteException e) {
5963            app.resetPackageList(mProcessStats);
5964            startProcessLocked(app, "link fail", processName);
5965            return false;
5966        }
5967
5968        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5969
5970        app.makeActive(thread, mProcessStats);
5971        app.curAdj = app.setAdj = -100;
5972        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5973        app.forcingToForeground = null;
5974        updateProcessForegroundLocked(app, false, false);
5975        app.hasShownUi = false;
5976        app.debugging = false;
5977        app.cached = false;
5978
5979        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5980
5981        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5982        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5983
5984        if (!normalMode) {
5985            Slog.i(TAG, "Launching preboot mode app: " + app);
5986        }
5987
5988        if (localLOGV) Slog.v(
5989            TAG, "New app record " + app
5990            + " thread=" + thread.asBinder() + " pid=" + pid);
5991        try {
5992            int testMode = IApplicationThread.DEBUG_OFF;
5993            if (mDebugApp != null && mDebugApp.equals(processName)) {
5994                testMode = mWaitForDebugger
5995                    ? IApplicationThread.DEBUG_WAIT
5996                    : IApplicationThread.DEBUG_ON;
5997                app.debugging = true;
5998                if (mDebugTransient) {
5999                    mDebugApp = mOrigDebugApp;
6000                    mWaitForDebugger = mOrigWaitForDebugger;
6001                }
6002            }
6003            String profileFile = app.instrumentationProfileFile;
6004            ParcelFileDescriptor profileFd = null;
6005            int samplingInterval = 0;
6006            boolean profileAutoStop = false;
6007            if (mProfileApp != null && mProfileApp.equals(processName)) {
6008                mProfileProc = app;
6009                profileFile = mProfileFile;
6010                profileFd = mProfileFd;
6011                samplingInterval = mSamplingInterval;
6012                profileAutoStop = mAutoStopProfiler;
6013            }
6014            boolean enableOpenGlTrace = false;
6015            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6016                enableOpenGlTrace = true;
6017                mOpenGlTraceApp = null;
6018            }
6019
6020            // If the app is being launched for restore or full backup, set it up specially
6021            boolean isRestrictedBackupMode = false;
6022            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6023                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6024                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6025                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6026            }
6027
6028            ensurePackageDexOpt(app.instrumentationInfo != null
6029                    ? app.instrumentationInfo.packageName
6030                    : app.info.packageName);
6031            if (app.instrumentationClass != null) {
6032                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6033            }
6034            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6035                    + processName + " with config " + mConfiguration);
6036            ApplicationInfo appInfo = app.instrumentationInfo != null
6037                    ? app.instrumentationInfo : app.info;
6038            app.compat = compatibilityInfoForPackageLocked(appInfo);
6039            if (profileFd != null) {
6040                profileFd = profileFd.dup();
6041            }
6042            ProfilerInfo profilerInfo = profileFile == null ? null
6043                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6044            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6045                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6046                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6047                    isRestrictedBackupMode || !normalMode, app.persistent,
6048                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6049                    mCoreSettingsObserver.getCoreSettingsLocked());
6050            updateLruProcessLocked(app, false, null);
6051            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6052        } catch (Exception e) {
6053            // todo: Yikes!  What should we do?  For now we will try to
6054            // start another process, but that could easily get us in
6055            // an infinite loop of restarting processes...
6056            Slog.w(TAG, "Exception thrown during bind!", e);
6057
6058            app.resetPackageList(mProcessStats);
6059            app.unlinkDeathRecipient();
6060            startProcessLocked(app, "bind fail", processName);
6061            return false;
6062        }
6063
6064        // Remove this record from the list of starting applications.
6065        mPersistentStartingProcesses.remove(app);
6066        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6067                "Attach application locked removing on hold: " + app);
6068        mProcessesOnHold.remove(app);
6069
6070        boolean badApp = false;
6071        boolean didSomething = false;
6072
6073        // See if the top visible activity is waiting to run in this process...
6074        if (normalMode) {
6075            try {
6076                if (mStackSupervisor.attachApplicationLocked(app)) {
6077                    didSomething = true;
6078                }
6079            } catch (Exception e) {
6080                badApp = true;
6081            }
6082        }
6083
6084        // Find any services that should be running in this process...
6085        if (!badApp) {
6086            try {
6087                didSomething |= mServices.attachApplicationLocked(app, processName);
6088            } catch (Exception e) {
6089                badApp = true;
6090            }
6091        }
6092
6093        // Check if a next-broadcast receiver is in this process...
6094        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6095            try {
6096                didSomething |= sendPendingBroadcastsLocked(app);
6097            } catch (Exception e) {
6098                // If the app died trying to launch the receiver we declare it 'bad'
6099                badApp = true;
6100            }
6101        }
6102
6103        // Check whether the next backup agent is in this process...
6104        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6105            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6106            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6107            try {
6108                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6109                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6110                        mBackupTarget.backupMode);
6111            } catch (Exception e) {
6112                Slog.w(TAG, "Exception scheduling backup agent creation: ");
6113                e.printStackTrace();
6114            }
6115        }
6116
6117        if (badApp) {
6118            // todo: Also need to kill application to deal with all
6119            // kinds of exceptions.
6120            handleAppDiedLocked(app, false, true);
6121            return false;
6122        }
6123
6124        if (!didSomething) {
6125            updateOomAdjLocked();
6126        }
6127
6128        return true;
6129    }
6130
6131    @Override
6132    public final void attachApplication(IApplicationThread thread) {
6133        synchronized (this) {
6134            int callingPid = Binder.getCallingPid();
6135            final long origId = Binder.clearCallingIdentity();
6136            attachApplicationLocked(thread, callingPid);
6137            Binder.restoreCallingIdentity(origId);
6138        }
6139    }
6140
6141    @Override
6142    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6143        final long origId = Binder.clearCallingIdentity();
6144        synchronized (this) {
6145            ActivityStack stack = ActivityRecord.getStackLocked(token);
6146            if (stack != null) {
6147                ActivityRecord r =
6148                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6149                if (stopProfiling) {
6150                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6151                        try {
6152                            mProfileFd.close();
6153                        } catch (IOException e) {
6154                        }
6155                        clearProfilerLocked();
6156                    }
6157                }
6158            }
6159        }
6160        Binder.restoreCallingIdentity(origId);
6161    }
6162
6163    void postEnableScreenAfterBootLocked() {
6164        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
6165    }
6166
6167    void enableScreenAfterBoot() {
6168        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6169                SystemClock.uptimeMillis());
6170        mWindowManager.enableScreenAfterBoot();
6171
6172        synchronized (this) {
6173            updateEventDispatchingLocked();
6174        }
6175    }
6176
6177    @Override
6178    public void showBootMessage(final CharSequence msg, final boolean always) {
6179        enforceNotIsolatedCaller("showBootMessage");
6180        mWindowManager.showBootMessage(msg, always);
6181    }
6182
6183    @Override
6184    public void keyguardWaitingForActivityDrawn() {
6185        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6186        final long token = Binder.clearCallingIdentity();
6187        try {
6188            synchronized (this) {
6189                if (DEBUG_LOCKSCREEN) logLockScreen("");
6190                mWindowManager.keyguardWaitingForActivityDrawn();
6191            }
6192        } finally {
6193            Binder.restoreCallingIdentity(token);
6194        }
6195    }
6196
6197    final void finishBooting() {
6198        // Register receivers to handle package update events
6199        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
6200
6201        // Let system services know.
6202        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6203
6204        synchronized (this) {
6205            // Ensure that any processes we had put on hold are now started
6206            // up.
6207            final int NP = mProcessesOnHold.size();
6208            if (NP > 0) {
6209                ArrayList<ProcessRecord> procs =
6210                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6211                for (int ip=0; ip<NP; ip++) {
6212                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6213                            + procs.get(ip));
6214                    startProcessLocked(procs.get(ip), "on-hold", null);
6215                }
6216            }
6217
6218            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6219                // Start looking for apps that are abusing wake locks.
6220                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6221                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6222                // Tell anyone interested that we are done booting!
6223                SystemProperties.set("sys.boot_completed", "1");
6224                SystemProperties.set("dev.bootcomplete", "1");
6225                for (int i=0; i<mStartedUsers.size(); i++) {
6226                    UserStartedState uss = mStartedUsers.valueAt(i);
6227                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6228                        uss.mState = UserStartedState.STATE_RUNNING;
6229                        final int userId = mStartedUsers.keyAt(i);
6230                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6231                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6232                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6233                        broadcastIntentLocked(null, null, intent, null,
6234                                new IIntentReceiver.Stub() {
6235                                    @Override
6236                                    public void performReceive(Intent intent, int resultCode,
6237                                            String data, Bundle extras, boolean ordered,
6238                                            boolean sticky, int sendingUser) {
6239                                        synchronized (ActivityManagerService.this) {
6240                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6241                                                    true, false);
6242                                        }
6243                                    }
6244                                },
6245                                0, null, null,
6246                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6247                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6248                                userId);
6249                    }
6250                }
6251                scheduleStartProfilesLocked();
6252            }
6253        }
6254    }
6255
6256    final void ensureBootCompleted() {
6257        boolean booting;
6258        boolean enableScreen;
6259        synchronized (this) {
6260            booting = mBooting;
6261            mBooting = false;
6262            enableScreen = !mBooted;
6263            mBooted = true;
6264        }
6265
6266        if (booting) {
6267            finishBooting();
6268        }
6269
6270        if (enableScreen) {
6271            enableScreenAfterBoot();
6272        }
6273    }
6274
6275    @Override
6276    public final void activityResumed(IBinder token) {
6277        final long origId = Binder.clearCallingIdentity();
6278        synchronized(this) {
6279            ActivityStack stack = ActivityRecord.getStackLocked(token);
6280            if (stack != null) {
6281                ActivityRecord.activityResumedLocked(token);
6282            }
6283        }
6284        Binder.restoreCallingIdentity(origId);
6285    }
6286
6287    @Override
6288    public final void activityPaused(IBinder token) {
6289        final long origId = Binder.clearCallingIdentity();
6290        synchronized(this) {
6291            ActivityStack stack = ActivityRecord.getStackLocked(token);
6292            if (stack != null) {
6293                stack.activityPausedLocked(token, false);
6294            }
6295        }
6296        Binder.restoreCallingIdentity(origId);
6297    }
6298
6299    @Override
6300    public final void activityStopped(IBinder token, Bundle icicle,
6301            PersistableBundle persistentState, CharSequence description) {
6302        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6303
6304        // Refuse possible leaked file descriptors
6305        if (icicle != null && icicle.hasFileDescriptors()) {
6306            throw new IllegalArgumentException("File descriptors passed in Bundle");
6307        }
6308
6309        final long origId = Binder.clearCallingIdentity();
6310
6311        synchronized (this) {
6312            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6313            if (r != null) {
6314                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6315            }
6316        }
6317
6318        trimApplications();
6319
6320        Binder.restoreCallingIdentity(origId);
6321    }
6322
6323    @Override
6324    public final void activityDestroyed(IBinder token) {
6325        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6326        synchronized (this) {
6327            ActivityStack stack = ActivityRecord.getStackLocked(token);
6328            if (stack != null) {
6329                stack.activityDestroyedLocked(token);
6330            }
6331        }
6332    }
6333
6334    @Override
6335    public final void backgroundResourcesReleased(IBinder token) {
6336        final long origId = Binder.clearCallingIdentity();
6337        try {
6338            synchronized (this) {
6339                ActivityStack stack = ActivityRecord.getStackLocked(token);
6340                if (stack != null) {
6341                    stack.backgroundResourcesReleased(token);
6342                }
6343            }
6344        } finally {
6345            Binder.restoreCallingIdentity(origId);
6346        }
6347    }
6348
6349    @Override
6350    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6351        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6352    }
6353
6354    @Override
6355    public final void notifyEnterAnimationComplete(IBinder token) {
6356        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6357    }
6358
6359    @Override
6360    public String getCallingPackage(IBinder token) {
6361        synchronized (this) {
6362            ActivityRecord r = getCallingRecordLocked(token);
6363            return r != null ? r.info.packageName : null;
6364        }
6365    }
6366
6367    @Override
6368    public ComponentName getCallingActivity(IBinder token) {
6369        synchronized (this) {
6370            ActivityRecord r = getCallingRecordLocked(token);
6371            return r != null ? r.intent.getComponent() : null;
6372        }
6373    }
6374
6375    private ActivityRecord getCallingRecordLocked(IBinder token) {
6376        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6377        if (r == null) {
6378            return null;
6379        }
6380        return r.resultTo;
6381    }
6382
6383    @Override
6384    public ComponentName getActivityClassForToken(IBinder token) {
6385        synchronized(this) {
6386            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6387            if (r == null) {
6388                return null;
6389            }
6390            return r.intent.getComponent();
6391        }
6392    }
6393
6394    @Override
6395    public String getPackageForToken(IBinder token) {
6396        synchronized(this) {
6397            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6398            if (r == null) {
6399                return null;
6400            }
6401            return r.packageName;
6402        }
6403    }
6404
6405    @Override
6406    public IIntentSender getIntentSender(int type,
6407            String packageName, IBinder token, String resultWho,
6408            int requestCode, Intent[] intents, String[] resolvedTypes,
6409            int flags, Bundle options, int userId) {
6410        enforceNotIsolatedCaller("getIntentSender");
6411        // Refuse possible leaked file descriptors
6412        if (intents != null) {
6413            if (intents.length < 1) {
6414                throw new IllegalArgumentException("Intents array length must be >= 1");
6415            }
6416            for (int i=0; i<intents.length; i++) {
6417                Intent intent = intents[i];
6418                if (intent != null) {
6419                    if (intent.hasFileDescriptors()) {
6420                        throw new IllegalArgumentException("File descriptors passed in Intent");
6421                    }
6422                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6423                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6424                        throw new IllegalArgumentException(
6425                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6426                    }
6427                    intents[i] = new Intent(intent);
6428                }
6429            }
6430            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6431                throw new IllegalArgumentException(
6432                        "Intent array length does not match resolvedTypes length");
6433            }
6434        }
6435        if (options != null) {
6436            if (options.hasFileDescriptors()) {
6437                throw new IllegalArgumentException("File descriptors passed in options");
6438            }
6439        }
6440
6441        synchronized(this) {
6442            int callingUid = Binder.getCallingUid();
6443            int origUserId = userId;
6444            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6445                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6446                    ALLOW_NON_FULL, "getIntentSender", null);
6447            if (origUserId == UserHandle.USER_CURRENT) {
6448                // We don't want to evaluate this until the pending intent is
6449                // actually executed.  However, we do want to always do the
6450                // security checking for it above.
6451                userId = UserHandle.USER_CURRENT;
6452            }
6453            try {
6454                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6455                    int uid = AppGlobals.getPackageManager()
6456                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6457                    if (!UserHandle.isSameApp(callingUid, uid)) {
6458                        String msg = "Permission Denial: getIntentSender() from pid="
6459                            + Binder.getCallingPid()
6460                            + ", uid=" + Binder.getCallingUid()
6461                            + ", (need uid=" + uid + ")"
6462                            + " is not allowed to send as package " + packageName;
6463                        Slog.w(TAG, msg);
6464                        throw new SecurityException(msg);
6465                    }
6466                }
6467
6468                return getIntentSenderLocked(type, packageName, callingUid, userId,
6469                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6470
6471            } catch (RemoteException e) {
6472                throw new SecurityException(e);
6473            }
6474        }
6475    }
6476
6477    IIntentSender getIntentSenderLocked(int type, String packageName,
6478            int callingUid, int userId, IBinder token, String resultWho,
6479            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6480            Bundle options) {
6481        if (DEBUG_MU)
6482            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6483        ActivityRecord activity = null;
6484        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6485            activity = ActivityRecord.isInStackLocked(token);
6486            if (activity == null) {
6487                return null;
6488            }
6489            if (activity.finishing) {
6490                return null;
6491            }
6492        }
6493
6494        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6495        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6496        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6497        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6498                |PendingIntent.FLAG_UPDATE_CURRENT);
6499
6500        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6501                type, packageName, activity, resultWho,
6502                requestCode, intents, resolvedTypes, flags, options, userId);
6503        WeakReference<PendingIntentRecord> ref;
6504        ref = mIntentSenderRecords.get(key);
6505        PendingIntentRecord rec = ref != null ? ref.get() : null;
6506        if (rec != null) {
6507            if (!cancelCurrent) {
6508                if (updateCurrent) {
6509                    if (rec.key.requestIntent != null) {
6510                        rec.key.requestIntent.replaceExtras(intents != null ?
6511                                intents[intents.length - 1] : null);
6512                    }
6513                    if (intents != null) {
6514                        intents[intents.length-1] = rec.key.requestIntent;
6515                        rec.key.allIntents = intents;
6516                        rec.key.allResolvedTypes = resolvedTypes;
6517                    } else {
6518                        rec.key.allIntents = null;
6519                        rec.key.allResolvedTypes = null;
6520                    }
6521                }
6522                return rec;
6523            }
6524            rec.canceled = true;
6525            mIntentSenderRecords.remove(key);
6526        }
6527        if (noCreate) {
6528            return rec;
6529        }
6530        rec = new PendingIntentRecord(this, key, callingUid);
6531        mIntentSenderRecords.put(key, rec.ref);
6532        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6533            if (activity.pendingResults == null) {
6534                activity.pendingResults
6535                        = new HashSet<WeakReference<PendingIntentRecord>>();
6536            }
6537            activity.pendingResults.add(rec.ref);
6538        }
6539        return rec;
6540    }
6541
6542    @Override
6543    public void cancelIntentSender(IIntentSender sender) {
6544        if (!(sender instanceof PendingIntentRecord)) {
6545            return;
6546        }
6547        synchronized(this) {
6548            PendingIntentRecord rec = (PendingIntentRecord)sender;
6549            try {
6550                int uid = AppGlobals.getPackageManager()
6551                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6552                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6553                    String msg = "Permission Denial: cancelIntentSender() from pid="
6554                        + Binder.getCallingPid()
6555                        + ", uid=" + Binder.getCallingUid()
6556                        + " is not allowed to cancel packges "
6557                        + rec.key.packageName;
6558                    Slog.w(TAG, msg);
6559                    throw new SecurityException(msg);
6560                }
6561            } catch (RemoteException e) {
6562                throw new SecurityException(e);
6563            }
6564            cancelIntentSenderLocked(rec, true);
6565        }
6566    }
6567
6568    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6569        rec.canceled = true;
6570        mIntentSenderRecords.remove(rec.key);
6571        if (cleanActivity && rec.key.activity != null) {
6572            rec.key.activity.pendingResults.remove(rec.ref);
6573        }
6574    }
6575
6576    @Override
6577    public String getPackageForIntentSender(IIntentSender pendingResult) {
6578        if (!(pendingResult instanceof PendingIntentRecord)) {
6579            return null;
6580        }
6581        try {
6582            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6583            return res.key.packageName;
6584        } catch (ClassCastException e) {
6585        }
6586        return null;
6587    }
6588
6589    @Override
6590    public int getUidForIntentSender(IIntentSender sender) {
6591        if (sender instanceof PendingIntentRecord) {
6592            try {
6593                PendingIntentRecord res = (PendingIntentRecord)sender;
6594                return res.uid;
6595            } catch (ClassCastException e) {
6596            }
6597        }
6598        return -1;
6599    }
6600
6601    @Override
6602    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6603        if (!(pendingResult instanceof PendingIntentRecord)) {
6604            return false;
6605        }
6606        try {
6607            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6608            if (res.key.allIntents == null) {
6609                return false;
6610            }
6611            for (int i=0; i<res.key.allIntents.length; i++) {
6612                Intent intent = res.key.allIntents[i];
6613                if (intent.getPackage() != null && intent.getComponent() != null) {
6614                    return false;
6615                }
6616            }
6617            return true;
6618        } catch (ClassCastException e) {
6619        }
6620        return false;
6621    }
6622
6623    @Override
6624    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6625        if (!(pendingResult instanceof PendingIntentRecord)) {
6626            return false;
6627        }
6628        try {
6629            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6630            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6631                return true;
6632            }
6633            return false;
6634        } catch (ClassCastException e) {
6635        }
6636        return false;
6637    }
6638
6639    @Override
6640    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6641        if (!(pendingResult instanceof PendingIntentRecord)) {
6642            return null;
6643        }
6644        try {
6645            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6646            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6647        } catch (ClassCastException e) {
6648        }
6649        return null;
6650    }
6651
6652    @Override
6653    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6654        if (!(pendingResult instanceof PendingIntentRecord)) {
6655            return null;
6656        }
6657        try {
6658            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6659            Intent intent = res.key.requestIntent;
6660            if (intent != null) {
6661                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6662                        || res.lastTagPrefix.equals(prefix))) {
6663                    return res.lastTag;
6664                }
6665                res.lastTagPrefix = prefix;
6666                StringBuilder sb = new StringBuilder(128);
6667                if (prefix != null) {
6668                    sb.append(prefix);
6669                }
6670                if (intent.getAction() != null) {
6671                    sb.append(intent.getAction());
6672                } else if (intent.getComponent() != null) {
6673                    intent.getComponent().appendShortString(sb);
6674                } else {
6675                    sb.append("?");
6676                }
6677                return res.lastTag = sb.toString();
6678            }
6679        } catch (ClassCastException e) {
6680        }
6681        return null;
6682    }
6683
6684    @Override
6685    public void setProcessLimit(int max) {
6686        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6687                "setProcessLimit()");
6688        synchronized (this) {
6689            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6690            mProcessLimitOverride = max;
6691        }
6692        trimApplications();
6693    }
6694
6695    @Override
6696    public int getProcessLimit() {
6697        synchronized (this) {
6698            return mProcessLimitOverride;
6699        }
6700    }
6701
6702    void foregroundTokenDied(ForegroundToken token) {
6703        synchronized (ActivityManagerService.this) {
6704            synchronized (mPidsSelfLocked) {
6705                ForegroundToken cur
6706                    = mForegroundProcesses.get(token.pid);
6707                if (cur != token) {
6708                    return;
6709                }
6710                mForegroundProcesses.remove(token.pid);
6711                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6712                if (pr == null) {
6713                    return;
6714                }
6715                pr.forcingToForeground = null;
6716                updateProcessForegroundLocked(pr, false, false);
6717            }
6718            updateOomAdjLocked();
6719        }
6720    }
6721
6722    @Override
6723    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6724        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6725                "setProcessForeground()");
6726        synchronized(this) {
6727            boolean changed = false;
6728
6729            synchronized (mPidsSelfLocked) {
6730                ProcessRecord pr = mPidsSelfLocked.get(pid);
6731                if (pr == null && isForeground) {
6732                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6733                    return;
6734                }
6735                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6736                if (oldToken != null) {
6737                    oldToken.token.unlinkToDeath(oldToken, 0);
6738                    mForegroundProcesses.remove(pid);
6739                    if (pr != null) {
6740                        pr.forcingToForeground = null;
6741                    }
6742                    changed = true;
6743                }
6744                if (isForeground && token != null) {
6745                    ForegroundToken newToken = new ForegroundToken() {
6746                        @Override
6747                        public void binderDied() {
6748                            foregroundTokenDied(this);
6749                        }
6750                    };
6751                    newToken.pid = pid;
6752                    newToken.token = token;
6753                    try {
6754                        token.linkToDeath(newToken, 0);
6755                        mForegroundProcesses.put(pid, newToken);
6756                        pr.forcingToForeground = token;
6757                        changed = true;
6758                    } catch (RemoteException e) {
6759                        // If the process died while doing this, we will later
6760                        // do the cleanup with the process death link.
6761                    }
6762                }
6763            }
6764
6765            if (changed) {
6766                updateOomAdjLocked();
6767            }
6768        }
6769    }
6770
6771    // =========================================================
6772    // PERMISSIONS
6773    // =========================================================
6774
6775    static class PermissionController extends IPermissionController.Stub {
6776        ActivityManagerService mActivityManagerService;
6777        PermissionController(ActivityManagerService activityManagerService) {
6778            mActivityManagerService = activityManagerService;
6779        }
6780
6781        @Override
6782        public boolean checkPermission(String permission, int pid, int uid) {
6783            return mActivityManagerService.checkPermission(permission, pid,
6784                    uid) == PackageManager.PERMISSION_GRANTED;
6785        }
6786    }
6787
6788    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6789        @Override
6790        public int checkComponentPermission(String permission, int pid, int uid,
6791                int owningUid, boolean exported) {
6792            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6793                    owningUid, exported);
6794        }
6795
6796        @Override
6797        public Object getAMSLock() {
6798            return ActivityManagerService.this;
6799        }
6800    }
6801
6802    /**
6803     * This can be called with or without the global lock held.
6804     */
6805    int checkComponentPermission(String permission, int pid, int uid,
6806            int owningUid, boolean exported) {
6807        // We might be performing an operation on behalf of an indirect binder
6808        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6809        // client identity accordingly before proceeding.
6810        Identity tlsIdentity = sCallerIdentity.get();
6811        if (tlsIdentity != null) {
6812            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6813                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6814            uid = tlsIdentity.uid;
6815            pid = tlsIdentity.pid;
6816        }
6817
6818        if (pid == MY_PID) {
6819            return PackageManager.PERMISSION_GRANTED;
6820        }
6821
6822        return ActivityManager.checkComponentPermission(permission, uid,
6823                owningUid, exported);
6824    }
6825
6826    /**
6827     * As the only public entry point for permissions checking, this method
6828     * can enforce the semantic that requesting a check on a null global
6829     * permission is automatically denied.  (Internally a null permission
6830     * string is used when calling {@link #checkComponentPermission} in cases
6831     * when only uid-based security is needed.)
6832     *
6833     * This can be called with or without the global lock held.
6834     */
6835    @Override
6836    public int checkPermission(String permission, int pid, int uid) {
6837        if (permission == null) {
6838            return PackageManager.PERMISSION_DENIED;
6839        }
6840        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6841    }
6842
6843    /**
6844     * Binder IPC calls go through the public entry point.
6845     * This can be called with or without the global lock held.
6846     */
6847    int checkCallingPermission(String permission) {
6848        return checkPermission(permission,
6849                Binder.getCallingPid(),
6850                UserHandle.getAppId(Binder.getCallingUid()));
6851    }
6852
6853    /**
6854     * This can be called with or without the global lock held.
6855     */
6856    void enforceCallingPermission(String permission, String func) {
6857        if (checkCallingPermission(permission)
6858                == PackageManager.PERMISSION_GRANTED) {
6859            return;
6860        }
6861
6862        String msg = "Permission Denial: " + func + " from pid="
6863                + Binder.getCallingPid()
6864                + ", uid=" + Binder.getCallingUid()
6865                + " requires " + permission;
6866        Slog.w(TAG, msg);
6867        throw new SecurityException(msg);
6868    }
6869
6870    /**
6871     * Determine if UID is holding permissions required to access {@link Uri} in
6872     * the given {@link ProviderInfo}. Final permission checking is always done
6873     * in {@link ContentProvider}.
6874     */
6875    private final boolean checkHoldingPermissionsLocked(
6876            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6877        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6878                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6879        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6880            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6881                    != PERMISSION_GRANTED) {
6882                return false;
6883            }
6884        }
6885        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6886    }
6887
6888    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6889            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6890        if (pi.applicationInfo.uid == uid) {
6891            return true;
6892        } else if (!pi.exported) {
6893            return false;
6894        }
6895
6896        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6897        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6898        try {
6899            // check if target holds top-level <provider> permissions
6900            if (!readMet && pi.readPermission != null && considerUidPermissions
6901                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6902                readMet = true;
6903            }
6904            if (!writeMet && pi.writePermission != null && considerUidPermissions
6905                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6906                writeMet = true;
6907            }
6908
6909            // track if unprotected read/write is allowed; any denied
6910            // <path-permission> below removes this ability
6911            boolean allowDefaultRead = pi.readPermission == null;
6912            boolean allowDefaultWrite = pi.writePermission == null;
6913
6914            // check if target holds any <path-permission> that match uri
6915            final PathPermission[] pps = pi.pathPermissions;
6916            if (pps != null) {
6917                final String path = grantUri.uri.getPath();
6918                int i = pps.length;
6919                while (i > 0 && (!readMet || !writeMet)) {
6920                    i--;
6921                    PathPermission pp = pps[i];
6922                    if (pp.match(path)) {
6923                        if (!readMet) {
6924                            final String pprperm = pp.getReadPermission();
6925                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6926                                    + pprperm + " for " + pp.getPath()
6927                                    + ": match=" + pp.match(path)
6928                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6929                            if (pprperm != null) {
6930                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6931                                        == PERMISSION_GRANTED) {
6932                                    readMet = true;
6933                                } else {
6934                                    allowDefaultRead = false;
6935                                }
6936                            }
6937                        }
6938                        if (!writeMet) {
6939                            final String ppwperm = pp.getWritePermission();
6940                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6941                                    + ppwperm + " for " + pp.getPath()
6942                                    + ": match=" + pp.match(path)
6943                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6944                            if (ppwperm != null) {
6945                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6946                                        == PERMISSION_GRANTED) {
6947                                    writeMet = true;
6948                                } else {
6949                                    allowDefaultWrite = false;
6950                                }
6951                            }
6952                        }
6953                    }
6954                }
6955            }
6956
6957            // grant unprotected <provider> read/write, if not blocked by
6958            // <path-permission> above
6959            if (allowDefaultRead) readMet = true;
6960            if (allowDefaultWrite) writeMet = true;
6961
6962        } catch (RemoteException e) {
6963            return false;
6964        }
6965
6966        return readMet && writeMet;
6967    }
6968
6969    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6970        ProviderInfo pi = null;
6971        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6972        if (cpr != null) {
6973            pi = cpr.info;
6974        } else {
6975            try {
6976                pi = AppGlobals.getPackageManager().resolveContentProvider(
6977                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6978            } catch (RemoteException ex) {
6979            }
6980        }
6981        return pi;
6982    }
6983
6984    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6985        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6986        if (targetUris != null) {
6987            return targetUris.get(grantUri);
6988        }
6989        return null;
6990    }
6991
6992    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6993            String targetPkg, int targetUid, GrantUri grantUri) {
6994        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6995        if (targetUris == null) {
6996            targetUris = Maps.newArrayMap();
6997            mGrantedUriPermissions.put(targetUid, targetUris);
6998        }
6999
7000        UriPermission perm = targetUris.get(grantUri);
7001        if (perm == null) {
7002            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7003            targetUris.put(grantUri, perm);
7004        }
7005
7006        return perm;
7007    }
7008
7009    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7010            final int modeFlags) {
7011        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7012        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7013                : UriPermission.STRENGTH_OWNED;
7014
7015        // Root gets to do everything.
7016        if (uid == 0) {
7017            return true;
7018        }
7019
7020        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7021        if (perms == null) return false;
7022
7023        // First look for exact match
7024        final UriPermission exactPerm = perms.get(grantUri);
7025        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7026            return true;
7027        }
7028
7029        // No exact match, look for prefixes
7030        final int N = perms.size();
7031        for (int i = 0; i < N; i++) {
7032            final UriPermission perm = perms.valueAt(i);
7033            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7034                    && perm.getStrength(modeFlags) >= minStrength) {
7035                return true;
7036            }
7037        }
7038
7039        return false;
7040    }
7041
7042    /**
7043     * @param uri This uri must NOT contain an embedded userId.
7044     * @param userId The userId in which the uri is to be resolved.
7045     */
7046    @Override
7047    public int checkUriPermission(Uri uri, int pid, int uid,
7048            final int modeFlags, int userId) {
7049        enforceNotIsolatedCaller("checkUriPermission");
7050
7051        // Another redirected-binder-call permissions check as in
7052        // {@link checkComponentPermission}.
7053        Identity tlsIdentity = sCallerIdentity.get();
7054        if (tlsIdentity != null) {
7055            uid = tlsIdentity.uid;
7056            pid = tlsIdentity.pid;
7057        }
7058
7059        // Our own process gets to do everything.
7060        if (pid == MY_PID) {
7061            return PackageManager.PERMISSION_GRANTED;
7062        }
7063        synchronized (this) {
7064            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7065                    ? PackageManager.PERMISSION_GRANTED
7066                    : PackageManager.PERMISSION_DENIED;
7067        }
7068    }
7069
7070    /**
7071     * Check if the targetPkg can be granted permission to access uri by
7072     * the callingUid using the given modeFlags.  Throws a security exception
7073     * if callingUid is not allowed to do this.  Returns the uid of the target
7074     * if the URI permission grant should be performed; returns -1 if it is not
7075     * needed (for example targetPkg already has permission to access the URI).
7076     * If you already know the uid of the target, you can supply it in
7077     * lastTargetUid else set that to -1.
7078     */
7079    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7080            final int modeFlags, int lastTargetUid) {
7081        if (!Intent.isAccessUriMode(modeFlags)) {
7082            return -1;
7083        }
7084
7085        if (targetPkg != null) {
7086            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7087                    "Checking grant " + targetPkg + " permission to " + grantUri);
7088        }
7089
7090        final IPackageManager pm = AppGlobals.getPackageManager();
7091
7092        // If this is not a content: uri, we can't do anything with it.
7093        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7094            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7095                    "Can't grant URI permission for non-content URI: " + grantUri);
7096            return -1;
7097        }
7098
7099        final String authority = grantUri.uri.getAuthority();
7100        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7101        if (pi == null) {
7102            Slog.w(TAG, "No content provider found for permission check: " +
7103                    grantUri.uri.toSafeString());
7104            return -1;
7105        }
7106
7107        int targetUid = lastTargetUid;
7108        if (targetUid < 0 && targetPkg != null) {
7109            try {
7110                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7111                if (targetUid < 0) {
7112                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7113                            "Can't grant URI permission no uid for: " + targetPkg);
7114                    return -1;
7115                }
7116            } catch (RemoteException ex) {
7117                return -1;
7118            }
7119        }
7120
7121        if (targetUid >= 0) {
7122            // First...  does the target actually need this permission?
7123            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7124                // No need to grant the target this permission.
7125                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7126                        "Target " + targetPkg + " already has full permission to " + grantUri);
7127                return -1;
7128            }
7129        } else {
7130            // First...  there is no target package, so can anyone access it?
7131            boolean allowed = pi.exported;
7132            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7133                if (pi.readPermission != null) {
7134                    allowed = false;
7135                }
7136            }
7137            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7138                if (pi.writePermission != null) {
7139                    allowed = false;
7140                }
7141            }
7142            if (allowed) {
7143                return -1;
7144            }
7145        }
7146
7147        /* There is a special cross user grant if:
7148         * - The target is on another user.
7149         * - Apps on the current user can access the uri without any uid permissions.
7150         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7151         * grant uri permissions.
7152         */
7153        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7154                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7155                modeFlags, false /*without considering the uid permissions*/);
7156
7157        // Second...  is the provider allowing granting of URI permissions?
7158        if (!specialCrossUserGrant) {
7159            if (!pi.grantUriPermissions) {
7160                throw new SecurityException("Provider " + pi.packageName
7161                        + "/" + pi.name
7162                        + " does not allow granting of Uri permissions (uri "
7163                        + grantUri + ")");
7164            }
7165            if (pi.uriPermissionPatterns != null) {
7166                final int N = pi.uriPermissionPatterns.length;
7167                boolean allowed = false;
7168                for (int i=0; i<N; i++) {
7169                    if (pi.uriPermissionPatterns[i] != null
7170                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7171                        allowed = true;
7172                        break;
7173                    }
7174                }
7175                if (!allowed) {
7176                    throw new SecurityException("Provider " + pi.packageName
7177                            + "/" + pi.name
7178                            + " does not allow granting of permission to path of Uri "
7179                            + grantUri);
7180                }
7181            }
7182        }
7183
7184        // Third...  does the caller itself have permission to access
7185        // this uri?
7186        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7187            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7188                // Require they hold a strong enough Uri permission
7189                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7190                    throw new SecurityException("Uid " + callingUid
7191                            + " does not have permission to uri " + grantUri);
7192                }
7193            }
7194        }
7195        return targetUid;
7196    }
7197
7198    /**
7199     * @param uri This uri must NOT contain an embedded userId.
7200     * @param userId The userId in which the uri is to be resolved.
7201     */
7202    @Override
7203    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7204            final int modeFlags, int userId) {
7205        enforceNotIsolatedCaller("checkGrantUriPermission");
7206        synchronized(this) {
7207            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7208                    new GrantUri(userId, uri, false), modeFlags, -1);
7209        }
7210    }
7211
7212    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7213            final int modeFlags, UriPermissionOwner owner) {
7214        if (!Intent.isAccessUriMode(modeFlags)) {
7215            return;
7216        }
7217
7218        // So here we are: the caller has the assumed permission
7219        // to the uri, and the target doesn't.  Let's now give this to
7220        // the target.
7221
7222        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7223                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7224
7225        final String authority = grantUri.uri.getAuthority();
7226        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7227        if (pi == null) {
7228            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7229            return;
7230        }
7231
7232        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7233            grantUri.prefix = true;
7234        }
7235        final UriPermission perm = findOrCreateUriPermissionLocked(
7236                pi.packageName, targetPkg, targetUid, grantUri);
7237        perm.grantModes(modeFlags, owner);
7238    }
7239
7240    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7241            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7242        if (targetPkg == null) {
7243            throw new NullPointerException("targetPkg");
7244        }
7245        int targetUid;
7246        final IPackageManager pm = AppGlobals.getPackageManager();
7247        try {
7248            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7249        } catch (RemoteException ex) {
7250            return;
7251        }
7252
7253        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7254                targetUid);
7255        if (targetUid < 0) {
7256            return;
7257        }
7258
7259        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7260                owner);
7261    }
7262
7263    static class NeededUriGrants extends ArrayList<GrantUri> {
7264        final String targetPkg;
7265        final int targetUid;
7266        final int flags;
7267
7268        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7269            this.targetPkg = targetPkg;
7270            this.targetUid = targetUid;
7271            this.flags = flags;
7272        }
7273    }
7274
7275    /**
7276     * Like checkGrantUriPermissionLocked, but takes an Intent.
7277     */
7278    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7279            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7280        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7281                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7282                + " clip=" + (intent != null ? intent.getClipData() : null)
7283                + " from " + intent + "; flags=0x"
7284                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7285
7286        if (targetPkg == null) {
7287            throw new NullPointerException("targetPkg");
7288        }
7289
7290        if (intent == null) {
7291            return null;
7292        }
7293        Uri data = intent.getData();
7294        ClipData clip = intent.getClipData();
7295        if (data == null && clip == null) {
7296            return null;
7297        }
7298        // Default userId for uris in the intent (if they don't specify it themselves)
7299        int contentUserHint = intent.getContentUserHint();
7300        if (contentUserHint == UserHandle.USER_CURRENT) {
7301            contentUserHint = UserHandle.getUserId(callingUid);
7302        }
7303        final IPackageManager pm = AppGlobals.getPackageManager();
7304        int targetUid;
7305        if (needed != null) {
7306            targetUid = needed.targetUid;
7307        } else {
7308            try {
7309                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7310            } catch (RemoteException ex) {
7311                return null;
7312            }
7313            if (targetUid < 0) {
7314                if (DEBUG_URI_PERMISSION) {
7315                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7316                            + " on user " + targetUserId);
7317                }
7318                return null;
7319            }
7320        }
7321        if (data != null) {
7322            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7323            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7324                    targetUid);
7325            if (targetUid > 0) {
7326                if (needed == null) {
7327                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7328                }
7329                needed.add(grantUri);
7330            }
7331        }
7332        if (clip != null) {
7333            for (int i=0; i<clip.getItemCount(); i++) {
7334                Uri uri = clip.getItemAt(i).getUri();
7335                if (uri != null) {
7336                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7337                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7338                            targetUid);
7339                    if (targetUid > 0) {
7340                        if (needed == null) {
7341                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7342                        }
7343                        needed.add(grantUri);
7344                    }
7345                } else {
7346                    Intent clipIntent = clip.getItemAt(i).getIntent();
7347                    if (clipIntent != null) {
7348                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7349                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7350                        if (newNeeded != null) {
7351                            needed = newNeeded;
7352                        }
7353                    }
7354                }
7355            }
7356        }
7357
7358        return needed;
7359    }
7360
7361    /**
7362     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7363     */
7364    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7365            UriPermissionOwner owner) {
7366        if (needed != null) {
7367            for (int i=0; i<needed.size(); i++) {
7368                GrantUri grantUri = needed.get(i);
7369                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7370                        grantUri, needed.flags, owner);
7371            }
7372        }
7373    }
7374
7375    void grantUriPermissionFromIntentLocked(int callingUid,
7376            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7377        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7378                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7379        if (needed == null) {
7380            return;
7381        }
7382
7383        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7384    }
7385
7386    /**
7387     * @param uri This uri must NOT contain an embedded userId.
7388     * @param userId The userId in which the uri is to be resolved.
7389     */
7390    @Override
7391    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7392            final int modeFlags, int userId) {
7393        enforceNotIsolatedCaller("grantUriPermission");
7394        GrantUri grantUri = new GrantUri(userId, uri, false);
7395        synchronized(this) {
7396            final ProcessRecord r = getRecordForAppLocked(caller);
7397            if (r == null) {
7398                throw new SecurityException("Unable to find app for caller "
7399                        + caller
7400                        + " when granting permission to uri " + grantUri);
7401            }
7402            if (targetPkg == null) {
7403                throw new IllegalArgumentException("null target");
7404            }
7405            if (grantUri == null) {
7406                throw new IllegalArgumentException("null uri");
7407            }
7408
7409            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7410                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7411                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7412                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7413
7414            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7415                    UserHandle.getUserId(r.uid));
7416        }
7417    }
7418
7419    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7420        if (perm.modeFlags == 0) {
7421            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7422                    perm.targetUid);
7423            if (perms != null) {
7424                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7425                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7426
7427                perms.remove(perm.uri);
7428                if (perms.isEmpty()) {
7429                    mGrantedUriPermissions.remove(perm.targetUid);
7430                }
7431            }
7432        }
7433    }
7434
7435    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7436        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7437
7438        final IPackageManager pm = AppGlobals.getPackageManager();
7439        final String authority = grantUri.uri.getAuthority();
7440        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7441        if (pi == null) {
7442            Slog.w(TAG, "No content provider found for permission revoke: "
7443                    + grantUri.toSafeString());
7444            return;
7445        }
7446
7447        // Does the caller have this permission on the URI?
7448        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7449            // Have they don't have direct access to the URI, then revoke any URI
7450            // permissions that have been granted to them.
7451            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7452            if (perms != null) {
7453                boolean persistChanged = false;
7454                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7455                    final UriPermission perm = it.next();
7456                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7457                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7458                        if (DEBUG_URI_PERMISSION)
7459                            Slog.v(TAG,
7460                                    "Revoking " + perm.targetUid + " permission to " + perm.uri);
7461                        persistChanged |= perm.revokeModes(
7462                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7463                        if (perm.modeFlags == 0) {
7464                            it.remove();
7465                        }
7466                    }
7467                }
7468                if (perms.isEmpty()) {
7469                    mGrantedUriPermissions.remove(callingUid);
7470                }
7471                if (persistChanged) {
7472                    schedulePersistUriGrants();
7473                }
7474            }
7475            return;
7476        }
7477
7478        boolean persistChanged = false;
7479
7480        // Go through all of the permissions and remove any that match.
7481        int N = mGrantedUriPermissions.size();
7482        for (int i = 0; i < N; i++) {
7483            final int targetUid = mGrantedUriPermissions.keyAt(i);
7484            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7485
7486            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7487                final UriPermission perm = it.next();
7488                if (perm.uri.sourceUserId == grantUri.sourceUserId
7489                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7490                    if (DEBUG_URI_PERMISSION)
7491                        Slog.v(TAG,
7492                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7493                    persistChanged |= perm.revokeModes(
7494                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7495                    if (perm.modeFlags == 0) {
7496                        it.remove();
7497                    }
7498                }
7499            }
7500
7501            if (perms.isEmpty()) {
7502                mGrantedUriPermissions.remove(targetUid);
7503                N--;
7504                i--;
7505            }
7506        }
7507
7508        if (persistChanged) {
7509            schedulePersistUriGrants();
7510        }
7511    }
7512
7513    /**
7514     * @param uri This uri must NOT contain an embedded userId.
7515     * @param userId The userId in which the uri is to be resolved.
7516     */
7517    @Override
7518    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7519            int userId) {
7520        enforceNotIsolatedCaller("revokeUriPermission");
7521        synchronized(this) {
7522            final ProcessRecord r = getRecordForAppLocked(caller);
7523            if (r == null) {
7524                throw new SecurityException("Unable to find app for caller "
7525                        + caller
7526                        + " when revoking permission to uri " + uri);
7527            }
7528            if (uri == null) {
7529                Slog.w(TAG, "revokeUriPermission: null uri");
7530                return;
7531            }
7532
7533            if (!Intent.isAccessUriMode(modeFlags)) {
7534                return;
7535            }
7536
7537            final IPackageManager pm = AppGlobals.getPackageManager();
7538            final String authority = uri.getAuthority();
7539            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7540            if (pi == null) {
7541                Slog.w(TAG, "No content provider found for permission revoke: "
7542                        + uri.toSafeString());
7543                return;
7544            }
7545
7546            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7547        }
7548    }
7549
7550    /**
7551     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7552     * given package.
7553     *
7554     * @param packageName Package name to match, or {@code null} to apply to all
7555     *            packages.
7556     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7557     *            to all users.
7558     * @param persistable If persistable grants should be removed.
7559     */
7560    private void removeUriPermissionsForPackageLocked(
7561            String packageName, int userHandle, boolean persistable) {
7562        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7563            throw new IllegalArgumentException("Must narrow by either package or user");
7564        }
7565
7566        boolean persistChanged = false;
7567
7568        int N = mGrantedUriPermissions.size();
7569        for (int i = 0; i < N; i++) {
7570            final int targetUid = mGrantedUriPermissions.keyAt(i);
7571            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7572
7573            // Only inspect grants matching user
7574            if (userHandle == UserHandle.USER_ALL
7575                    || userHandle == UserHandle.getUserId(targetUid)) {
7576                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7577                    final UriPermission perm = it.next();
7578
7579                    // Only inspect grants matching package
7580                    if (packageName == null || perm.sourcePkg.equals(packageName)
7581                            || perm.targetPkg.equals(packageName)) {
7582                        persistChanged |= perm.revokeModes(
7583                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7584
7585                        // Only remove when no modes remain; any persisted grants
7586                        // will keep this alive.
7587                        if (perm.modeFlags == 0) {
7588                            it.remove();
7589                        }
7590                    }
7591                }
7592
7593                if (perms.isEmpty()) {
7594                    mGrantedUriPermissions.remove(targetUid);
7595                    N--;
7596                    i--;
7597                }
7598            }
7599        }
7600
7601        if (persistChanged) {
7602            schedulePersistUriGrants();
7603        }
7604    }
7605
7606    @Override
7607    public IBinder newUriPermissionOwner(String name) {
7608        enforceNotIsolatedCaller("newUriPermissionOwner");
7609        synchronized(this) {
7610            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7611            return owner.getExternalTokenLocked();
7612        }
7613    }
7614
7615    /**
7616     * @param uri This uri must NOT contain an embedded userId.
7617     * @param sourceUserId The userId in which the uri is to be resolved.
7618     * @param targetUserId The userId of the app that receives the grant.
7619     */
7620    @Override
7621    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7622            final int modeFlags, int sourceUserId, int targetUserId) {
7623        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7624                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7625        synchronized(this) {
7626            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7627            if (owner == null) {
7628                throw new IllegalArgumentException("Unknown owner: " + token);
7629            }
7630            if (fromUid != Binder.getCallingUid()) {
7631                if (Binder.getCallingUid() != Process.myUid()) {
7632                    // Only system code can grant URI permissions on behalf
7633                    // of other users.
7634                    throw new SecurityException("nice try");
7635                }
7636            }
7637            if (targetPkg == null) {
7638                throw new IllegalArgumentException("null target");
7639            }
7640            if (uri == null) {
7641                throw new IllegalArgumentException("null uri");
7642            }
7643
7644            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7645                    modeFlags, owner, targetUserId);
7646        }
7647    }
7648
7649    /**
7650     * @param uri This uri must NOT contain an embedded userId.
7651     * @param userId The userId in which the uri is to be resolved.
7652     */
7653    @Override
7654    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7655        synchronized(this) {
7656            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7657            if (owner == null) {
7658                throw new IllegalArgumentException("Unknown owner: " + token);
7659            }
7660
7661            if (uri == null) {
7662                owner.removeUriPermissionsLocked(mode);
7663            } else {
7664                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7665            }
7666        }
7667    }
7668
7669    private void schedulePersistUriGrants() {
7670        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7671            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7672                    10 * DateUtils.SECOND_IN_MILLIS);
7673        }
7674    }
7675
7676    private void writeGrantedUriPermissions() {
7677        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7678
7679        // Snapshot permissions so we can persist without lock
7680        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7681        synchronized (this) {
7682            final int size = mGrantedUriPermissions.size();
7683            for (int i = 0; i < size; i++) {
7684                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7685                for (UriPermission perm : perms.values()) {
7686                    if (perm.persistedModeFlags != 0) {
7687                        persist.add(perm.snapshot());
7688                    }
7689                }
7690            }
7691        }
7692
7693        FileOutputStream fos = null;
7694        try {
7695            fos = mGrantFile.startWrite();
7696
7697            XmlSerializer out = new FastXmlSerializer();
7698            out.setOutput(fos, "utf-8");
7699            out.startDocument(null, true);
7700            out.startTag(null, TAG_URI_GRANTS);
7701            for (UriPermission.Snapshot perm : persist) {
7702                out.startTag(null, TAG_URI_GRANT);
7703                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7704                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7705                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7706                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7707                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7708                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7709                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7710                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7711                out.endTag(null, TAG_URI_GRANT);
7712            }
7713            out.endTag(null, TAG_URI_GRANTS);
7714            out.endDocument();
7715
7716            mGrantFile.finishWrite(fos);
7717        } catch (IOException e) {
7718            if (fos != null) {
7719                mGrantFile.failWrite(fos);
7720            }
7721        }
7722    }
7723
7724    private void readGrantedUriPermissionsLocked() {
7725        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7726
7727        final long now = System.currentTimeMillis();
7728
7729        FileInputStream fis = null;
7730        try {
7731            fis = mGrantFile.openRead();
7732            final XmlPullParser in = Xml.newPullParser();
7733            in.setInput(fis, null);
7734
7735            int type;
7736            while ((type = in.next()) != END_DOCUMENT) {
7737                final String tag = in.getName();
7738                if (type == START_TAG) {
7739                    if (TAG_URI_GRANT.equals(tag)) {
7740                        final int sourceUserId;
7741                        final int targetUserId;
7742                        final int userHandle = readIntAttribute(in,
7743                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7744                        if (userHandle != UserHandle.USER_NULL) {
7745                            // For backwards compatibility.
7746                            sourceUserId = userHandle;
7747                            targetUserId = userHandle;
7748                        } else {
7749                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7750                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7751                        }
7752                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7753                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7754                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7755                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7756                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7757                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7758
7759                        // Sanity check that provider still belongs to source package
7760                        final ProviderInfo pi = getProviderInfoLocked(
7761                                uri.getAuthority(), sourceUserId);
7762                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7763                            int targetUid = -1;
7764                            try {
7765                                targetUid = AppGlobals.getPackageManager()
7766                                        .getPackageUid(targetPkg, targetUserId);
7767                            } catch (RemoteException e) {
7768                            }
7769                            if (targetUid != -1) {
7770                                final UriPermission perm = findOrCreateUriPermissionLocked(
7771                                        sourcePkg, targetPkg, targetUid,
7772                                        new GrantUri(sourceUserId, uri, prefix));
7773                                perm.initPersistedModes(modeFlags, createdTime);
7774                            }
7775                        } else {
7776                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7777                                    + " but instead found " + pi);
7778                        }
7779                    }
7780                }
7781            }
7782        } catch (FileNotFoundException e) {
7783            // Missing grants is okay
7784        } catch (IOException e) {
7785            Log.wtf(TAG, "Failed reading Uri grants", e);
7786        } catch (XmlPullParserException e) {
7787            Log.wtf(TAG, "Failed reading Uri grants", e);
7788        } finally {
7789            IoUtils.closeQuietly(fis);
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 takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7799        enforceNotIsolatedCaller("takePersistableUriPermission");
7800
7801        Preconditions.checkFlagsArgument(modeFlags,
7802                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7803
7804        synchronized (this) {
7805            final int callingUid = Binder.getCallingUid();
7806            boolean persistChanged = false;
7807            GrantUri grantUri = new GrantUri(userId, uri, false);
7808
7809            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7810                    new GrantUri(userId, uri, false));
7811            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7812                    new GrantUri(userId, uri, true));
7813
7814            final boolean exactValid = (exactPerm != null)
7815                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7816            final boolean prefixValid = (prefixPerm != null)
7817                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7818
7819            if (!(exactValid || prefixValid)) {
7820                throw new SecurityException("No persistable permission grants found for UID "
7821                        + callingUid + " and Uri " + grantUri.toSafeString());
7822            }
7823
7824            if (exactValid) {
7825                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7826            }
7827            if (prefixValid) {
7828                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7829            }
7830
7831            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7832
7833            if (persistChanged) {
7834                schedulePersistUriGrants();
7835            }
7836        }
7837    }
7838
7839    /**
7840     * @param uri This uri must NOT contain an embedded userId.
7841     * @param userId The userId in which the uri is to be resolved.
7842     */
7843    @Override
7844    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7845        enforceNotIsolatedCaller("releasePersistableUriPermission");
7846
7847        Preconditions.checkFlagsArgument(modeFlags,
7848                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7849
7850        synchronized (this) {
7851            final int callingUid = Binder.getCallingUid();
7852            boolean persistChanged = false;
7853
7854            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7855                    new GrantUri(userId, uri, false));
7856            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7857                    new GrantUri(userId, uri, true));
7858            if (exactPerm == null && prefixPerm == null) {
7859                throw new SecurityException("No permission grants found for UID " + callingUid
7860                        + " and Uri " + uri.toSafeString());
7861            }
7862
7863            if (exactPerm != null) {
7864                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7865                removeUriPermissionIfNeededLocked(exactPerm);
7866            }
7867            if (prefixPerm != null) {
7868                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7869                removeUriPermissionIfNeededLocked(prefixPerm);
7870            }
7871
7872            if (persistChanged) {
7873                schedulePersistUriGrants();
7874            }
7875        }
7876    }
7877
7878    /**
7879     * Prune any older {@link UriPermission} for the given UID until outstanding
7880     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7881     *
7882     * @return if any mutations occured that require persisting.
7883     */
7884    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7885        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7886        if (perms == null) return false;
7887        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7888
7889        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7890        for (UriPermission perm : perms.values()) {
7891            if (perm.persistedModeFlags != 0) {
7892                persisted.add(perm);
7893            }
7894        }
7895
7896        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7897        if (trimCount <= 0) return false;
7898
7899        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7900        for (int i = 0; i < trimCount; i++) {
7901            final UriPermission perm = persisted.get(i);
7902
7903            if (DEBUG_URI_PERMISSION) {
7904                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7905            }
7906
7907            perm.releasePersistableModes(~0);
7908            removeUriPermissionIfNeededLocked(perm);
7909        }
7910
7911        return true;
7912    }
7913
7914    @Override
7915    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7916            String packageName, boolean incoming) {
7917        enforceNotIsolatedCaller("getPersistedUriPermissions");
7918        Preconditions.checkNotNull(packageName, "packageName");
7919
7920        final int callingUid = Binder.getCallingUid();
7921        final IPackageManager pm = AppGlobals.getPackageManager();
7922        try {
7923            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7924            if (packageUid != callingUid) {
7925                throw new SecurityException(
7926                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7927            }
7928        } catch (RemoteException e) {
7929            throw new SecurityException("Failed to verify package name ownership");
7930        }
7931
7932        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7933        synchronized (this) {
7934            if (incoming) {
7935                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7936                        callingUid);
7937                if (perms == null) {
7938                    Slog.w(TAG, "No permission grants found for " + packageName);
7939                } else {
7940                    for (UriPermission perm : perms.values()) {
7941                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7942                            result.add(perm.buildPersistedPublicApiObject());
7943                        }
7944                    }
7945                }
7946            } else {
7947                final int size = mGrantedUriPermissions.size();
7948                for (int i = 0; i < size; i++) {
7949                    final ArrayMap<GrantUri, UriPermission> perms =
7950                            mGrantedUriPermissions.valueAt(i);
7951                    for (UriPermission perm : perms.values()) {
7952                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7953                            result.add(perm.buildPersistedPublicApiObject());
7954                        }
7955                    }
7956                }
7957            }
7958        }
7959        return new ParceledListSlice<android.content.UriPermission>(result);
7960    }
7961
7962    @Override
7963    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7964        synchronized (this) {
7965            ProcessRecord app =
7966                who != null ? getRecordForAppLocked(who) : null;
7967            if (app == null) return;
7968
7969            Message msg = Message.obtain();
7970            msg.what = WAIT_FOR_DEBUGGER_MSG;
7971            msg.obj = app;
7972            msg.arg1 = waiting ? 1 : 0;
7973            mHandler.sendMessage(msg);
7974        }
7975    }
7976
7977    @Override
7978    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7979        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7980        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7981        outInfo.availMem = Process.getFreeMemory();
7982        outInfo.totalMem = Process.getTotalMemory();
7983        outInfo.threshold = homeAppMem;
7984        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7985        outInfo.hiddenAppThreshold = cachedAppMem;
7986        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7987                ProcessList.SERVICE_ADJ);
7988        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7989                ProcessList.VISIBLE_APP_ADJ);
7990        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7991                ProcessList.FOREGROUND_APP_ADJ);
7992    }
7993
7994    // =========================================================
7995    // TASK MANAGEMENT
7996    // =========================================================
7997
7998    @Override
7999    public List<IAppTask> getAppTasks(String callingPackage) {
8000        int callingUid = Binder.getCallingUid();
8001        long ident = Binder.clearCallingIdentity();
8002
8003        synchronized(this) {
8004            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8005            try {
8006                if (localLOGV) Slog.v(TAG, "getAppTasks");
8007
8008                final int N = mRecentTasks.size();
8009                for (int i = 0; i < N; i++) {
8010                    TaskRecord tr = mRecentTasks.get(i);
8011                    // Skip tasks that do not match the caller.  We don't need to verify
8012                    // callingPackage, because we are also limiting to callingUid and know
8013                    // that will limit to the correct security sandbox.
8014                    if (tr.effectiveUid != callingUid) {
8015                        continue;
8016                    }
8017                    Intent intent = tr.getBaseIntent();
8018                    if (intent == null ||
8019                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8020                        continue;
8021                    }
8022                    ActivityManager.RecentTaskInfo taskInfo =
8023                            createRecentTaskInfoFromTaskRecord(tr);
8024                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8025                    list.add(taskImpl);
8026                }
8027            } finally {
8028                Binder.restoreCallingIdentity(ident);
8029            }
8030            return list;
8031        }
8032    }
8033
8034    @Override
8035    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8036        final int callingUid = Binder.getCallingUid();
8037        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8038
8039        synchronized(this) {
8040            if (localLOGV) Slog.v(
8041                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8042
8043            final boolean allowed = checkCallingPermission(
8044                    android.Manifest.permission.GET_TASKS)
8045                    == PackageManager.PERMISSION_GRANTED;
8046            if (!allowed) {
8047                Slog.w(TAG, "getTasks: caller " + callingUid
8048                        + " does not hold GET_TASKS; limiting output");
8049            }
8050
8051            // TODO: Improve with MRU list from all ActivityStacks.
8052            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8053        }
8054
8055        return list;
8056    }
8057
8058    TaskRecord getMostRecentTask() {
8059        return mRecentTasks.get(0);
8060    }
8061
8062    /**
8063     * Creates a new RecentTaskInfo from a TaskRecord.
8064     */
8065    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8066        // Update the task description to reflect any changes in the task stack
8067        tr.updateTaskDescription();
8068
8069        // Compose the recent task info
8070        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8071        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8072        rti.persistentId = tr.taskId;
8073        rti.baseIntent = new Intent(tr.getBaseIntent());
8074        rti.origActivity = tr.origActivity;
8075        rti.description = tr.lastDescription;
8076        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8077        rti.userId = tr.userId;
8078        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8079        rti.firstActiveTime = tr.firstActiveTime;
8080        rti.lastActiveTime = tr.lastActiveTime;
8081        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8082        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8083        return rti;
8084    }
8085
8086    @Override
8087    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8088        final int callingUid = Binder.getCallingUid();
8089        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8090                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8091
8092        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8093        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8094        synchronized (this) {
8095            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
8096                    == PackageManager.PERMISSION_GRANTED;
8097            if (!allowed) {
8098                Slog.w(TAG, "getRecentTasks: caller " + callingUid
8099                        + " does not hold GET_TASKS; limiting output");
8100            }
8101            final boolean detailed = checkCallingPermission(
8102                    android.Manifest.permission.GET_DETAILED_TASKS)
8103                    == PackageManager.PERMISSION_GRANTED;
8104
8105            final int N = mRecentTasks.size();
8106            ArrayList<ActivityManager.RecentTaskInfo> res
8107                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8108                            maxNum < N ? maxNum : N);
8109
8110            final Set<Integer> includedUsers;
8111            if (includeProfiles) {
8112                includedUsers = getProfileIdsLocked(userId);
8113            } else {
8114                includedUsers = new HashSet<Integer>();
8115            }
8116            includedUsers.add(Integer.valueOf(userId));
8117
8118            for (int i=0; i<N && maxNum > 0; i++) {
8119                TaskRecord tr = mRecentTasks.get(i);
8120                // Only add calling user or related users recent tasks
8121                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8122                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8123                    continue;
8124                }
8125
8126                // Return the entry if desired by the caller.  We always return
8127                // the first entry, because callers always expect this to be the
8128                // foreground app.  We may filter others if the caller has
8129                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8130                // we should exclude the entry.
8131
8132                if (i == 0
8133                        || withExcluded
8134                        || (tr.intent == null)
8135                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8136                                == 0)) {
8137                    if (!allowed) {
8138                        // If the caller doesn't have the GET_TASKS permission, then only
8139                        // allow them to see a small subset of tasks -- their own and home.
8140                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8141                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8142                            continue;
8143                        }
8144                    }
8145                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8146                        if (tr.stack != null && tr.stack.isHomeStack()) {
8147                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8148                            continue;
8149                        }
8150                    }
8151                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8152                        // Don't include auto remove tasks that are finished or finishing.
8153                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8154                                + tr);
8155                        continue;
8156                    }
8157                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8158                            && !tr.isAvailable) {
8159                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8160                        continue;
8161                    }
8162
8163                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8164                    if (!detailed) {
8165                        rti.baseIntent.replaceExtras((Bundle)null);
8166                    }
8167
8168                    res.add(rti);
8169                    maxNum--;
8170                }
8171            }
8172            return res;
8173        }
8174    }
8175
8176    private TaskRecord recentTaskForIdLocked(int id) {
8177        final int N = mRecentTasks.size();
8178            for (int i=0; i<N; i++) {
8179                TaskRecord tr = mRecentTasks.get(i);
8180                if (tr.taskId == id) {
8181                    return tr;
8182                }
8183            }
8184            return null;
8185    }
8186
8187    @Override
8188    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8189        synchronized (this) {
8190            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8191                    "getTaskThumbnail()");
8192            TaskRecord tr = recentTaskForIdLocked(id);
8193            if (tr != null) {
8194                return tr.getTaskThumbnailLocked();
8195            }
8196        }
8197        return null;
8198    }
8199
8200    @Override
8201    public int addAppTask(IBinder activityToken, Intent intent,
8202            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8203        final int callingUid = Binder.getCallingUid();
8204        final long callingIdent = Binder.clearCallingIdentity();
8205
8206        try {
8207            synchronized (this) {
8208                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8209                if (r == null) {
8210                    throw new IllegalArgumentException("Activity does not exist; token="
8211                            + activityToken);
8212                }
8213                ComponentName comp = intent.getComponent();
8214                if (comp == null) {
8215                    throw new IllegalArgumentException("Intent " + intent
8216                            + " must specify explicit component");
8217                }
8218                if (thumbnail.getWidth() != mThumbnailWidth
8219                        || thumbnail.getHeight() != mThumbnailHeight) {
8220                    throw new IllegalArgumentException("Bad thumbnail size: got "
8221                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8222                            + mThumbnailWidth + "x" + mThumbnailHeight);
8223                }
8224                if (intent.getSelector() != null) {
8225                    intent.setSelector(null);
8226                }
8227                if (intent.getSourceBounds() != null) {
8228                    intent.setSourceBounds(null);
8229                }
8230                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8231                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8232                        // The caller has added this as an auto-remove task...  that makes no
8233                        // sense, so turn off auto-remove.
8234                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8235                    }
8236                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8237                    // Must be a new task.
8238                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8239                }
8240                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8241                    mLastAddedTaskActivity = null;
8242                }
8243                ActivityInfo ainfo = mLastAddedTaskActivity;
8244                if (ainfo == null) {
8245                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8246                            comp, 0, UserHandle.getUserId(callingUid));
8247                    if (ainfo.applicationInfo.uid != callingUid) {
8248                        throw new SecurityException(
8249                                "Can't add task for another application: target uid="
8250                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8251                    }
8252                }
8253
8254                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8255                        intent, description);
8256
8257                int trimIdx = trimRecentsForTask(task, false);
8258                if (trimIdx >= 0) {
8259                    // If this would have caused a trim, then we'll abort because that
8260                    // means it would be added at the end of the list but then just removed.
8261                    return -1;
8262                }
8263
8264                final int N = mRecentTasks.size();
8265                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8266                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8267                    tr.removedFromRecents(mTaskPersister);
8268                }
8269
8270                task.inRecents = true;
8271                mRecentTasks.add(task);
8272                r.task.stack.addTask(task, false, false);
8273
8274                task.setLastThumbnail(thumbnail);
8275                task.freeLastThumbnail();
8276
8277                return task.taskId;
8278            }
8279        } finally {
8280            Binder.restoreCallingIdentity(callingIdent);
8281        }
8282    }
8283
8284    @Override
8285    public Point getAppTaskThumbnailSize() {
8286        synchronized (this) {
8287            return new Point(mThumbnailWidth,  mThumbnailHeight);
8288        }
8289    }
8290
8291    @Override
8292    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8293        synchronized (this) {
8294            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8295            if (r != null) {
8296                r.taskDescription = td;
8297                r.task.updateTaskDescription();
8298            }
8299        }
8300    }
8301
8302    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8303        mRecentTasks.remove(tr);
8304        tr.removedFromRecents(mTaskPersister);
8305        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8306        Intent baseIntent = new Intent(
8307                tr.intent != null ? tr.intent : tr.affinityIntent);
8308        ComponentName component = baseIntent.getComponent();
8309        if (component == null) {
8310            Slog.w(TAG, "Now component for base intent of task: " + tr);
8311            return;
8312        }
8313
8314        // Find any running services associated with this app.
8315        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8316
8317        if (killProcesses) {
8318            // Find any running processes associated with this app.
8319            final String pkg = component.getPackageName();
8320            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8321            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8322            for (int i=0; i<pmap.size(); i++) {
8323                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8324                for (int j=0; j<uids.size(); j++) {
8325                    ProcessRecord proc = uids.valueAt(j);
8326                    if (proc.userId != tr.userId) {
8327                        continue;
8328                    }
8329                    if (!proc.pkgList.containsKey(pkg)) {
8330                        continue;
8331                    }
8332                    procs.add(proc);
8333                }
8334            }
8335
8336            // Kill the running processes.
8337            for (int i=0; i<procs.size(); i++) {
8338                ProcessRecord pr = procs.get(i);
8339                if (pr == mHomeProcess) {
8340                    // Don't kill the home process along with tasks from the same package.
8341                    continue;
8342                }
8343                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8344                    pr.kill("remove task", true);
8345                } else {
8346                    pr.waitingToKill = "remove task";
8347                }
8348            }
8349        }
8350    }
8351
8352    /**
8353     * Removes the task with the specified task id.
8354     *
8355     * @param taskId Identifier of the task to be removed.
8356     * @param flags Additional operational flags.  May be 0 or
8357     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8358     * @return Returns true if the given task was found and removed.
8359     */
8360    private boolean removeTaskByIdLocked(int taskId, int flags) {
8361        TaskRecord tr = recentTaskForIdLocked(taskId);
8362        if (tr != null) {
8363            tr.removeTaskActivitiesLocked();
8364            cleanUpRemovedTaskLocked(tr, flags);
8365            if (tr.isPersistable) {
8366                notifyTaskPersisterLocked(null, true);
8367            }
8368            return true;
8369        }
8370        return false;
8371    }
8372
8373    @Override
8374    public boolean removeTask(int taskId, int flags) {
8375        synchronized (this) {
8376            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8377                    "removeTask()");
8378            long ident = Binder.clearCallingIdentity();
8379            try {
8380                return removeTaskByIdLocked(taskId, flags);
8381            } finally {
8382                Binder.restoreCallingIdentity(ident);
8383            }
8384        }
8385    }
8386
8387    /**
8388     * TODO: Add mController hook
8389     */
8390    @Override
8391    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8392        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8393                "moveTaskToFront()");
8394
8395        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8396        synchronized(this) {
8397            moveTaskToFrontLocked(taskId, flags, options);
8398        }
8399    }
8400
8401    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8402        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8403                Binder.getCallingUid(), "Task to front")) {
8404            ActivityOptions.abort(options);
8405            return;
8406        }
8407        final long origId = Binder.clearCallingIdentity();
8408        try {
8409            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8410            if (task == null) {
8411                return;
8412            }
8413            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8414                mStackSupervisor.showLockTaskToast();
8415                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8416                return;
8417            }
8418            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8419            if (prev != null && prev.isRecentsActivity()) {
8420                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8421            }
8422            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8423        } finally {
8424            Binder.restoreCallingIdentity(origId);
8425        }
8426        ActivityOptions.abort(options);
8427    }
8428
8429    @Override
8430    public void moveTaskToBack(int taskId) {
8431        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8432                "moveTaskToBack()");
8433
8434        synchronized(this) {
8435            TaskRecord tr = recentTaskForIdLocked(taskId);
8436            if (tr != null) {
8437                if (tr == mStackSupervisor.mLockTaskModeTask) {
8438                    mStackSupervisor.showLockTaskToast();
8439                    return;
8440                }
8441                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8442                ActivityStack stack = tr.stack;
8443                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8444                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8445                            Binder.getCallingUid(), "Task to back")) {
8446                        return;
8447                    }
8448                }
8449                final long origId = Binder.clearCallingIdentity();
8450                try {
8451                    stack.moveTaskToBackLocked(taskId, null);
8452                } finally {
8453                    Binder.restoreCallingIdentity(origId);
8454                }
8455            }
8456        }
8457    }
8458
8459    /**
8460     * Moves an activity, and all of the other activities within the same task, to the bottom
8461     * of the history stack.  The activity's order within the task is unchanged.
8462     *
8463     * @param token A reference to the activity we wish to move
8464     * @param nonRoot If false then this only works if the activity is the root
8465     *                of a task; if true it will work for any activity in a task.
8466     * @return Returns true if the move completed, false if not.
8467     */
8468    @Override
8469    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8470        enforceNotIsolatedCaller("moveActivityTaskToBack");
8471        synchronized(this) {
8472            final long origId = Binder.clearCallingIdentity();
8473            try {
8474                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8475                if (taskId >= 0) {
8476                    if ((mStackSupervisor.mLockTaskModeTask != null)
8477                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8478                        mStackSupervisor.showLockTaskToast();
8479                        return false;
8480                    }
8481                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8482                }
8483            } finally {
8484                Binder.restoreCallingIdentity(origId);
8485            }
8486        }
8487        return false;
8488    }
8489
8490    @Override
8491    public void moveTaskBackwards(int task) {
8492        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8493                "moveTaskBackwards()");
8494
8495        synchronized(this) {
8496            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8497                    Binder.getCallingUid(), "Task backwards")) {
8498                return;
8499            }
8500            final long origId = Binder.clearCallingIdentity();
8501            moveTaskBackwardsLocked(task);
8502            Binder.restoreCallingIdentity(origId);
8503        }
8504    }
8505
8506    private final void moveTaskBackwardsLocked(int task) {
8507        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8508    }
8509
8510    @Override
8511    public IBinder getHomeActivityToken() throws RemoteException {
8512        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8513                "getHomeActivityToken()");
8514        synchronized (this) {
8515            return mStackSupervisor.getHomeActivityToken();
8516        }
8517    }
8518
8519    @Override
8520    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8521            IActivityContainerCallback callback) throws RemoteException {
8522        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8523                "createActivityContainer()");
8524        synchronized (this) {
8525            if (parentActivityToken == null) {
8526                throw new IllegalArgumentException("parent token must not be null");
8527            }
8528            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8529            if (r == null) {
8530                return null;
8531            }
8532            if (callback == null) {
8533                throw new IllegalArgumentException("callback must not be null");
8534            }
8535            return mStackSupervisor.createActivityContainer(r, callback);
8536        }
8537    }
8538
8539    @Override
8540    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8541        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8542                "deleteActivityContainer()");
8543        synchronized (this) {
8544            mStackSupervisor.deleteActivityContainer(container);
8545        }
8546    }
8547
8548    @Override
8549    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8550            throws RemoteException {
8551        synchronized (this) {
8552            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8553            if (stack != null) {
8554                return stack.mActivityContainer;
8555            }
8556            return null;
8557        }
8558    }
8559
8560    @Override
8561    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8562        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8563                "moveTaskToStack()");
8564        if (stackId == HOME_STACK_ID) {
8565            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8566                    new RuntimeException("here").fillInStackTrace());
8567        }
8568        synchronized (this) {
8569            long ident = Binder.clearCallingIdentity();
8570            try {
8571                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8572                        + stackId + " toTop=" + toTop);
8573                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8574            } finally {
8575                Binder.restoreCallingIdentity(ident);
8576            }
8577        }
8578    }
8579
8580    @Override
8581    public void resizeStack(int stackBoxId, Rect bounds) {
8582        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8583                "resizeStackBox()");
8584        long ident = Binder.clearCallingIdentity();
8585        try {
8586            mWindowManager.resizeStack(stackBoxId, bounds);
8587        } finally {
8588            Binder.restoreCallingIdentity(ident);
8589        }
8590    }
8591
8592    @Override
8593    public List<StackInfo> getAllStackInfos() {
8594        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8595                "getAllStackInfos()");
8596        long ident = Binder.clearCallingIdentity();
8597        try {
8598            synchronized (this) {
8599                return mStackSupervisor.getAllStackInfosLocked();
8600            }
8601        } finally {
8602            Binder.restoreCallingIdentity(ident);
8603        }
8604    }
8605
8606    @Override
8607    public StackInfo getStackInfo(int stackId) {
8608        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8609                "getStackInfo()");
8610        long ident = Binder.clearCallingIdentity();
8611        try {
8612            synchronized (this) {
8613                return mStackSupervisor.getStackInfoLocked(stackId);
8614            }
8615        } finally {
8616            Binder.restoreCallingIdentity(ident);
8617        }
8618    }
8619
8620    @Override
8621    public boolean isInHomeStack(int taskId) {
8622        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8623                "getStackInfo()");
8624        long ident = Binder.clearCallingIdentity();
8625        try {
8626            synchronized (this) {
8627                TaskRecord tr = recentTaskForIdLocked(taskId);
8628                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8629            }
8630        } finally {
8631            Binder.restoreCallingIdentity(ident);
8632        }
8633    }
8634
8635    @Override
8636    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8637        synchronized(this) {
8638            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8639        }
8640    }
8641
8642    private boolean isLockTaskAuthorized(String pkg) {
8643        final DevicePolicyManager dpm = (DevicePolicyManager)
8644                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8645        try {
8646            int uid = mContext.getPackageManager().getPackageUid(pkg,
8647                    Binder.getCallingUserHandle().getIdentifier());
8648            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8649        } catch (NameNotFoundException e) {
8650            return false;
8651        }
8652    }
8653
8654    void startLockTaskMode(TaskRecord task) {
8655        final String pkg;
8656        synchronized (this) {
8657            pkg = task.intent.getComponent().getPackageName();
8658        }
8659        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8660        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8661            final TaskRecord taskRecord = task;
8662            mHandler.post(new Runnable() {
8663                @Override
8664                public void run() {
8665                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8666                }
8667            });
8668            return;
8669        }
8670        long ident = Binder.clearCallingIdentity();
8671        try {
8672            synchronized (this) {
8673                // Since we lost lock on task, make sure it is still there.
8674                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8675                if (task != null) {
8676                    if (!isSystemInitiated
8677                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8678                        throw new IllegalArgumentException("Invalid task, not in foreground");
8679                    }
8680                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8681                }
8682            }
8683        } finally {
8684            Binder.restoreCallingIdentity(ident);
8685        }
8686    }
8687
8688    @Override
8689    public void startLockTaskMode(int taskId) {
8690        final TaskRecord task;
8691        long ident = Binder.clearCallingIdentity();
8692        try {
8693            synchronized (this) {
8694                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8695            }
8696        } finally {
8697            Binder.restoreCallingIdentity(ident);
8698        }
8699        if (task != null) {
8700            startLockTaskMode(task);
8701        }
8702    }
8703
8704    @Override
8705    public void startLockTaskMode(IBinder token) {
8706        final TaskRecord task;
8707        long ident = Binder.clearCallingIdentity();
8708        try {
8709            synchronized (this) {
8710                final ActivityRecord r = ActivityRecord.forToken(token);
8711                if (r == null) {
8712                    return;
8713                }
8714                task = r.task;
8715            }
8716        } finally {
8717            Binder.restoreCallingIdentity(ident);
8718        }
8719        if (task != null) {
8720            startLockTaskMode(task);
8721        }
8722    }
8723
8724    @Override
8725    public void startLockTaskModeOnCurrent() throws RemoteException {
8726        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8727                "startLockTaskModeOnCurrent");
8728        ActivityRecord r = null;
8729        synchronized (this) {
8730            r = mStackSupervisor.topRunningActivityLocked();
8731        }
8732        startLockTaskMode(r.task);
8733    }
8734
8735    @Override
8736    public void stopLockTaskMode() {
8737        // Verify that the user matches the package of the intent for the TaskRecord
8738        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8739        // and stopLockTaskMode.
8740        final int callingUid = Binder.getCallingUid();
8741        if (callingUid != Process.SYSTEM_UID) {
8742            try {
8743                String pkg =
8744                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8745                int uid = mContext.getPackageManager().getPackageUid(pkg,
8746                        Binder.getCallingUserHandle().getIdentifier());
8747                if (uid != callingUid) {
8748                    throw new SecurityException("Invalid uid, expected " + uid);
8749                }
8750            } catch (NameNotFoundException e) {
8751                Log.d(TAG, "stopLockTaskMode " + e);
8752                return;
8753            }
8754        }
8755        long ident = Binder.clearCallingIdentity();
8756        try {
8757            Log.d(TAG, "stopLockTaskMode");
8758            // Stop lock task
8759            synchronized (this) {
8760                mStackSupervisor.setLockTaskModeLocked(null, false);
8761            }
8762        } finally {
8763            Binder.restoreCallingIdentity(ident);
8764        }
8765    }
8766
8767    @Override
8768    public void stopLockTaskModeOnCurrent() throws RemoteException {
8769        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8770                "stopLockTaskModeOnCurrent");
8771        long ident = Binder.clearCallingIdentity();
8772        try {
8773            stopLockTaskMode();
8774        } finally {
8775            Binder.restoreCallingIdentity(ident);
8776        }
8777    }
8778
8779    @Override
8780    public boolean isInLockTaskMode() {
8781        synchronized (this) {
8782            return mStackSupervisor.isInLockTaskMode();
8783        }
8784    }
8785
8786    // =========================================================
8787    // CONTENT PROVIDERS
8788    // =========================================================
8789
8790    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8791        List<ProviderInfo> providers = null;
8792        try {
8793            providers = AppGlobals.getPackageManager().
8794                queryContentProviders(app.processName, app.uid,
8795                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8796        } catch (RemoteException ex) {
8797        }
8798        if (DEBUG_MU)
8799            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8800        int userId = app.userId;
8801        if (providers != null) {
8802            int N = providers.size();
8803            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8804            for (int i=0; i<N; i++) {
8805                ProviderInfo cpi =
8806                    (ProviderInfo)providers.get(i);
8807                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8808                        cpi.name, cpi.flags);
8809                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8810                    // This is a singleton provider, but a user besides the
8811                    // default user is asking to initialize a process it runs
8812                    // in...  well, no, it doesn't actually run in this process,
8813                    // it runs in the process of the default user.  Get rid of it.
8814                    providers.remove(i);
8815                    N--;
8816                    i--;
8817                    continue;
8818                }
8819
8820                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8821                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8822                if (cpr == null) {
8823                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8824                    mProviderMap.putProviderByClass(comp, cpr);
8825                }
8826                if (DEBUG_MU)
8827                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8828                app.pubProviders.put(cpi.name, cpr);
8829                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8830                    // Don't add this if it is a platform component that is marked
8831                    // to run in multiple processes, because this is actually
8832                    // part of the framework so doesn't make sense to track as a
8833                    // separate apk in the process.
8834                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8835                            mProcessStats);
8836                }
8837                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8838            }
8839        }
8840        return providers;
8841    }
8842
8843    /**
8844     * Check if {@link ProcessRecord} has a possible chance at accessing the
8845     * given {@link ProviderInfo}. Final permission checking is always done
8846     * in {@link ContentProvider}.
8847     */
8848    private final String checkContentProviderPermissionLocked(
8849            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8850        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8851        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8852        boolean checkedGrants = false;
8853        if (checkUser) {
8854            // Looking for cross-user grants before enforcing the typical cross-users permissions
8855            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8856            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8857                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8858                    return null;
8859                }
8860                checkedGrants = true;
8861            }
8862            userId = handleIncomingUser(callingPid, callingUid, userId,
8863                    false, ALLOW_NON_FULL,
8864                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8865            if (userId != tmpTargetUserId) {
8866                // When we actually went to determine the final targer user ID, this ended
8867                // up different than our initial check for the authority.  This is because
8868                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8869                // SELF.  So we need to re-check the grants again.
8870                checkedGrants = false;
8871            }
8872        }
8873        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8874                cpi.applicationInfo.uid, cpi.exported)
8875                == PackageManager.PERMISSION_GRANTED) {
8876            return null;
8877        }
8878        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8879                cpi.applicationInfo.uid, cpi.exported)
8880                == PackageManager.PERMISSION_GRANTED) {
8881            return null;
8882        }
8883
8884        PathPermission[] pps = cpi.pathPermissions;
8885        if (pps != null) {
8886            int i = pps.length;
8887            while (i > 0) {
8888                i--;
8889                PathPermission pp = pps[i];
8890                String pprperm = pp.getReadPermission();
8891                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8892                        cpi.applicationInfo.uid, cpi.exported)
8893                        == PackageManager.PERMISSION_GRANTED) {
8894                    return null;
8895                }
8896                String ppwperm = pp.getWritePermission();
8897                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8898                        cpi.applicationInfo.uid, cpi.exported)
8899                        == PackageManager.PERMISSION_GRANTED) {
8900                    return null;
8901                }
8902            }
8903        }
8904        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8905            return null;
8906        }
8907
8908        String msg;
8909        if (!cpi.exported) {
8910            msg = "Permission Denial: opening provider " + cpi.name
8911                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8912                    + ", uid=" + callingUid + ") that is not exported from uid "
8913                    + cpi.applicationInfo.uid;
8914        } else {
8915            msg = "Permission Denial: opening provider " + cpi.name
8916                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8917                    + ", uid=" + callingUid + ") requires "
8918                    + cpi.readPermission + " or " + cpi.writePermission;
8919        }
8920        Slog.w(TAG, msg);
8921        return msg;
8922    }
8923
8924    /**
8925     * Returns if the ContentProvider has granted a uri to callingUid
8926     */
8927    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8928        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8929        if (perms != null) {
8930            for (int i=perms.size()-1; i>=0; i--) {
8931                GrantUri grantUri = perms.keyAt(i);
8932                if (grantUri.sourceUserId == userId || !checkUser) {
8933                    if (matchesProvider(grantUri.uri, cpi)) {
8934                        return true;
8935                    }
8936                }
8937            }
8938        }
8939        return false;
8940    }
8941
8942    /**
8943     * Returns true if the uri authority is one of the authorities specified in the provider.
8944     */
8945    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8946        String uriAuth = uri.getAuthority();
8947        String cpiAuth = cpi.authority;
8948        if (cpiAuth.indexOf(';') == -1) {
8949            return cpiAuth.equals(uriAuth);
8950        }
8951        String[] cpiAuths = cpiAuth.split(";");
8952        int length = cpiAuths.length;
8953        for (int i = 0; i < length; i++) {
8954            if (cpiAuths[i].equals(uriAuth)) return true;
8955        }
8956        return false;
8957    }
8958
8959    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8960            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8961        if (r != null) {
8962            for (int i=0; i<r.conProviders.size(); i++) {
8963                ContentProviderConnection conn = r.conProviders.get(i);
8964                if (conn.provider == cpr) {
8965                    if (DEBUG_PROVIDER) Slog.v(TAG,
8966                            "Adding provider requested by "
8967                            + r.processName + " from process "
8968                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8969                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8970                    if (stable) {
8971                        conn.stableCount++;
8972                        conn.numStableIncs++;
8973                    } else {
8974                        conn.unstableCount++;
8975                        conn.numUnstableIncs++;
8976                    }
8977                    return conn;
8978                }
8979            }
8980            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8981            if (stable) {
8982                conn.stableCount = 1;
8983                conn.numStableIncs = 1;
8984            } else {
8985                conn.unstableCount = 1;
8986                conn.numUnstableIncs = 1;
8987            }
8988            cpr.connections.add(conn);
8989            r.conProviders.add(conn);
8990            return conn;
8991        }
8992        cpr.addExternalProcessHandleLocked(externalProcessToken);
8993        return null;
8994    }
8995
8996    boolean decProviderCountLocked(ContentProviderConnection conn,
8997            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8998        if (conn != null) {
8999            cpr = conn.provider;
9000            if (DEBUG_PROVIDER) Slog.v(TAG,
9001                    "Removing provider requested by "
9002                    + conn.client.processName + " from process "
9003                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9004                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9005            if (stable) {
9006                conn.stableCount--;
9007            } else {
9008                conn.unstableCount--;
9009            }
9010            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9011                cpr.connections.remove(conn);
9012                conn.client.conProviders.remove(conn);
9013                return true;
9014            }
9015            return false;
9016        }
9017        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9018        return false;
9019    }
9020
9021    private void checkTime(long startTime, String where) {
9022        long now = SystemClock.elapsedRealtime();
9023        if ((now-startTime) > 1000) {
9024            // If we are taking more than a second, log about it.
9025            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9026        }
9027    }
9028
9029    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9030            String name, IBinder token, boolean stable, int userId) {
9031        ContentProviderRecord cpr;
9032        ContentProviderConnection conn = null;
9033        ProviderInfo cpi = null;
9034
9035        synchronized(this) {
9036            long startTime = SystemClock.elapsedRealtime();
9037
9038            ProcessRecord r = null;
9039            if (caller != null) {
9040                r = getRecordForAppLocked(caller);
9041                if (r == null) {
9042                    throw new SecurityException(
9043                            "Unable to find app for caller " + caller
9044                          + " (pid=" + Binder.getCallingPid()
9045                          + ") when getting content provider " + name);
9046                }
9047            }
9048
9049            boolean checkCrossUser = true;
9050
9051            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9052
9053            // First check if this content provider has been published...
9054            cpr = mProviderMap.getProviderByName(name, userId);
9055            // If that didn't work, check if it exists for user 0 and then
9056            // verify that it's a singleton provider before using it.
9057            if (cpr == null && userId != UserHandle.USER_OWNER) {
9058                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9059                if (cpr != null) {
9060                    cpi = cpr.info;
9061                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9062                            cpi.name, cpi.flags)
9063                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9064                        userId = UserHandle.USER_OWNER;
9065                        checkCrossUser = false;
9066                    } else {
9067                        cpr = null;
9068                        cpi = null;
9069                    }
9070                }
9071            }
9072
9073            boolean providerRunning = cpr != null;
9074            if (providerRunning) {
9075                cpi = cpr.info;
9076                String msg;
9077                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9078                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9079                        != null) {
9080                    throw new SecurityException(msg);
9081                }
9082                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9083
9084                if (r != null && cpr.canRunHere(r)) {
9085                    // This provider has been published or is in the process
9086                    // of being published...  but it is also allowed to run
9087                    // in the caller's process, so don't make a connection
9088                    // and just let the caller instantiate its own instance.
9089                    ContentProviderHolder holder = cpr.newHolder(null);
9090                    // don't give caller the provider object, it needs
9091                    // to make its own.
9092                    holder.provider = null;
9093                    return holder;
9094                }
9095
9096                final long origId = Binder.clearCallingIdentity();
9097
9098                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9099
9100                // In this case the provider instance already exists, so we can
9101                // return it right away.
9102                conn = incProviderCountLocked(r, cpr, token, stable);
9103                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9104                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9105                        // If this is a perceptible app accessing the provider,
9106                        // make sure to count it as being accessed and thus
9107                        // back up on the LRU list.  This is good because
9108                        // content providers are often expensive to start.
9109                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9110                        updateLruProcessLocked(cpr.proc, false, null);
9111                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9112                    }
9113                }
9114
9115                if (cpr.proc != null) {
9116                    if (false) {
9117                        if (cpr.name.flattenToShortString().equals(
9118                                "com.android.providers.calendar/.CalendarProvider2")) {
9119                            Slog.v(TAG, "****************** KILLING "
9120                                + cpr.name.flattenToShortString());
9121                            Process.killProcess(cpr.proc.pid);
9122                        }
9123                    }
9124                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9125                    boolean success = updateOomAdjLocked(cpr.proc);
9126                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9127                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9128                    // NOTE: there is still a race here where a signal could be
9129                    // pending on the process even though we managed to update its
9130                    // adj level.  Not sure what to do about this, but at least
9131                    // the race is now smaller.
9132                    if (!success) {
9133                        // Uh oh...  it looks like the provider's process
9134                        // has been killed on us.  We need to wait for a new
9135                        // process to be started, and make sure its death
9136                        // doesn't kill our process.
9137                        Slog.i(TAG,
9138                                "Existing provider " + cpr.name.flattenToShortString()
9139                                + " is crashing; detaching " + r);
9140                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9141                        checkTime(startTime, "getContentProviderImpl: before appDied");
9142                        appDiedLocked(cpr.proc);
9143                        checkTime(startTime, "getContentProviderImpl: after appDied");
9144                        if (!lastRef) {
9145                            // This wasn't the last ref our process had on
9146                            // the provider...  we have now been killed, bail.
9147                            return null;
9148                        }
9149                        providerRunning = false;
9150                        conn = null;
9151                    }
9152                }
9153
9154                Binder.restoreCallingIdentity(origId);
9155            }
9156
9157            boolean singleton;
9158            if (!providerRunning) {
9159                try {
9160                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9161                    cpi = AppGlobals.getPackageManager().
9162                        resolveContentProvider(name,
9163                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9164                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9165                } catch (RemoteException ex) {
9166                }
9167                if (cpi == null) {
9168                    return null;
9169                }
9170                // If the provider is a singleton AND
9171                // (it's a call within the same user || the provider is a
9172                // privileged app)
9173                // Then allow connecting to the singleton provider
9174                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9175                        cpi.name, cpi.flags)
9176                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9177                if (singleton) {
9178                    userId = UserHandle.USER_OWNER;
9179                }
9180                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9181                checkTime(startTime, "getContentProviderImpl: got app info for user");
9182
9183                String msg;
9184                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9185                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9186                        != null) {
9187                    throw new SecurityException(msg);
9188                }
9189                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9190
9191                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9192                        && !cpi.processName.equals("system")) {
9193                    // If this content provider does not run in the system
9194                    // process, and the system is not yet ready to run other
9195                    // processes, then fail fast instead of hanging.
9196                    throw new IllegalArgumentException(
9197                            "Attempt to launch content provider before system ready");
9198                }
9199
9200                // Make sure that the user who owns this provider is started.  If not,
9201                // we don't want to allow it to run.
9202                if (mStartedUsers.get(userId) == null) {
9203                    Slog.w(TAG, "Unable to launch app "
9204                            + cpi.applicationInfo.packageName + "/"
9205                            + cpi.applicationInfo.uid + " for provider "
9206                            + name + ": user " + userId + " is stopped");
9207                    return null;
9208                }
9209
9210                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9211                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9212                cpr = mProviderMap.getProviderByClass(comp, userId);
9213                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9214                final boolean firstClass = cpr == null;
9215                if (firstClass) {
9216                    try {
9217                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9218                        ApplicationInfo ai =
9219                            AppGlobals.getPackageManager().
9220                                getApplicationInfo(
9221                                        cpi.applicationInfo.packageName,
9222                                        STOCK_PM_FLAGS, userId);
9223                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9224                        if (ai == null) {
9225                            Slog.w(TAG, "No package info for content provider "
9226                                    + cpi.name);
9227                            return null;
9228                        }
9229                        ai = getAppInfoForUser(ai, userId);
9230                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9231                    } catch (RemoteException ex) {
9232                        // pm is in same process, this will never happen.
9233                    }
9234                }
9235
9236                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9237
9238                if (r != null && cpr.canRunHere(r)) {
9239                    // If this is a multiprocess provider, then just return its
9240                    // info and allow the caller to instantiate it.  Only do
9241                    // this if the provider is the same user as the caller's
9242                    // process, or can run as root (so can be in any process).
9243                    return cpr.newHolder(null);
9244                }
9245
9246                if (DEBUG_PROVIDER) {
9247                    RuntimeException e = new RuntimeException("here");
9248                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9249                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9250                }
9251
9252                // This is single process, and our app is now connecting to it.
9253                // See if we are already in the process of launching this
9254                // provider.
9255                final int N = mLaunchingProviders.size();
9256                int i;
9257                for (i=0; i<N; i++) {
9258                    if (mLaunchingProviders.get(i) == cpr) {
9259                        break;
9260                    }
9261                }
9262
9263                // If the provider is not already being launched, then get it
9264                // started.
9265                if (i >= N) {
9266                    final long origId = Binder.clearCallingIdentity();
9267
9268                    try {
9269                        // Content provider is now in use, its package can't be stopped.
9270                        try {
9271                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9272                            AppGlobals.getPackageManager().setPackageStoppedState(
9273                                    cpr.appInfo.packageName, false, userId);
9274                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9275                        } catch (RemoteException e) {
9276                        } catch (IllegalArgumentException e) {
9277                            Slog.w(TAG, "Failed trying to unstop package "
9278                                    + cpr.appInfo.packageName + ": " + e);
9279                        }
9280
9281                        // Use existing process if already started
9282                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9283                        ProcessRecord proc = getProcessRecordLocked(
9284                                cpi.processName, cpr.appInfo.uid, false);
9285                        if (proc != null && proc.thread != null) {
9286                            if (DEBUG_PROVIDER) {
9287                                Slog.d(TAG, "Installing in existing process " + proc);
9288                            }
9289                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9290                            proc.pubProviders.put(cpi.name, cpr);
9291                            try {
9292                                proc.thread.scheduleInstallProvider(cpi);
9293                            } catch (RemoteException e) {
9294                            }
9295                        } else {
9296                            checkTime(startTime, "getContentProviderImpl: before start process");
9297                            proc = startProcessLocked(cpi.processName,
9298                                    cpr.appInfo, false, 0, "content provider",
9299                                    new ComponentName(cpi.applicationInfo.packageName,
9300                                            cpi.name), false, false, false);
9301                            checkTime(startTime, "getContentProviderImpl: after start process");
9302                            if (proc == null) {
9303                                Slog.w(TAG, "Unable to launch app "
9304                                        + cpi.applicationInfo.packageName + "/"
9305                                        + cpi.applicationInfo.uid + " for provider "
9306                                        + name + ": process is bad");
9307                                return null;
9308                            }
9309                        }
9310                        cpr.launchingApp = proc;
9311                        mLaunchingProviders.add(cpr);
9312                    } finally {
9313                        Binder.restoreCallingIdentity(origId);
9314                    }
9315                }
9316
9317                checkTime(startTime, "getContentProviderImpl: updating data structures");
9318
9319                // Make sure the provider is published (the same provider class
9320                // may be published under multiple names).
9321                if (firstClass) {
9322                    mProviderMap.putProviderByClass(comp, cpr);
9323                }
9324
9325                mProviderMap.putProviderByName(name, cpr);
9326                conn = incProviderCountLocked(r, cpr, token, stable);
9327                if (conn != null) {
9328                    conn.waiting = true;
9329                }
9330            }
9331            checkTime(startTime, "getContentProviderImpl: done!");
9332        }
9333
9334        // Wait for the provider to be published...
9335        synchronized (cpr) {
9336            while (cpr.provider == null) {
9337                if (cpr.launchingApp == null) {
9338                    Slog.w(TAG, "Unable to launch app "
9339                            + cpi.applicationInfo.packageName + "/"
9340                            + cpi.applicationInfo.uid + " for provider "
9341                            + name + ": launching app became null");
9342                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9343                            UserHandle.getUserId(cpi.applicationInfo.uid),
9344                            cpi.applicationInfo.packageName,
9345                            cpi.applicationInfo.uid, name);
9346                    return null;
9347                }
9348                try {
9349                    if (DEBUG_MU) {
9350                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9351                                + cpr.launchingApp);
9352                    }
9353                    if (conn != null) {
9354                        conn.waiting = true;
9355                    }
9356                    cpr.wait();
9357                } catch (InterruptedException ex) {
9358                } finally {
9359                    if (conn != null) {
9360                        conn.waiting = false;
9361                    }
9362                }
9363            }
9364        }
9365        return cpr != null ? cpr.newHolder(conn) : null;
9366    }
9367
9368    @Override
9369    public final ContentProviderHolder getContentProvider(
9370            IApplicationThread caller, String name, int userId, boolean stable) {
9371        enforceNotIsolatedCaller("getContentProvider");
9372        if (caller == null) {
9373            String msg = "null IApplicationThread when getting content provider "
9374                    + name;
9375            Slog.w(TAG, msg);
9376            throw new SecurityException(msg);
9377        }
9378        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9379        // with cross-user grant.
9380        return getContentProviderImpl(caller, name, null, stable, userId);
9381    }
9382
9383    public ContentProviderHolder getContentProviderExternal(
9384            String name, int userId, IBinder token) {
9385        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9386            "Do not have permission in call getContentProviderExternal()");
9387        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9388                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9389        return getContentProviderExternalUnchecked(name, token, userId);
9390    }
9391
9392    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9393            IBinder token, int userId) {
9394        return getContentProviderImpl(null, name, token, true, userId);
9395    }
9396
9397    /**
9398     * Drop a content provider from a ProcessRecord's bookkeeping
9399     */
9400    public void removeContentProvider(IBinder connection, boolean stable) {
9401        enforceNotIsolatedCaller("removeContentProvider");
9402        long ident = Binder.clearCallingIdentity();
9403        try {
9404            synchronized (this) {
9405                ContentProviderConnection conn;
9406                try {
9407                    conn = (ContentProviderConnection)connection;
9408                } catch (ClassCastException e) {
9409                    String msg ="removeContentProvider: " + connection
9410                            + " not a ContentProviderConnection";
9411                    Slog.w(TAG, msg);
9412                    throw new IllegalArgumentException(msg);
9413                }
9414                if (conn == null) {
9415                    throw new NullPointerException("connection is null");
9416                }
9417                if (decProviderCountLocked(conn, null, null, stable)) {
9418                    updateOomAdjLocked();
9419                }
9420            }
9421        } finally {
9422            Binder.restoreCallingIdentity(ident);
9423        }
9424    }
9425
9426    public void removeContentProviderExternal(String name, IBinder token) {
9427        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9428            "Do not have permission in call removeContentProviderExternal()");
9429        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
9430    }
9431
9432    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9433        synchronized (this) {
9434            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9435            if(cpr == null) {
9436                //remove from mProvidersByClass
9437                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9438                return;
9439            }
9440
9441            //update content provider record entry info
9442            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9443            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9444            if (localCpr.hasExternalProcessHandles()) {
9445                if (localCpr.removeExternalProcessHandleLocked(token)) {
9446                    updateOomAdjLocked();
9447                } else {
9448                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9449                            + " with no external reference for token: "
9450                            + token + ".");
9451                }
9452            } else {
9453                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9454                        + " with no external references.");
9455            }
9456        }
9457    }
9458
9459    public final void publishContentProviders(IApplicationThread caller,
9460            List<ContentProviderHolder> providers) {
9461        if (providers == null) {
9462            return;
9463        }
9464
9465        enforceNotIsolatedCaller("publishContentProviders");
9466        synchronized (this) {
9467            final ProcessRecord r = getRecordForAppLocked(caller);
9468            if (DEBUG_MU)
9469                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9470            if (r == null) {
9471                throw new SecurityException(
9472                        "Unable to find app for caller " + caller
9473                      + " (pid=" + Binder.getCallingPid()
9474                      + ") when publishing content providers");
9475            }
9476
9477            final long origId = Binder.clearCallingIdentity();
9478
9479            final int N = providers.size();
9480            for (int i=0; i<N; i++) {
9481                ContentProviderHolder src = providers.get(i);
9482                if (src == null || src.info == null || src.provider == null) {
9483                    continue;
9484                }
9485                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9486                if (DEBUG_MU)
9487                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9488                if (dst != null) {
9489                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9490                    mProviderMap.putProviderByClass(comp, dst);
9491                    String names[] = dst.info.authority.split(";");
9492                    for (int j = 0; j < names.length; j++) {
9493                        mProviderMap.putProviderByName(names[j], dst);
9494                    }
9495
9496                    int NL = mLaunchingProviders.size();
9497                    int j;
9498                    for (j=0; j<NL; j++) {
9499                        if (mLaunchingProviders.get(j) == dst) {
9500                            mLaunchingProviders.remove(j);
9501                            j--;
9502                            NL--;
9503                        }
9504                    }
9505                    synchronized (dst) {
9506                        dst.provider = src.provider;
9507                        dst.proc = r;
9508                        dst.notifyAll();
9509                    }
9510                    updateOomAdjLocked(r);
9511                }
9512            }
9513
9514            Binder.restoreCallingIdentity(origId);
9515        }
9516    }
9517
9518    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9519        ContentProviderConnection conn;
9520        try {
9521            conn = (ContentProviderConnection)connection;
9522        } catch (ClassCastException e) {
9523            String msg ="refContentProvider: " + connection
9524                    + " not a ContentProviderConnection";
9525            Slog.w(TAG, msg);
9526            throw new IllegalArgumentException(msg);
9527        }
9528        if (conn == null) {
9529            throw new NullPointerException("connection is null");
9530        }
9531
9532        synchronized (this) {
9533            if (stable > 0) {
9534                conn.numStableIncs += stable;
9535            }
9536            stable = conn.stableCount + stable;
9537            if (stable < 0) {
9538                throw new IllegalStateException("stableCount < 0: " + stable);
9539            }
9540
9541            if (unstable > 0) {
9542                conn.numUnstableIncs += unstable;
9543            }
9544            unstable = conn.unstableCount + unstable;
9545            if (unstable < 0) {
9546                throw new IllegalStateException("unstableCount < 0: " + unstable);
9547            }
9548
9549            if ((stable+unstable) <= 0) {
9550                throw new IllegalStateException("ref counts can't go to zero here: stable="
9551                        + stable + " unstable=" + unstable);
9552            }
9553            conn.stableCount = stable;
9554            conn.unstableCount = unstable;
9555            return !conn.dead;
9556        }
9557    }
9558
9559    public void unstableProviderDied(IBinder connection) {
9560        ContentProviderConnection conn;
9561        try {
9562            conn = (ContentProviderConnection)connection;
9563        } catch (ClassCastException e) {
9564            String msg ="refContentProvider: " + connection
9565                    + " not a ContentProviderConnection";
9566            Slog.w(TAG, msg);
9567            throw new IllegalArgumentException(msg);
9568        }
9569        if (conn == null) {
9570            throw new NullPointerException("connection is null");
9571        }
9572
9573        // Safely retrieve the content provider associated with the connection.
9574        IContentProvider provider;
9575        synchronized (this) {
9576            provider = conn.provider.provider;
9577        }
9578
9579        if (provider == null) {
9580            // Um, yeah, we're way ahead of you.
9581            return;
9582        }
9583
9584        // Make sure the caller is being honest with us.
9585        if (provider.asBinder().pingBinder()) {
9586            // Er, no, still looks good to us.
9587            synchronized (this) {
9588                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9589                        + " says " + conn + " died, but we don't agree");
9590                return;
9591            }
9592        }
9593
9594        // Well look at that!  It's dead!
9595        synchronized (this) {
9596            if (conn.provider.provider != provider) {
9597                // But something changed...  good enough.
9598                return;
9599            }
9600
9601            ProcessRecord proc = conn.provider.proc;
9602            if (proc == null || proc.thread == null) {
9603                // Seems like the process is already cleaned up.
9604                return;
9605            }
9606
9607            // As far as we're concerned, this is just like receiving a
9608            // death notification...  just a bit prematurely.
9609            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9610                    + ") early provider death");
9611            final long ident = Binder.clearCallingIdentity();
9612            try {
9613                appDiedLocked(proc);
9614            } finally {
9615                Binder.restoreCallingIdentity(ident);
9616            }
9617        }
9618    }
9619
9620    @Override
9621    public void appNotRespondingViaProvider(IBinder connection) {
9622        enforceCallingPermission(
9623                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9624
9625        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9626        if (conn == null) {
9627            Slog.w(TAG, "ContentProviderConnection is null");
9628            return;
9629        }
9630
9631        final ProcessRecord host = conn.provider.proc;
9632        if (host == null) {
9633            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9634            return;
9635        }
9636
9637        final long token = Binder.clearCallingIdentity();
9638        try {
9639            appNotResponding(host, null, null, false, "ContentProvider not responding");
9640        } finally {
9641            Binder.restoreCallingIdentity(token);
9642        }
9643    }
9644
9645    public final void installSystemProviders() {
9646        List<ProviderInfo> providers;
9647        synchronized (this) {
9648            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9649            providers = generateApplicationProvidersLocked(app);
9650            if (providers != null) {
9651                for (int i=providers.size()-1; i>=0; i--) {
9652                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9653                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9654                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9655                                + ": not system .apk");
9656                        providers.remove(i);
9657                    }
9658                }
9659            }
9660        }
9661        if (providers != null) {
9662            mSystemThread.installSystemProviders(providers);
9663        }
9664
9665        mCoreSettingsObserver = new CoreSettingsObserver(this);
9666
9667        //mUsageStatsService.monitorPackages();
9668    }
9669
9670    /**
9671     * Allows apps to retrieve the MIME type of a URI.
9672     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9673     * users, then it does not need permission to access the ContentProvider.
9674     * Either, it needs cross-user uri grants.
9675     *
9676     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9677     *
9678     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9679     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9680     */
9681    public String getProviderMimeType(Uri uri, int userId) {
9682        enforceNotIsolatedCaller("getProviderMimeType");
9683        final String name = uri.getAuthority();
9684        int callingUid = Binder.getCallingUid();
9685        int callingPid = Binder.getCallingPid();
9686        long ident = 0;
9687        boolean clearedIdentity = false;
9688        userId = unsafeConvertIncomingUser(userId);
9689        if (UserHandle.getUserId(callingUid) != userId) {
9690            if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9691                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9692                    || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9693                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9694                clearedIdentity = true;
9695                ident = Binder.clearCallingIdentity();
9696            }
9697        }
9698        ContentProviderHolder holder = null;
9699        try {
9700            holder = getContentProviderExternalUnchecked(name, null, userId);
9701            if (holder != null) {
9702                return holder.provider.getType(uri);
9703            }
9704        } catch (RemoteException e) {
9705            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9706            return null;
9707        } finally {
9708            // We need to clear the identity to call removeContentProviderExternalUnchecked
9709            if (!clearedIdentity) {
9710                ident = Binder.clearCallingIdentity();
9711            }
9712            try {
9713                if (holder != null) {
9714                    removeContentProviderExternalUnchecked(name, null, userId);
9715                }
9716            } finally {
9717                Binder.restoreCallingIdentity(ident);
9718            }
9719        }
9720
9721        return null;
9722    }
9723
9724    // =========================================================
9725    // GLOBAL MANAGEMENT
9726    // =========================================================
9727
9728    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9729            boolean isolated, int isolatedUid) {
9730        String proc = customProcess != null ? customProcess : info.processName;
9731        BatteryStatsImpl.Uid.Proc ps = null;
9732        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9733        int uid = info.uid;
9734        if (isolated) {
9735            if (isolatedUid == 0) {
9736                int userId = UserHandle.getUserId(uid);
9737                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9738                while (true) {
9739                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9740                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9741                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9742                    }
9743                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9744                    mNextIsolatedProcessUid++;
9745                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9746                        // No process for this uid, use it.
9747                        break;
9748                    }
9749                    stepsLeft--;
9750                    if (stepsLeft <= 0) {
9751                        return null;
9752                    }
9753                }
9754            } else {
9755                // Special case for startIsolatedProcess (internal only), where
9756                // the uid of the isolated process is specified by the caller.
9757                uid = isolatedUid;
9758            }
9759        }
9760        return new ProcessRecord(stats, info, proc, uid);
9761    }
9762
9763    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9764            String abiOverride) {
9765        ProcessRecord app;
9766        if (!isolated) {
9767            app = getProcessRecordLocked(info.processName, info.uid, true);
9768        } else {
9769            app = null;
9770        }
9771
9772        if (app == null) {
9773            app = newProcessRecordLocked(info, null, isolated, 0);
9774            mProcessNames.put(info.processName, app.uid, app);
9775            if (isolated) {
9776                mIsolatedProcesses.put(app.uid, app);
9777            }
9778            updateLruProcessLocked(app, false, null);
9779            updateOomAdjLocked();
9780        }
9781
9782        // This package really, really can not be stopped.
9783        try {
9784            AppGlobals.getPackageManager().setPackageStoppedState(
9785                    info.packageName, false, UserHandle.getUserId(app.uid));
9786        } catch (RemoteException e) {
9787        } catch (IllegalArgumentException e) {
9788            Slog.w(TAG, "Failed trying to unstop package "
9789                    + info.packageName + ": " + e);
9790        }
9791
9792        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9793                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9794            app.persistent = true;
9795            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9796        }
9797        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9798            mPersistentStartingProcesses.add(app);
9799            startProcessLocked(app, "added application", app.processName, abiOverride,
9800                    null /* entryPoint */, null /* entryPointArgs */);
9801        }
9802
9803        return app;
9804    }
9805
9806    public void unhandledBack() {
9807        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9808                "unhandledBack()");
9809
9810        synchronized(this) {
9811            final long origId = Binder.clearCallingIdentity();
9812            try {
9813                getFocusedStack().unhandledBackLocked();
9814            } finally {
9815                Binder.restoreCallingIdentity(origId);
9816            }
9817        }
9818    }
9819
9820    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9821        enforceNotIsolatedCaller("openContentUri");
9822        final int userId = UserHandle.getCallingUserId();
9823        String name = uri.getAuthority();
9824        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9825        ParcelFileDescriptor pfd = null;
9826        if (cph != null) {
9827            // We record the binder invoker's uid in thread-local storage before
9828            // going to the content provider to open the file.  Later, in the code
9829            // that handles all permissions checks, we look for this uid and use
9830            // that rather than the Activity Manager's own uid.  The effect is that
9831            // we do the check against the caller's permissions even though it looks
9832            // to the content provider like the Activity Manager itself is making
9833            // the request.
9834            sCallerIdentity.set(new Identity(
9835                    Binder.getCallingPid(), Binder.getCallingUid()));
9836            try {
9837                pfd = cph.provider.openFile(null, uri, "r", null);
9838            } catch (FileNotFoundException e) {
9839                // do nothing; pfd will be returned null
9840            } finally {
9841                // Ensure that whatever happens, we clean up the identity state
9842                sCallerIdentity.remove();
9843            }
9844
9845            // We've got the fd now, so we're done with the provider.
9846            removeContentProviderExternalUnchecked(name, null, userId);
9847        } else {
9848            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9849        }
9850        return pfd;
9851    }
9852
9853    // Actually is sleeping or shutting down or whatever else in the future
9854    // is an inactive state.
9855    public boolean isSleepingOrShuttingDown() {
9856        return mSleeping || mShuttingDown;
9857    }
9858
9859    public boolean isSleeping() {
9860        return mSleeping;
9861    }
9862
9863    void goingToSleep() {
9864        synchronized(this) {
9865            mWentToSleep = true;
9866            updateEventDispatchingLocked();
9867            goToSleepIfNeededLocked();
9868        }
9869    }
9870
9871    void finishRunningVoiceLocked() {
9872        if (mRunningVoice) {
9873            mRunningVoice = false;
9874            goToSleepIfNeededLocked();
9875        }
9876    }
9877
9878    void goToSleepIfNeededLocked() {
9879        if (mWentToSleep && !mRunningVoice) {
9880            if (!mSleeping) {
9881                mSleeping = true;
9882                mStackSupervisor.goingToSleepLocked();
9883
9884                // Initialize the wake times of all processes.
9885                checkExcessivePowerUsageLocked(false);
9886                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9887                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9888                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9889            }
9890        }
9891    }
9892
9893    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9894        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9895            // Never persist the home stack.
9896            return;
9897        }
9898        mTaskPersister.wakeup(task, flush);
9899    }
9900
9901    @Override
9902    public boolean shutdown(int timeout) {
9903        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9904                != PackageManager.PERMISSION_GRANTED) {
9905            throw new SecurityException("Requires permission "
9906                    + android.Manifest.permission.SHUTDOWN);
9907        }
9908
9909        boolean timedout = false;
9910
9911        synchronized(this) {
9912            mShuttingDown = true;
9913            updateEventDispatchingLocked();
9914            timedout = mStackSupervisor.shutdownLocked(timeout);
9915        }
9916
9917        mAppOpsService.shutdown();
9918        if (mUsageStatsService != null) {
9919            mUsageStatsService.prepareShutdown();
9920        }
9921        mBatteryStatsService.shutdown();
9922        synchronized (this) {
9923            mProcessStats.shutdownLocked();
9924        }
9925        notifyTaskPersisterLocked(null, true);
9926
9927        return timedout;
9928    }
9929
9930    public final void activitySlept(IBinder token) {
9931        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9932
9933        final long origId = Binder.clearCallingIdentity();
9934
9935        synchronized (this) {
9936            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9937            if (r != null) {
9938                mStackSupervisor.activitySleptLocked(r);
9939            }
9940        }
9941
9942        Binder.restoreCallingIdentity(origId);
9943    }
9944
9945    void logLockScreen(String msg) {
9946        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9947                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9948                mWentToSleep + " mSleeping=" + mSleeping);
9949    }
9950
9951    private void comeOutOfSleepIfNeededLocked() {
9952        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9953            if (mSleeping) {
9954                mSleeping = false;
9955                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9956            }
9957        }
9958    }
9959
9960    void wakingUp() {
9961        synchronized(this) {
9962            mWentToSleep = false;
9963            updateEventDispatchingLocked();
9964            comeOutOfSleepIfNeededLocked();
9965        }
9966    }
9967
9968    void startRunningVoiceLocked() {
9969        if (!mRunningVoice) {
9970            mRunningVoice = true;
9971            comeOutOfSleepIfNeededLocked();
9972        }
9973    }
9974
9975    private void updateEventDispatchingLocked() {
9976        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
9977    }
9978
9979    public void setLockScreenShown(boolean shown) {
9980        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9981                != PackageManager.PERMISSION_GRANTED) {
9982            throw new SecurityException("Requires permission "
9983                    + android.Manifest.permission.DEVICE_POWER);
9984        }
9985
9986        synchronized(this) {
9987            long ident = Binder.clearCallingIdentity();
9988            try {
9989                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9990                mLockScreenShown = shown;
9991                comeOutOfSleepIfNeededLocked();
9992            } finally {
9993                Binder.restoreCallingIdentity(ident);
9994            }
9995        }
9996    }
9997
9998    @Override
9999    public void stopAppSwitches() {
10000        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10001                != PackageManager.PERMISSION_GRANTED) {
10002            throw new SecurityException("Requires permission "
10003                    + android.Manifest.permission.STOP_APP_SWITCHES);
10004        }
10005
10006        synchronized(this) {
10007            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10008                    + APP_SWITCH_DELAY_TIME;
10009            mDidAppSwitch = false;
10010            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10011            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10012            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10013        }
10014    }
10015
10016    public void resumeAppSwitches() {
10017        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10018                != PackageManager.PERMISSION_GRANTED) {
10019            throw new SecurityException("Requires permission "
10020                    + android.Manifest.permission.STOP_APP_SWITCHES);
10021        }
10022
10023        synchronized(this) {
10024            // Note that we don't execute any pending app switches... we will
10025            // let those wait until either the timeout, or the next start
10026            // activity request.
10027            mAppSwitchesAllowedTime = 0;
10028        }
10029    }
10030
10031    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
10032            String name) {
10033        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10034            return true;
10035        }
10036
10037        final int perm = checkComponentPermission(
10038                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10039                callingUid, -1, true);
10040        if (perm == PackageManager.PERMISSION_GRANTED) {
10041            return true;
10042        }
10043
10044        Slog.w(TAG, name + " request from " + callingUid + " stopped");
10045        return false;
10046    }
10047
10048    public void setDebugApp(String packageName, boolean waitForDebugger,
10049            boolean persistent) {
10050        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10051                "setDebugApp()");
10052
10053        long ident = Binder.clearCallingIdentity();
10054        try {
10055            // Note that this is not really thread safe if there are multiple
10056            // callers into it at the same time, but that's not a situation we
10057            // care about.
10058            if (persistent) {
10059                final ContentResolver resolver = mContext.getContentResolver();
10060                Settings.Global.putString(
10061                    resolver, Settings.Global.DEBUG_APP,
10062                    packageName);
10063                Settings.Global.putInt(
10064                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10065                    waitForDebugger ? 1 : 0);
10066            }
10067
10068            synchronized (this) {
10069                if (!persistent) {
10070                    mOrigDebugApp = mDebugApp;
10071                    mOrigWaitForDebugger = mWaitForDebugger;
10072                }
10073                mDebugApp = packageName;
10074                mWaitForDebugger = waitForDebugger;
10075                mDebugTransient = !persistent;
10076                if (packageName != null) {
10077                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10078                            false, UserHandle.USER_ALL, "set debug app");
10079                }
10080            }
10081        } finally {
10082            Binder.restoreCallingIdentity(ident);
10083        }
10084    }
10085
10086    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10087        synchronized (this) {
10088            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10089            if (!isDebuggable) {
10090                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10091                    throw new SecurityException("Process not debuggable: " + app.packageName);
10092                }
10093            }
10094
10095            mOpenGlTraceApp = processName;
10096        }
10097    }
10098
10099    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10100        synchronized (this) {
10101            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10102            if (!isDebuggable) {
10103                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10104                    throw new SecurityException("Process not debuggable: " + app.packageName);
10105                }
10106            }
10107            mProfileApp = processName;
10108            mProfileFile = profilerInfo.profileFile;
10109            if (mProfileFd != null) {
10110                try {
10111                    mProfileFd.close();
10112                } catch (IOException e) {
10113                }
10114                mProfileFd = null;
10115            }
10116            mProfileFd = profilerInfo.profileFd;
10117            mSamplingInterval = profilerInfo.samplingInterval;
10118            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10119            mProfileType = 0;
10120        }
10121    }
10122
10123    @Override
10124    public void setAlwaysFinish(boolean enabled) {
10125        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10126                "setAlwaysFinish()");
10127
10128        Settings.Global.putInt(
10129                mContext.getContentResolver(),
10130                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10131
10132        synchronized (this) {
10133            mAlwaysFinishActivities = enabled;
10134        }
10135    }
10136
10137    @Override
10138    public void setActivityController(IActivityController controller) {
10139        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10140                "setActivityController()");
10141        synchronized (this) {
10142            mController = controller;
10143            Watchdog.getInstance().setActivityController(controller);
10144        }
10145    }
10146
10147    @Override
10148    public void setUserIsMonkey(boolean userIsMonkey) {
10149        synchronized (this) {
10150            synchronized (mPidsSelfLocked) {
10151                final int callingPid = Binder.getCallingPid();
10152                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10153                if (precessRecord == null) {
10154                    throw new SecurityException("Unknown process: " + callingPid);
10155                }
10156                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10157                    throw new SecurityException("Only an instrumentation process "
10158                            + "with a UiAutomation can call setUserIsMonkey");
10159                }
10160            }
10161            mUserIsMonkey = userIsMonkey;
10162        }
10163    }
10164
10165    @Override
10166    public boolean isUserAMonkey() {
10167        synchronized (this) {
10168            // If there is a controller also implies the user is a monkey.
10169            return (mUserIsMonkey || mController != null);
10170        }
10171    }
10172
10173    public void requestBugReport() {
10174        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10175        SystemProperties.set("ctl.start", "bugreport");
10176    }
10177
10178    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10179        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10180    }
10181
10182    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10183        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10184            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10185        }
10186        return KEY_DISPATCHING_TIMEOUT;
10187    }
10188
10189    @Override
10190    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10191        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10192                != PackageManager.PERMISSION_GRANTED) {
10193            throw new SecurityException("Requires permission "
10194                    + android.Manifest.permission.FILTER_EVENTS);
10195        }
10196        ProcessRecord proc;
10197        long timeout;
10198        synchronized (this) {
10199            synchronized (mPidsSelfLocked) {
10200                proc = mPidsSelfLocked.get(pid);
10201            }
10202            timeout = getInputDispatchingTimeoutLocked(proc);
10203        }
10204
10205        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10206            return -1;
10207        }
10208
10209        return timeout;
10210    }
10211
10212    /**
10213     * Handle input dispatching timeouts.
10214     * Returns whether input dispatching should be aborted or not.
10215     */
10216    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10217            final ActivityRecord activity, final ActivityRecord parent,
10218            final boolean aboveSystem, String reason) {
10219        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10220                != PackageManager.PERMISSION_GRANTED) {
10221            throw new SecurityException("Requires permission "
10222                    + android.Manifest.permission.FILTER_EVENTS);
10223        }
10224
10225        final String annotation;
10226        if (reason == null) {
10227            annotation = "Input dispatching timed out";
10228        } else {
10229            annotation = "Input dispatching timed out (" + reason + ")";
10230        }
10231
10232        if (proc != null) {
10233            synchronized (this) {
10234                if (proc.debugging) {
10235                    return false;
10236                }
10237
10238                if (mDidDexOpt) {
10239                    // Give more time since we were dexopting.
10240                    mDidDexOpt = false;
10241                    return false;
10242                }
10243
10244                if (proc.instrumentationClass != null) {
10245                    Bundle info = new Bundle();
10246                    info.putString("shortMsg", "keyDispatchingTimedOut");
10247                    info.putString("longMsg", annotation);
10248                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10249                    return true;
10250                }
10251            }
10252            mHandler.post(new Runnable() {
10253                @Override
10254                public void run() {
10255                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10256                }
10257            });
10258        }
10259
10260        return true;
10261    }
10262
10263    public Bundle getAssistContextExtras(int requestType) {
10264        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10265                "getAssistContextExtras()");
10266        PendingAssistExtras pae;
10267        Bundle extras = new Bundle();
10268        synchronized (this) {
10269            ActivityRecord activity = getFocusedStack().mResumedActivity;
10270            if (activity == null) {
10271                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10272                return null;
10273            }
10274            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10275            if (activity.app == null || activity.app.thread == null) {
10276                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10277                return extras;
10278            }
10279            if (activity.app.pid == Binder.getCallingPid()) {
10280                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10281                return extras;
10282            }
10283            pae = new PendingAssistExtras(activity);
10284            try {
10285                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10286                        requestType);
10287                mPendingAssistExtras.add(pae);
10288                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10289            } catch (RemoteException e) {
10290                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10291                return extras;
10292            }
10293        }
10294        synchronized (pae) {
10295            while (!pae.haveResult) {
10296                try {
10297                    pae.wait();
10298                } catch (InterruptedException e) {
10299                }
10300            }
10301            if (pae.result != null) {
10302                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10303            }
10304        }
10305        synchronized (this) {
10306            mPendingAssistExtras.remove(pae);
10307            mHandler.removeCallbacks(pae);
10308        }
10309        return extras;
10310    }
10311
10312    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10313        PendingAssistExtras pae = (PendingAssistExtras)token;
10314        synchronized (pae) {
10315            pae.result = extras;
10316            pae.haveResult = true;
10317            pae.notifyAll();
10318        }
10319    }
10320
10321    public void registerProcessObserver(IProcessObserver observer) {
10322        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10323                "registerProcessObserver()");
10324        synchronized (this) {
10325            mProcessObservers.register(observer);
10326        }
10327    }
10328
10329    @Override
10330    public void unregisterProcessObserver(IProcessObserver observer) {
10331        synchronized (this) {
10332            mProcessObservers.unregister(observer);
10333        }
10334    }
10335
10336    @Override
10337    public boolean convertFromTranslucent(IBinder token) {
10338        final long origId = Binder.clearCallingIdentity();
10339        try {
10340            synchronized (this) {
10341                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10342                if (r == null) {
10343                    return false;
10344                }
10345                final boolean translucentChanged = r.changeWindowTranslucency(true);
10346                if (translucentChanged) {
10347                    r.task.stack.releaseBackgroundResources();
10348                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10349                }
10350                mWindowManager.setAppFullscreen(token, true);
10351                return translucentChanged;
10352            }
10353        } finally {
10354            Binder.restoreCallingIdentity(origId);
10355        }
10356    }
10357
10358    @Override
10359    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10360        final long origId = Binder.clearCallingIdentity();
10361        try {
10362            synchronized (this) {
10363                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10364                if (r == null) {
10365                    return false;
10366                }
10367                int index = r.task.mActivities.lastIndexOf(r);
10368                if (index > 0) {
10369                    ActivityRecord under = r.task.mActivities.get(index - 1);
10370                    under.returningOptions = options;
10371                }
10372                final boolean translucentChanged = r.changeWindowTranslucency(false);
10373                if (translucentChanged) {
10374                    r.task.stack.convertToTranslucent(r);
10375                }
10376                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10377                mWindowManager.setAppFullscreen(token, false);
10378                return translucentChanged;
10379            }
10380        } finally {
10381            Binder.restoreCallingIdentity(origId);
10382        }
10383    }
10384
10385    @Override
10386    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10387        final long origId = Binder.clearCallingIdentity();
10388        try {
10389            synchronized (this) {
10390                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10391                if (r != null) {
10392                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10393                }
10394            }
10395            return false;
10396        } finally {
10397            Binder.restoreCallingIdentity(origId);
10398        }
10399    }
10400
10401    @Override
10402    public boolean isBackgroundVisibleBehind(IBinder token) {
10403        final long origId = Binder.clearCallingIdentity();
10404        try {
10405            synchronized (this) {
10406                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10407                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10408                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10409                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10410                return visible;
10411            }
10412        } finally {
10413            Binder.restoreCallingIdentity(origId);
10414        }
10415    }
10416
10417    @Override
10418    public ActivityOptions getActivityOptions(IBinder token) {
10419        final long origId = Binder.clearCallingIdentity();
10420        try {
10421            synchronized (this) {
10422                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10423                if (r != null) {
10424                    final ActivityOptions activityOptions = r.pendingOptions;
10425                    r.pendingOptions = null;
10426                    return activityOptions;
10427                }
10428                return null;
10429            }
10430        } finally {
10431            Binder.restoreCallingIdentity(origId);
10432        }
10433    }
10434
10435    @Override
10436    public void setImmersive(IBinder token, boolean immersive) {
10437        synchronized(this) {
10438            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10439            if (r == null) {
10440                throw new IllegalArgumentException();
10441            }
10442            r.immersive = immersive;
10443
10444            // update associated state if we're frontmost
10445            if (r == mFocusedActivity) {
10446                if (DEBUG_IMMERSIVE) {
10447                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10448                }
10449                applyUpdateLockStateLocked(r);
10450            }
10451        }
10452    }
10453
10454    @Override
10455    public boolean isImmersive(IBinder token) {
10456        synchronized (this) {
10457            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10458            if (r == null) {
10459                throw new IllegalArgumentException();
10460            }
10461            return r.immersive;
10462        }
10463    }
10464
10465    public boolean isTopActivityImmersive() {
10466        enforceNotIsolatedCaller("startActivity");
10467        synchronized (this) {
10468            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10469            return (r != null) ? r.immersive : false;
10470        }
10471    }
10472
10473    @Override
10474    public boolean isTopOfTask(IBinder token) {
10475        synchronized (this) {
10476            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10477            if (r == null) {
10478                throw new IllegalArgumentException();
10479            }
10480            return r.task.getTopActivity() == r;
10481        }
10482    }
10483
10484    public final void enterSafeMode() {
10485        synchronized(this) {
10486            // It only makes sense to do this before the system is ready
10487            // and started launching other packages.
10488            if (!mSystemReady) {
10489                try {
10490                    AppGlobals.getPackageManager().enterSafeMode();
10491                } catch (RemoteException e) {
10492                }
10493            }
10494
10495            mSafeMode = true;
10496        }
10497    }
10498
10499    public final void showSafeModeOverlay() {
10500        View v = LayoutInflater.from(mContext).inflate(
10501                com.android.internal.R.layout.safe_mode, null);
10502        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10503        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10504        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10505        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10506        lp.gravity = Gravity.BOTTOM | Gravity.START;
10507        lp.format = v.getBackground().getOpacity();
10508        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10509                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10510        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10511        ((WindowManager)mContext.getSystemService(
10512                Context.WINDOW_SERVICE)).addView(v, lp);
10513    }
10514
10515    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10516        if (!(sender instanceof PendingIntentRecord)) {
10517            return;
10518        }
10519        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10520        synchronized (stats) {
10521            if (mBatteryStatsService.isOnBattery()) {
10522                mBatteryStatsService.enforceCallingPermission();
10523                PendingIntentRecord rec = (PendingIntentRecord)sender;
10524                int MY_UID = Binder.getCallingUid();
10525                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10526                BatteryStatsImpl.Uid.Pkg pkg =
10527                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10528                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10529                pkg.incWakeupsLocked();
10530            }
10531        }
10532    }
10533
10534    public boolean killPids(int[] pids, String pReason, boolean secure) {
10535        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10536            throw new SecurityException("killPids only available to the system");
10537        }
10538        String reason = (pReason == null) ? "Unknown" : pReason;
10539        // XXX Note: don't acquire main activity lock here, because the window
10540        // manager calls in with its locks held.
10541
10542        boolean killed = false;
10543        synchronized (mPidsSelfLocked) {
10544            int[] types = new int[pids.length];
10545            int worstType = 0;
10546            for (int i=0; i<pids.length; i++) {
10547                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10548                if (proc != null) {
10549                    int type = proc.setAdj;
10550                    types[i] = type;
10551                    if (type > worstType) {
10552                        worstType = type;
10553                    }
10554                }
10555            }
10556
10557            // If the worst oom_adj is somewhere in the cached proc LRU range,
10558            // then constrain it so we will kill all cached procs.
10559            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10560                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10561                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10562            }
10563
10564            // If this is not a secure call, don't let it kill processes that
10565            // are important.
10566            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10567                worstType = ProcessList.SERVICE_ADJ;
10568            }
10569
10570            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10571            for (int i=0; i<pids.length; i++) {
10572                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10573                if (proc == null) {
10574                    continue;
10575                }
10576                int adj = proc.setAdj;
10577                if (adj >= worstType && !proc.killedByAm) {
10578                    proc.kill(reason, true);
10579                    killed = true;
10580                }
10581            }
10582        }
10583        return killed;
10584    }
10585
10586    @Override
10587    public void killUid(int uid, String reason) {
10588        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10589            throw new SecurityException("killUid only available to the system");
10590        }
10591        synchronized (this) {
10592            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10593                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10594                    reason != null ? reason : "kill uid");
10595        }
10596    }
10597
10598    @Override
10599    public boolean killProcessesBelowForeground(String reason) {
10600        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10601            throw new SecurityException("killProcessesBelowForeground() only available to system");
10602        }
10603
10604        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10605    }
10606
10607    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10608        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10609            throw new SecurityException("killProcessesBelowAdj() only available to system");
10610        }
10611
10612        boolean killed = false;
10613        synchronized (mPidsSelfLocked) {
10614            final int size = mPidsSelfLocked.size();
10615            for (int i = 0; i < size; i++) {
10616                final int pid = mPidsSelfLocked.keyAt(i);
10617                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10618                if (proc == null) continue;
10619
10620                final int adj = proc.setAdj;
10621                if (adj > belowAdj && !proc.killedByAm) {
10622                    proc.kill(reason, true);
10623                    killed = true;
10624                }
10625            }
10626        }
10627        return killed;
10628    }
10629
10630    @Override
10631    public void hang(final IBinder who, boolean allowRestart) {
10632        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10633                != PackageManager.PERMISSION_GRANTED) {
10634            throw new SecurityException("Requires permission "
10635                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10636        }
10637
10638        final IBinder.DeathRecipient death = new DeathRecipient() {
10639            @Override
10640            public void binderDied() {
10641                synchronized (this) {
10642                    notifyAll();
10643                }
10644            }
10645        };
10646
10647        try {
10648            who.linkToDeath(death, 0);
10649        } catch (RemoteException e) {
10650            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10651            return;
10652        }
10653
10654        synchronized (this) {
10655            Watchdog.getInstance().setAllowRestart(allowRestart);
10656            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10657            synchronized (death) {
10658                while (who.isBinderAlive()) {
10659                    try {
10660                        death.wait();
10661                    } catch (InterruptedException e) {
10662                    }
10663                }
10664            }
10665            Watchdog.getInstance().setAllowRestart(true);
10666        }
10667    }
10668
10669    @Override
10670    public void restart() {
10671        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10672                != PackageManager.PERMISSION_GRANTED) {
10673            throw new SecurityException("Requires permission "
10674                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10675        }
10676
10677        Log.i(TAG, "Sending shutdown broadcast...");
10678
10679        BroadcastReceiver br = new BroadcastReceiver() {
10680            @Override public void onReceive(Context context, Intent intent) {
10681                // Now the broadcast is done, finish up the low-level shutdown.
10682                Log.i(TAG, "Shutting down activity manager...");
10683                shutdown(10000);
10684                Log.i(TAG, "Shutdown complete, restarting!");
10685                Process.killProcess(Process.myPid());
10686                System.exit(10);
10687            }
10688        };
10689
10690        // First send the high-level shut down broadcast.
10691        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10692        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10693        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10694        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10695        mContext.sendOrderedBroadcastAsUser(intent,
10696                UserHandle.ALL, null, br, mHandler, 0, null, null);
10697        */
10698        br.onReceive(mContext, intent);
10699    }
10700
10701    private long getLowRamTimeSinceIdle(long now) {
10702        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10703    }
10704
10705    @Override
10706    public void performIdleMaintenance() {
10707        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10708                != PackageManager.PERMISSION_GRANTED) {
10709            throw new SecurityException("Requires permission "
10710                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10711        }
10712
10713        synchronized (this) {
10714            final long now = SystemClock.uptimeMillis();
10715            final long timeSinceLastIdle = now - mLastIdleTime;
10716            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10717            mLastIdleTime = now;
10718            mLowRamTimeSinceLastIdle = 0;
10719            if (mLowRamStartTime != 0) {
10720                mLowRamStartTime = now;
10721            }
10722
10723            StringBuilder sb = new StringBuilder(128);
10724            sb.append("Idle maintenance over ");
10725            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10726            sb.append(" low RAM for ");
10727            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10728            Slog.i(TAG, sb.toString());
10729
10730            // If at least 1/3 of our time since the last idle period has been spent
10731            // with RAM low, then we want to kill processes.
10732            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10733
10734            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10735                ProcessRecord proc = mLruProcesses.get(i);
10736                if (proc.notCachedSinceIdle) {
10737                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10738                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10739                        if (doKilling && proc.initialIdlePss != 0
10740                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10741                            proc.kill("idle maint (pss " + proc.lastPss
10742                                    + " from " + proc.initialIdlePss + ")", true);
10743                        }
10744                    }
10745                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10746                    proc.notCachedSinceIdle = true;
10747                    proc.initialIdlePss = 0;
10748                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10749                            isSleeping(), now);
10750                }
10751            }
10752
10753            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10754            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10755        }
10756    }
10757
10758    private void retrieveSettings() {
10759        final ContentResolver resolver = mContext.getContentResolver();
10760        String debugApp = Settings.Global.getString(
10761            resolver, Settings.Global.DEBUG_APP);
10762        boolean waitForDebugger = Settings.Global.getInt(
10763            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10764        boolean alwaysFinishActivities = Settings.Global.getInt(
10765            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10766        boolean forceRtl = Settings.Global.getInt(
10767                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10768        // Transfer any global setting for forcing RTL layout, into a System Property
10769        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10770
10771        Configuration configuration = new Configuration();
10772        Settings.System.getConfiguration(resolver, configuration);
10773        if (forceRtl) {
10774            // This will take care of setting the correct layout direction flags
10775            configuration.setLayoutDirection(configuration.locale);
10776        }
10777
10778        synchronized (this) {
10779            mDebugApp = mOrigDebugApp = debugApp;
10780            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10781            mAlwaysFinishActivities = alwaysFinishActivities;
10782            // This happens before any activities are started, so we can
10783            // change mConfiguration in-place.
10784            updateConfigurationLocked(configuration, null, false, true);
10785            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10786        }
10787    }
10788
10789    /** Loads resources after the current configuration has been set. */
10790    private void loadResourcesOnSystemReady() {
10791        final Resources res = mContext.getResources();
10792        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10793        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10794        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10795    }
10796
10797    public boolean testIsSystemReady() {
10798        // no need to synchronize(this) just to read & return the value
10799        return mSystemReady;
10800    }
10801
10802    private static File getCalledPreBootReceiversFile() {
10803        File dataDir = Environment.getDataDirectory();
10804        File systemDir = new File(dataDir, "system");
10805        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10806        return fname;
10807    }
10808
10809    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10810        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10811        File file = getCalledPreBootReceiversFile();
10812        FileInputStream fis = null;
10813        try {
10814            fis = new FileInputStream(file);
10815            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10816            int fvers = dis.readInt();
10817            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10818                String vers = dis.readUTF();
10819                String codename = dis.readUTF();
10820                String build = dis.readUTF();
10821                if (android.os.Build.VERSION.RELEASE.equals(vers)
10822                        && android.os.Build.VERSION.CODENAME.equals(codename)
10823                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10824                    int num = dis.readInt();
10825                    while (num > 0) {
10826                        num--;
10827                        String pkg = dis.readUTF();
10828                        String cls = dis.readUTF();
10829                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10830                    }
10831                }
10832            }
10833        } catch (FileNotFoundException e) {
10834        } catch (IOException e) {
10835            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10836        } finally {
10837            if (fis != null) {
10838                try {
10839                    fis.close();
10840                } catch (IOException e) {
10841                }
10842            }
10843        }
10844        return lastDoneReceivers;
10845    }
10846
10847    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10848        File file = getCalledPreBootReceiversFile();
10849        FileOutputStream fos = null;
10850        DataOutputStream dos = null;
10851        try {
10852            fos = new FileOutputStream(file);
10853            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10854            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10855            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10856            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10857            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10858            dos.writeInt(list.size());
10859            for (int i=0; i<list.size(); i++) {
10860                dos.writeUTF(list.get(i).getPackageName());
10861                dos.writeUTF(list.get(i).getClassName());
10862            }
10863        } catch (IOException e) {
10864            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10865            file.delete();
10866        } finally {
10867            FileUtils.sync(fos);
10868            if (dos != null) {
10869                try {
10870                    dos.close();
10871                } catch (IOException e) {
10872                    // TODO Auto-generated catch block
10873                    e.printStackTrace();
10874                }
10875            }
10876        }
10877    }
10878
10879    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10880            ArrayList<ComponentName> doneReceivers, int userId) {
10881        boolean waitingUpdate = false;
10882        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10883        List<ResolveInfo> ris = null;
10884        try {
10885            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10886                    intent, null, 0, userId);
10887        } catch (RemoteException e) {
10888        }
10889        if (ris != null) {
10890            for (int i=ris.size()-1; i>=0; i--) {
10891                if ((ris.get(i).activityInfo.applicationInfo.flags
10892                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10893                    ris.remove(i);
10894                }
10895            }
10896            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10897
10898            // For User 0, load the version number. When delivering to a new user, deliver
10899            // to all receivers.
10900            if (userId == UserHandle.USER_OWNER) {
10901                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10902                for (int i=0; i<ris.size(); i++) {
10903                    ActivityInfo ai = ris.get(i).activityInfo;
10904                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10905                    if (lastDoneReceivers.contains(comp)) {
10906                        // We already did the pre boot receiver for this app with the current
10907                        // platform version, so don't do it again...
10908                        ris.remove(i);
10909                        i--;
10910                        // ...however, do keep it as one that has been done, so we don't
10911                        // forget about it when rewriting the file of last done receivers.
10912                        doneReceivers.add(comp);
10913                    }
10914                }
10915            }
10916
10917            // If primary user, send broadcast to all available users, else just to userId
10918            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10919                    : new int[] { userId };
10920            for (int i = 0; i < ris.size(); i++) {
10921                ActivityInfo ai = ris.get(i).activityInfo;
10922                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10923                doneReceivers.add(comp);
10924                intent.setComponent(comp);
10925                for (int j=0; j<users.length; j++) {
10926                    IIntentReceiver finisher = null;
10927                    // On last receiver and user, set up a completion callback
10928                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10929                        finisher = new IIntentReceiver.Stub() {
10930                            public void performReceive(Intent intent, int resultCode,
10931                                    String data, Bundle extras, boolean ordered,
10932                                    boolean sticky, int sendingUser) {
10933                                // The raw IIntentReceiver interface is called
10934                                // with the AM lock held, so redispatch to
10935                                // execute our code without the lock.
10936                                mHandler.post(onFinishCallback);
10937                            }
10938                        };
10939                    }
10940                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10941                            + " for user " + users[j]);
10942                    broadcastIntentLocked(null, null, intent, null, finisher,
10943                            0, null, null, null, AppOpsManager.OP_NONE,
10944                            true, false, MY_PID, Process.SYSTEM_UID,
10945                            users[j]);
10946                    if (finisher != null) {
10947                        waitingUpdate = true;
10948                    }
10949                }
10950            }
10951        }
10952
10953        return waitingUpdate;
10954    }
10955
10956    public void systemReady(final Runnable goingCallback) {
10957        synchronized(this) {
10958            if (mSystemReady) {
10959                // If we're done calling all the receivers, run the next "boot phase" passed in
10960                // by the SystemServer
10961                if (goingCallback != null) {
10962                    goingCallback.run();
10963                }
10964                return;
10965            }
10966
10967            // Make sure we have the current profile info, since it is needed for
10968            // security checks.
10969            updateCurrentProfileIdsLocked();
10970
10971            if (mRecentTasks == null) {
10972                mRecentTasks = mTaskPersister.restoreTasksLocked();
10973                if (!mRecentTasks.isEmpty()) {
10974                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10975                }
10976                cleanupRecentTasksLocked(UserHandle.USER_ALL);
10977                mTaskPersister.startPersisting();
10978            }
10979
10980            // Check to see if there are any update receivers to run.
10981            if (!mDidUpdate) {
10982                if (mWaitingUpdate) {
10983                    return;
10984                }
10985                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10986                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10987                    public void run() {
10988                        synchronized (ActivityManagerService.this) {
10989                            mDidUpdate = true;
10990                        }
10991                        writeLastDonePreBootReceivers(doneReceivers);
10992                        showBootMessage(mContext.getText(
10993                                R.string.android_upgrading_complete),
10994                                false);
10995                        systemReady(goingCallback);
10996                    }
10997                }, doneReceivers, UserHandle.USER_OWNER);
10998
10999                if (mWaitingUpdate) {
11000                    return;
11001                }
11002                mDidUpdate = true;
11003            }
11004
11005            mAppOpsService.systemReady();
11006            mSystemReady = true;
11007        }
11008
11009        ArrayList<ProcessRecord> procsToKill = null;
11010        synchronized(mPidsSelfLocked) {
11011            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11012                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11013                if (!isAllowedWhileBooting(proc.info)){
11014                    if (procsToKill == null) {
11015                        procsToKill = new ArrayList<ProcessRecord>();
11016                    }
11017                    procsToKill.add(proc);
11018                }
11019            }
11020        }
11021
11022        synchronized(this) {
11023            if (procsToKill != null) {
11024                for (int i=procsToKill.size()-1; i>=0; i--) {
11025                    ProcessRecord proc = procsToKill.get(i);
11026                    Slog.i(TAG, "Removing system update proc: " + proc);
11027                    removeProcessLocked(proc, true, false, "system update done");
11028                }
11029            }
11030
11031            // Now that we have cleaned up any update processes, we
11032            // are ready to start launching real processes and know that
11033            // we won't trample on them any more.
11034            mProcessesReady = true;
11035        }
11036
11037        Slog.i(TAG, "System now ready");
11038        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11039            SystemClock.uptimeMillis());
11040
11041        synchronized(this) {
11042            // Make sure we have no pre-ready processes sitting around.
11043
11044            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11045                ResolveInfo ri = mContext.getPackageManager()
11046                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11047                                STOCK_PM_FLAGS);
11048                CharSequence errorMsg = null;
11049                if (ri != null) {
11050                    ActivityInfo ai = ri.activityInfo;
11051                    ApplicationInfo app = ai.applicationInfo;
11052                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11053                        mTopAction = Intent.ACTION_FACTORY_TEST;
11054                        mTopData = null;
11055                        mTopComponent = new ComponentName(app.packageName,
11056                                ai.name);
11057                    } else {
11058                        errorMsg = mContext.getResources().getText(
11059                                com.android.internal.R.string.factorytest_not_system);
11060                    }
11061                } else {
11062                    errorMsg = mContext.getResources().getText(
11063                            com.android.internal.R.string.factorytest_no_action);
11064                }
11065                if (errorMsg != null) {
11066                    mTopAction = null;
11067                    mTopData = null;
11068                    mTopComponent = null;
11069                    Message msg = Message.obtain();
11070                    msg.what = SHOW_FACTORY_ERROR_MSG;
11071                    msg.getData().putCharSequence("msg", errorMsg);
11072                    mHandler.sendMessage(msg);
11073                }
11074            }
11075        }
11076
11077        retrieveSettings();
11078        loadResourcesOnSystemReady();
11079
11080        synchronized (this) {
11081            readGrantedUriPermissionsLocked();
11082        }
11083
11084        if (goingCallback != null) goingCallback.run();
11085
11086        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11087                Integer.toString(mCurrentUserId), mCurrentUserId);
11088        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11089                Integer.toString(mCurrentUserId), mCurrentUserId);
11090        mSystemServiceManager.startUser(mCurrentUserId);
11091
11092        synchronized (this) {
11093            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11094                try {
11095                    List apps = AppGlobals.getPackageManager().
11096                        getPersistentApplications(STOCK_PM_FLAGS);
11097                    if (apps != null) {
11098                        int N = apps.size();
11099                        int i;
11100                        for (i=0; i<N; i++) {
11101                            ApplicationInfo info
11102                                = (ApplicationInfo)apps.get(i);
11103                            if (info != null &&
11104                                    !info.packageName.equals("android")) {
11105                                addAppLocked(info, false, null /* ABI override */);
11106                            }
11107                        }
11108                    }
11109                } catch (RemoteException ex) {
11110                    // pm is in same process, this will never happen.
11111                }
11112            }
11113
11114            // Start up initial activity.
11115            mBooting = true;
11116
11117            try {
11118                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11119                    Message msg = Message.obtain();
11120                    msg.what = SHOW_UID_ERROR_MSG;
11121                    mHandler.sendMessage(msg);
11122                }
11123            } catch (RemoteException e) {
11124            }
11125
11126            long ident = Binder.clearCallingIdentity();
11127            try {
11128                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11129                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11130                        | Intent.FLAG_RECEIVER_FOREGROUND);
11131                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11132                broadcastIntentLocked(null, null, intent,
11133                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11134                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11135                intent = new Intent(Intent.ACTION_USER_STARTING);
11136                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11137                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11138                broadcastIntentLocked(null, null, intent,
11139                        null, new IIntentReceiver.Stub() {
11140                            @Override
11141                            public void performReceive(Intent intent, int resultCode, String data,
11142                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11143                                    throws RemoteException {
11144                            }
11145                        }, 0, null, null,
11146                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11147                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11148            } catch (Throwable t) {
11149                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11150            } finally {
11151                Binder.restoreCallingIdentity(ident);
11152            }
11153            mStackSupervisor.resumeTopActivitiesLocked();
11154            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11155        }
11156    }
11157
11158    private boolean makeAppCrashingLocked(ProcessRecord app,
11159            String shortMsg, String longMsg, String stackTrace) {
11160        app.crashing = true;
11161        app.crashingReport = generateProcessError(app,
11162                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11163        startAppProblemLocked(app);
11164        app.stopFreezingAllLocked();
11165        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11166    }
11167
11168    private void makeAppNotRespondingLocked(ProcessRecord app,
11169            String activity, String shortMsg, String longMsg) {
11170        app.notResponding = true;
11171        app.notRespondingReport = generateProcessError(app,
11172                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11173                activity, shortMsg, longMsg, null);
11174        startAppProblemLocked(app);
11175        app.stopFreezingAllLocked();
11176    }
11177
11178    /**
11179     * Generate a process error record, suitable for attachment to a ProcessRecord.
11180     *
11181     * @param app The ProcessRecord in which the error occurred.
11182     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11183     *                      ActivityManager.AppErrorStateInfo
11184     * @param activity The activity associated with the crash, if known.
11185     * @param shortMsg Short message describing the crash.
11186     * @param longMsg Long message describing the crash.
11187     * @param stackTrace Full crash stack trace, may be null.
11188     *
11189     * @return Returns a fully-formed AppErrorStateInfo record.
11190     */
11191    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11192            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11193        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11194
11195        report.condition = condition;
11196        report.processName = app.processName;
11197        report.pid = app.pid;
11198        report.uid = app.info.uid;
11199        report.tag = activity;
11200        report.shortMsg = shortMsg;
11201        report.longMsg = longMsg;
11202        report.stackTrace = stackTrace;
11203
11204        return report;
11205    }
11206
11207    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11208        synchronized (this) {
11209            app.crashing = false;
11210            app.crashingReport = null;
11211            app.notResponding = false;
11212            app.notRespondingReport = null;
11213            if (app.anrDialog == fromDialog) {
11214                app.anrDialog = null;
11215            }
11216            if (app.waitDialog == fromDialog) {
11217                app.waitDialog = null;
11218            }
11219            if (app.pid > 0 && app.pid != MY_PID) {
11220                handleAppCrashLocked(app, null, null, null);
11221                app.kill("user request after error", true);
11222            }
11223        }
11224    }
11225
11226    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11227            String stackTrace) {
11228        long now = SystemClock.uptimeMillis();
11229
11230        Long crashTime;
11231        if (!app.isolated) {
11232            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11233        } else {
11234            crashTime = null;
11235        }
11236        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11237            // This process loses!
11238            Slog.w(TAG, "Process " + app.info.processName
11239                    + " has crashed too many times: killing!");
11240            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11241                    app.userId, app.info.processName, app.uid);
11242            mStackSupervisor.handleAppCrashLocked(app);
11243            if (!app.persistent) {
11244                // We don't want to start this process again until the user
11245                // explicitly does so...  but for persistent process, we really
11246                // need to keep it running.  If a persistent process is actually
11247                // repeatedly crashing, then badness for everyone.
11248                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11249                        app.info.processName);
11250                if (!app.isolated) {
11251                    // XXX We don't have a way to mark isolated processes
11252                    // as bad, since they don't have a peristent identity.
11253                    mBadProcesses.put(app.info.processName, app.uid,
11254                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11255                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11256                }
11257                app.bad = true;
11258                app.removed = true;
11259                // Don't let services in this process be restarted and potentially
11260                // annoy the user repeatedly.  Unless it is persistent, since those
11261                // processes run critical code.
11262                removeProcessLocked(app, false, false, "crash");
11263                mStackSupervisor.resumeTopActivitiesLocked();
11264                return false;
11265            }
11266            mStackSupervisor.resumeTopActivitiesLocked();
11267        } else {
11268            mStackSupervisor.finishTopRunningActivityLocked(app);
11269        }
11270
11271        // Bump up the crash count of any services currently running in the proc.
11272        for (int i=app.services.size()-1; i>=0; i--) {
11273            // Any services running in the application need to be placed
11274            // back in the pending list.
11275            ServiceRecord sr = app.services.valueAt(i);
11276            sr.crashCount++;
11277        }
11278
11279        // If the crashing process is what we consider to be the "home process" and it has been
11280        // replaced by a third-party app, clear the package preferred activities from packages
11281        // with a home activity running in the process to prevent a repeatedly crashing app
11282        // from blocking the user to manually clear the list.
11283        final ArrayList<ActivityRecord> activities = app.activities;
11284        if (app == mHomeProcess && activities.size() > 0
11285                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11286            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11287                final ActivityRecord r = activities.get(activityNdx);
11288                if (r.isHomeActivity()) {
11289                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11290                    try {
11291                        ActivityThread.getPackageManager()
11292                                .clearPackagePreferredActivities(r.packageName);
11293                    } catch (RemoteException c) {
11294                        // pm is in same process, this will never happen.
11295                    }
11296                }
11297            }
11298        }
11299
11300        if (!app.isolated) {
11301            // XXX Can't keep track of crash times for isolated processes,
11302            // because they don't have a perisistent identity.
11303            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11304        }
11305
11306        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11307        return true;
11308    }
11309
11310    void startAppProblemLocked(ProcessRecord app) {
11311        // If this app is not running under the current user, then we
11312        // can't give it a report button because that would require
11313        // launching the report UI under a different user.
11314        app.errorReportReceiver = null;
11315
11316        for (int userId : mCurrentProfileIds) {
11317            if (app.userId == userId) {
11318                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11319                        mContext, app.info.packageName, app.info.flags);
11320            }
11321        }
11322        skipCurrentReceiverLocked(app);
11323    }
11324
11325    void skipCurrentReceiverLocked(ProcessRecord app) {
11326        for (BroadcastQueue queue : mBroadcastQueues) {
11327            queue.skipCurrentReceiverLocked(app);
11328        }
11329    }
11330
11331    /**
11332     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11333     * The application process will exit immediately after this call returns.
11334     * @param app object of the crashing app, null for the system server
11335     * @param crashInfo describing the exception
11336     */
11337    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11338        ProcessRecord r = findAppProcess(app, "Crash");
11339        final String processName = app == null ? "system_server"
11340                : (r == null ? "unknown" : r.processName);
11341
11342        handleApplicationCrashInner("crash", r, processName, crashInfo);
11343    }
11344
11345    /* Native crash reporting uses this inner version because it needs to be somewhat
11346     * decoupled from the AM-managed cleanup lifecycle
11347     */
11348    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11349            ApplicationErrorReport.CrashInfo crashInfo) {
11350        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11351                UserHandle.getUserId(Binder.getCallingUid()), processName,
11352                r == null ? -1 : r.info.flags,
11353                crashInfo.exceptionClassName,
11354                crashInfo.exceptionMessage,
11355                crashInfo.throwFileName,
11356                crashInfo.throwLineNumber);
11357
11358        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11359
11360        crashApplication(r, crashInfo);
11361    }
11362
11363    public void handleApplicationStrictModeViolation(
11364            IBinder app,
11365            int violationMask,
11366            StrictMode.ViolationInfo info) {
11367        ProcessRecord r = findAppProcess(app, "StrictMode");
11368        if (r == null) {
11369            return;
11370        }
11371
11372        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11373            Integer stackFingerprint = info.hashCode();
11374            boolean logIt = true;
11375            synchronized (mAlreadyLoggedViolatedStacks) {
11376                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11377                    logIt = false;
11378                    // TODO: sub-sample into EventLog for these, with
11379                    // the info.durationMillis?  Then we'd get
11380                    // the relative pain numbers, without logging all
11381                    // the stack traces repeatedly.  We'd want to do
11382                    // likewise in the client code, which also does
11383                    // dup suppression, before the Binder call.
11384                } else {
11385                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11386                        mAlreadyLoggedViolatedStacks.clear();
11387                    }
11388                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11389                }
11390            }
11391            if (logIt) {
11392                logStrictModeViolationToDropBox(r, info);
11393            }
11394        }
11395
11396        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11397            AppErrorResult result = new AppErrorResult();
11398            synchronized (this) {
11399                final long origId = Binder.clearCallingIdentity();
11400
11401                Message msg = Message.obtain();
11402                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11403                HashMap<String, Object> data = new HashMap<String, Object>();
11404                data.put("result", result);
11405                data.put("app", r);
11406                data.put("violationMask", violationMask);
11407                data.put("info", info);
11408                msg.obj = data;
11409                mHandler.sendMessage(msg);
11410
11411                Binder.restoreCallingIdentity(origId);
11412            }
11413            int res = result.get();
11414            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11415        }
11416    }
11417
11418    // Depending on the policy in effect, there could be a bunch of
11419    // these in quick succession so we try to batch these together to
11420    // minimize disk writes, number of dropbox entries, and maximize
11421    // compression, by having more fewer, larger records.
11422    private void logStrictModeViolationToDropBox(
11423            ProcessRecord process,
11424            StrictMode.ViolationInfo info) {
11425        if (info == null) {
11426            return;
11427        }
11428        final boolean isSystemApp = process == null ||
11429                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11430                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11431        final String processName = process == null ? "unknown" : process.processName;
11432        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11433        final DropBoxManager dbox = (DropBoxManager)
11434                mContext.getSystemService(Context.DROPBOX_SERVICE);
11435
11436        // Exit early if the dropbox isn't configured to accept this report type.
11437        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11438
11439        boolean bufferWasEmpty;
11440        boolean needsFlush;
11441        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11442        synchronized (sb) {
11443            bufferWasEmpty = sb.length() == 0;
11444            appendDropBoxProcessHeaders(process, processName, sb);
11445            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11446            sb.append("System-App: ").append(isSystemApp).append("\n");
11447            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11448            if (info.violationNumThisLoop != 0) {
11449                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11450            }
11451            if (info.numAnimationsRunning != 0) {
11452                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11453            }
11454            if (info.broadcastIntentAction != null) {
11455                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11456            }
11457            if (info.durationMillis != -1) {
11458                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11459            }
11460            if (info.numInstances != -1) {
11461                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11462            }
11463            if (info.tags != null) {
11464                for (String tag : info.tags) {
11465                    sb.append("Span-Tag: ").append(tag).append("\n");
11466                }
11467            }
11468            sb.append("\n");
11469            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11470                sb.append(info.crashInfo.stackTrace);
11471            }
11472            sb.append("\n");
11473
11474            // Only buffer up to ~64k.  Various logging bits truncate
11475            // things at 128k.
11476            needsFlush = (sb.length() > 64 * 1024);
11477        }
11478
11479        // Flush immediately if the buffer's grown too large, or this
11480        // is a non-system app.  Non-system apps are isolated with a
11481        // different tag & policy and not batched.
11482        //
11483        // Batching is useful during internal testing with
11484        // StrictMode settings turned up high.  Without batching,
11485        // thousands of separate files could be created on boot.
11486        if (!isSystemApp || needsFlush) {
11487            new Thread("Error dump: " + dropboxTag) {
11488                @Override
11489                public void run() {
11490                    String report;
11491                    synchronized (sb) {
11492                        report = sb.toString();
11493                        sb.delete(0, sb.length());
11494                        sb.trimToSize();
11495                    }
11496                    if (report.length() != 0) {
11497                        dbox.addText(dropboxTag, report);
11498                    }
11499                }
11500            }.start();
11501            return;
11502        }
11503
11504        // System app batching:
11505        if (!bufferWasEmpty) {
11506            // An existing dropbox-writing thread is outstanding, so
11507            // we don't need to start it up.  The existing thread will
11508            // catch the buffer appends we just did.
11509            return;
11510        }
11511
11512        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11513        // (After this point, we shouldn't access AMS internal data structures.)
11514        new Thread("Error dump: " + dropboxTag) {
11515            @Override
11516            public void run() {
11517                // 5 second sleep to let stacks arrive and be batched together
11518                try {
11519                    Thread.sleep(5000);  // 5 seconds
11520                } catch (InterruptedException e) {}
11521
11522                String errorReport;
11523                synchronized (mStrictModeBuffer) {
11524                    errorReport = mStrictModeBuffer.toString();
11525                    if (errorReport.length() == 0) {
11526                        return;
11527                    }
11528                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11529                    mStrictModeBuffer.trimToSize();
11530                }
11531                dbox.addText(dropboxTag, errorReport);
11532            }
11533        }.start();
11534    }
11535
11536    /**
11537     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11538     * @param app object of the crashing app, null for the system server
11539     * @param tag reported by the caller
11540     * @param system whether this wtf is coming from the system
11541     * @param crashInfo describing the context of the error
11542     * @return true if the process should exit immediately (WTF is fatal)
11543     */
11544    public boolean handleApplicationWtf(IBinder app, final String tag, boolean system,
11545            final ApplicationErrorReport.CrashInfo crashInfo) {
11546        final ProcessRecord r = findAppProcess(app, "WTF");
11547        final String processName = app == null ? "system_server"
11548                : (r == null ? "unknown" : r.processName);
11549
11550        EventLog.writeEvent(EventLogTags.AM_WTF,
11551                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
11552                processName,
11553                r == null ? -1 : r.info.flags,
11554                tag, crashInfo.exceptionMessage);
11555
11556        if (system) {
11557            // If this is coming from the system, we could very well have low-level
11558            // system locks held, so we want to do this all asynchronously.  And we
11559            // never want this to become fatal, so there is that too.
11560            mHandler.post(new Runnable() {
11561                @Override public void run() {
11562                    addErrorToDropBox("wtf", r, processName, null, null, tag, null, null,
11563                            crashInfo);
11564                }
11565            });
11566            return false;
11567        }
11568
11569        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11570
11571        if (r != null && r.pid != Process.myPid() &&
11572                Settings.Global.getInt(mContext.getContentResolver(),
11573                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11574            crashApplication(r, crashInfo);
11575            return true;
11576        } else {
11577            return false;
11578        }
11579    }
11580
11581    /**
11582     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11583     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11584     */
11585    private ProcessRecord findAppProcess(IBinder app, String reason) {
11586        if (app == null) {
11587            return null;
11588        }
11589
11590        synchronized (this) {
11591            final int NP = mProcessNames.getMap().size();
11592            for (int ip=0; ip<NP; ip++) {
11593                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11594                final int NA = apps.size();
11595                for (int ia=0; ia<NA; ia++) {
11596                    ProcessRecord p = apps.valueAt(ia);
11597                    if (p.thread != null && p.thread.asBinder() == app) {
11598                        return p;
11599                    }
11600                }
11601            }
11602
11603            Slog.w(TAG, "Can't find mystery application for " + reason
11604                    + " from pid=" + Binder.getCallingPid()
11605                    + " uid=" + Binder.getCallingUid() + ": " + app);
11606            return null;
11607        }
11608    }
11609
11610    /**
11611     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11612     * to append various headers to the dropbox log text.
11613     */
11614    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11615            StringBuilder sb) {
11616        // Watchdog thread ends up invoking this function (with
11617        // a null ProcessRecord) to add the stack file to dropbox.
11618        // Do not acquire a lock on this (am) in such cases, as it
11619        // could cause a potential deadlock, if and when watchdog
11620        // is invoked due to unavailability of lock on am and it
11621        // would prevent watchdog from killing system_server.
11622        if (process == null) {
11623            sb.append("Process: ").append(processName).append("\n");
11624            return;
11625        }
11626        // Note: ProcessRecord 'process' is guarded by the service
11627        // instance.  (notably process.pkgList, which could otherwise change
11628        // concurrently during execution of this method)
11629        synchronized (this) {
11630            sb.append("Process: ").append(processName).append("\n");
11631            int flags = process.info.flags;
11632            IPackageManager pm = AppGlobals.getPackageManager();
11633            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11634            for (int ip=0; ip<process.pkgList.size(); ip++) {
11635                String pkg = process.pkgList.keyAt(ip);
11636                sb.append("Package: ").append(pkg);
11637                try {
11638                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11639                    if (pi != null) {
11640                        sb.append(" v").append(pi.versionCode);
11641                        if (pi.versionName != null) {
11642                            sb.append(" (").append(pi.versionName).append(")");
11643                        }
11644                    }
11645                } catch (RemoteException e) {
11646                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11647                }
11648                sb.append("\n");
11649            }
11650        }
11651    }
11652
11653    private static String processClass(ProcessRecord process) {
11654        if (process == null || process.pid == MY_PID) {
11655            return "system_server";
11656        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11657            return "system_app";
11658        } else {
11659            return "data_app";
11660        }
11661    }
11662
11663    /**
11664     * Write a description of an error (crash, WTF, ANR) to the drop box.
11665     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11666     * @param process which caused the error, null means the system server
11667     * @param activity which triggered the error, null if unknown
11668     * @param parent activity related to the error, null if unknown
11669     * @param subject line related to the error, null if absent
11670     * @param report in long form describing the error, null if absent
11671     * @param logFile to include in the report, null if none
11672     * @param crashInfo giving an application stack trace, null if absent
11673     */
11674    public void addErrorToDropBox(String eventType,
11675            ProcessRecord process, String processName, ActivityRecord activity,
11676            ActivityRecord parent, String subject,
11677            final String report, final File logFile,
11678            final ApplicationErrorReport.CrashInfo crashInfo) {
11679        // NOTE -- this must never acquire the ActivityManagerService lock,
11680        // otherwise the watchdog may be prevented from resetting the system.
11681
11682        final String dropboxTag = processClass(process) + "_" + eventType;
11683        final DropBoxManager dbox = (DropBoxManager)
11684                mContext.getSystemService(Context.DROPBOX_SERVICE);
11685
11686        // Exit early if the dropbox isn't configured to accept this report type.
11687        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11688
11689        final StringBuilder sb = new StringBuilder(1024);
11690        appendDropBoxProcessHeaders(process, processName, sb);
11691        if (activity != null) {
11692            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11693        }
11694        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11695            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11696        }
11697        if (parent != null && parent != activity) {
11698            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11699        }
11700        if (subject != null) {
11701            sb.append("Subject: ").append(subject).append("\n");
11702        }
11703        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11704        if (Debug.isDebuggerConnected()) {
11705            sb.append("Debugger: Connected\n");
11706        }
11707        sb.append("\n");
11708
11709        // Do the rest in a worker thread to avoid blocking the caller on I/O
11710        // (After this point, we shouldn't access AMS internal data structures.)
11711        Thread worker = new Thread("Error dump: " + dropboxTag) {
11712            @Override
11713            public void run() {
11714                if (report != null) {
11715                    sb.append(report);
11716                }
11717                if (logFile != null) {
11718                    try {
11719                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11720                                    "\n\n[[TRUNCATED]]"));
11721                    } catch (IOException e) {
11722                        Slog.e(TAG, "Error reading " + logFile, e);
11723                    }
11724                }
11725                if (crashInfo != null && crashInfo.stackTrace != null) {
11726                    sb.append(crashInfo.stackTrace);
11727                }
11728
11729                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11730                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11731                if (lines > 0) {
11732                    sb.append("\n");
11733
11734                    // Merge several logcat streams, and take the last N lines
11735                    InputStreamReader input = null;
11736                    try {
11737                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11738                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11739                                "-b", "crash",
11740                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11741
11742                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11743                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11744                        input = new InputStreamReader(logcat.getInputStream());
11745
11746                        int num;
11747                        char[] buf = new char[8192];
11748                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11749                    } catch (IOException e) {
11750                        Slog.e(TAG, "Error running logcat", e);
11751                    } finally {
11752                        if (input != null) try { input.close(); } catch (IOException e) {}
11753                    }
11754                }
11755
11756                dbox.addText(dropboxTag, sb.toString());
11757            }
11758        };
11759
11760        if (process == null) {
11761            // If process is null, we are being called from some internal code
11762            // and may be about to die -- run this synchronously.
11763            worker.run();
11764        } else {
11765            worker.start();
11766        }
11767    }
11768
11769    /**
11770     * Bring up the "unexpected error" dialog box for a crashing app.
11771     * Deal with edge cases (intercepts from instrumented applications,
11772     * ActivityController, error intent receivers, that sort of thing).
11773     * @param r the application crashing
11774     * @param crashInfo describing the failure
11775     */
11776    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11777        long timeMillis = System.currentTimeMillis();
11778        String shortMsg = crashInfo.exceptionClassName;
11779        String longMsg = crashInfo.exceptionMessage;
11780        String stackTrace = crashInfo.stackTrace;
11781        if (shortMsg != null && longMsg != null) {
11782            longMsg = shortMsg + ": " + longMsg;
11783        } else if (shortMsg != null) {
11784            longMsg = shortMsg;
11785        }
11786
11787        AppErrorResult result = new AppErrorResult();
11788        synchronized (this) {
11789            if (mController != null) {
11790                try {
11791                    String name = r != null ? r.processName : null;
11792                    int pid = r != null ? r.pid : Binder.getCallingPid();
11793                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11794                    if (!mController.appCrashed(name, pid,
11795                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11796                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11797                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11798                            Slog.w(TAG, "Skip killing native crashed app " + name
11799                                    + "(" + pid + ") during testing");
11800                        } else {
11801                            Slog.w(TAG, "Force-killing crashed app " + name
11802                                    + " at watcher's request");
11803                            if (r != null) {
11804                                r.kill("crash", true);
11805                            } else {
11806                                // Huh.
11807                                Process.killProcess(pid);
11808                                Process.killProcessGroup(uid, pid);
11809                            }
11810                        }
11811                        return;
11812                    }
11813                } catch (RemoteException e) {
11814                    mController = null;
11815                    Watchdog.getInstance().setActivityController(null);
11816                }
11817            }
11818
11819            final long origId = Binder.clearCallingIdentity();
11820
11821            // If this process is running instrumentation, finish it.
11822            if (r != null && r.instrumentationClass != null) {
11823                Slog.w(TAG, "Error in app " + r.processName
11824                      + " running instrumentation " + r.instrumentationClass + ":");
11825                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11826                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11827                Bundle info = new Bundle();
11828                info.putString("shortMsg", shortMsg);
11829                info.putString("longMsg", longMsg);
11830                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11831                Binder.restoreCallingIdentity(origId);
11832                return;
11833            }
11834
11835            // If we can't identify the process or it's already exceeded its crash quota,
11836            // quit right away without showing a crash dialog.
11837            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11838                Binder.restoreCallingIdentity(origId);
11839                return;
11840            }
11841
11842            Message msg = Message.obtain();
11843            msg.what = SHOW_ERROR_MSG;
11844            HashMap data = new HashMap();
11845            data.put("result", result);
11846            data.put("app", r);
11847            msg.obj = data;
11848            mHandler.sendMessage(msg);
11849
11850            Binder.restoreCallingIdentity(origId);
11851        }
11852
11853        int res = result.get();
11854
11855        Intent appErrorIntent = null;
11856        synchronized (this) {
11857            if (r != null && !r.isolated) {
11858                // XXX Can't keep track of crash time for isolated processes,
11859                // since they don't have a persistent identity.
11860                mProcessCrashTimes.put(r.info.processName, r.uid,
11861                        SystemClock.uptimeMillis());
11862            }
11863            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11864                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11865            }
11866        }
11867
11868        if (appErrorIntent != null) {
11869            try {
11870                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11871            } catch (ActivityNotFoundException e) {
11872                Slog.w(TAG, "bug report receiver dissappeared", e);
11873            }
11874        }
11875    }
11876
11877    Intent createAppErrorIntentLocked(ProcessRecord r,
11878            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11879        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11880        if (report == null) {
11881            return null;
11882        }
11883        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11884        result.setComponent(r.errorReportReceiver);
11885        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11886        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11887        return result;
11888    }
11889
11890    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11891            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11892        if (r.errorReportReceiver == null) {
11893            return null;
11894        }
11895
11896        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11897            return null;
11898        }
11899
11900        ApplicationErrorReport report = new ApplicationErrorReport();
11901        report.packageName = r.info.packageName;
11902        report.installerPackageName = r.errorReportReceiver.getPackageName();
11903        report.processName = r.processName;
11904        report.time = timeMillis;
11905        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11906
11907        if (r.crashing || r.forceCrashReport) {
11908            report.type = ApplicationErrorReport.TYPE_CRASH;
11909            report.crashInfo = crashInfo;
11910        } else if (r.notResponding) {
11911            report.type = ApplicationErrorReport.TYPE_ANR;
11912            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11913
11914            report.anrInfo.activity = r.notRespondingReport.tag;
11915            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11916            report.anrInfo.info = r.notRespondingReport.longMsg;
11917        }
11918
11919        return report;
11920    }
11921
11922    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11923        enforceNotIsolatedCaller("getProcessesInErrorState");
11924        // assume our apps are happy - lazy create the list
11925        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11926
11927        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11928                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11929        int userId = UserHandle.getUserId(Binder.getCallingUid());
11930
11931        synchronized (this) {
11932
11933            // iterate across all processes
11934            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11935                ProcessRecord app = mLruProcesses.get(i);
11936                if (!allUsers && app.userId != userId) {
11937                    continue;
11938                }
11939                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11940                    // This one's in trouble, so we'll generate a report for it
11941                    // crashes are higher priority (in case there's a crash *and* an anr)
11942                    ActivityManager.ProcessErrorStateInfo report = null;
11943                    if (app.crashing) {
11944                        report = app.crashingReport;
11945                    } else if (app.notResponding) {
11946                        report = app.notRespondingReport;
11947                    }
11948
11949                    if (report != null) {
11950                        if (errList == null) {
11951                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11952                        }
11953                        errList.add(report);
11954                    } else {
11955                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11956                                " crashing = " + app.crashing +
11957                                " notResponding = " + app.notResponding);
11958                    }
11959                }
11960            }
11961        }
11962
11963        return errList;
11964    }
11965
11966    static int procStateToImportance(int procState, int memAdj,
11967            ActivityManager.RunningAppProcessInfo currApp) {
11968        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11969        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11970            currApp.lru = memAdj;
11971        } else {
11972            currApp.lru = 0;
11973        }
11974        return imp;
11975    }
11976
11977    private void fillInProcMemInfo(ProcessRecord app,
11978            ActivityManager.RunningAppProcessInfo outInfo) {
11979        outInfo.pid = app.pid;
11980        outInfo.uid = app.info.uid;
11981        if (mHeavyWeightProcess == app) {
11982            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11983        }
11984        if (app.persistent) {
11985            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11986        }
11987        if (app.activities.size() > 0) {
11988            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11989        }
11990        outInfo.lastTrimLevel = app.trimMemoryLevel;
11991        int adj = app.curAdj;
11992        int procState = app.curProcState;
11993        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11994        outInfo.importanceReasonCode = app.adjTypeCode;
11995        outInfo.processState = app.curProcState;
11996    }
11997
11998    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11999        enforceNotIsolatedCaller("getRunningAppProcesses");
12000        // Lazy instantiation of list
12001        List<ActivityManager.RunningAppProcessInfo> runList = null;
12002        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12003                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12004        int userId = UserHandle.getUserId(Binder.getCallingUid());
12005        synchronized (this) {
12006            // Iterate across all processes
12007            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12008                ProcessRecord app = mLruProcesses.get(i);
12009                if (!allUsers && app.userId != userId) {
12010                    continue;
12011                }
12012                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12013                    // Generate process state info for running application
12014                    ActivityManager.RunningAppProcessInfo currApp =
12015                        new ActivityManager.RunningAppProcessInfo(app.processName,
12016                                app.pid, app.getPackageList());
12017                    fillInProcMemInfo(app, currApp);
12018                    if (app.adjSource instanceof ProcessRecord) {
12019                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12020                        currApp.importanceReasonImportance =
12021                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12022                                        app.adjSourceProcState);
12023                    } else if (app.adjSource instanceof ActivityRecord) {
12024                        ActivityRecord r = (ActivityRecord)app.adjSource;
12025                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12026                    }
12027                    if (app.adjTarget instanceof ComponentName) {
12028                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12029                    }
12030                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12031                    //        + " lru=" + currApp.lru);
12032                    if (runList == null) {
12033                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12034                    }
12035                    runList.add(currApp);
12036                }
12037            }
12038        }
12039        return runList;
12040    }
12041
12042    public List<ApplicationInfo> getRunningExternalApplications() {
12043        enforceNotIsolatedCaller("getRunningExternalApplications");
12044        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12045        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12046        if (runningApps != null && runningApps.size() > 0) {
12047            Set<String> extList = new HashSet<String>();
12048            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12049                if (app.pkgList != null) {
12050                    for (String pkg : app.pkgList) {
12051                        extList.add(pkg);
12052                    }
12053                }
12054            }
12055            IPackageManager pm = AppGlobals.getPackageManager();
12056            for (String pkg : extList) {
12057                try {
12058                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12059                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12060                        retList.add(info);
12061                    }
12062                } catch (RemoteException e) {
12063                }
12064            }
12065        }
12066        return retList;
12067    }
12068
12069    @Override
12070    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12071        enforceNotIsolatedCaller("getMyMemoryState");
12072        synchronized (this) {
12073            ProcessRecord proc;
12074            synchronized (mPidsSelfLocked) {
12075                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12076            }
12077            fillInProcMemInfo(proc, outInfo);
12078        }
12079    }
12080
12081    @Override
12082    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12083        if (checkCallingPermission(android.Manifest.permission.DUMP)
12084                != PackageManager.PERMISSION_GRANTED) {
12085            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12086                    + Binder.getCallingPid()
12087                    + ", uid=" + Binder.getCallingUid()
12088                    + " without permission "
12089                    + android.Manifest.permission.DUMP);
12090            return;
12091        }
12092
12093        boolean dumpAll = false;
12094        boolean dumpClient = false;
12095        String dumpPackage = null;
12096
12097        int opti = 0;
12098        while (opti < args.length) {
12099            String opt = args[opti];
12100            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12101                break;
12102            }
12103            opti++;
12104            if ("-a".equals(opt)) {
12105                dumpAll = true;
12106            } else if ("-c".equals(opt)) {
12107                dumpClient = true;
12108            } else if ("-h".equals(opt)) {
12109                pw.println("Activity manager dump options:");
12110                pw.println("  [-a] [-c] [-h] [cmd] ...");
12111                pw.println("  cmd may be one of:");
12112                pw.println("    a[ctivities]: activity stack state");
12113                pw.println("    r[recents]: recent activities state");
12114                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12115                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12116                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12117                pw.println("    o[om]: out of memory management");
12118                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12119                pw.println("    provider [COMP_SPEC]: provider client-side state");
12120                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12121                pw.println("    service [COMP_SPEC]: service client-side state");
12122                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12123                pw.println("    all: dump all activities");
12124                pw.println("    top: dump the top activity");
12125                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12126                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12127                pw.println("    a partial substring in a component name, a");
12128                pw.println("    hex object identifier.");
12129                pw.println("  -a: include all available server state.");
12130                pw.println("  -c: include client state.");
12131                return;
12132            } else {
12133                pw.println("Unknown argument: " + opt + "; use -h for help");
12134            }
12135        }
12136
12137        long origId = Binder.clearCallingIdentity();
12138        boolean more = false;
12139        // Is the caller requesting to dump a particular piece of data?
12140        if (opti < args.length) {
12141            String cmd = args[opti];
12142            opti++;
12143            if ("activities".equals(cmd) || "a".equals(cmd)) {
12144                synchronized (this) {
12145                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12146                }
12147            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12148                synchronized (this) {
12149                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12150                }
12151            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12152                String[] newArgs;
12153                String name;
12154                if (opti >= args.length) {
12155                    name = null;
12156                    newArgs = EMPTY_STRING_ARRAY;
12157                } else {
12158                    name = args[opti];
12159                    opti++;
12160                    newArgs = new String[args.length - opti];
12161                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12162                            args.length - opti);
12163                }
12164                synchronized (this) {
12165                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12166                }
12167            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12168                String[] newArgs;
12169                String name;
12170                if (opti >= args.length) {
12171                    name = null;
12172                    newArgs = EMPTY_STRING_ARRAY;
12173                } else {
12174                    name = args[opti];
12175                    opti++;
12176                    newArgs = new String[args.length - opti];
12177                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12178                            args.length - opti);
12179                }
12180                synchronized (this) {
12181                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12182                }
12183            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12184                String[] newArgs;
12185                String name;
12186                if (opti >= args.length) {
12187                    name = null;
12188                    newArgs = EMPTY_STRING_ARRAY;
12189                } else {
12190                    name = args[opti];
12191                    opti++;
12192                    newArgs = new String[args.length - opti];
12193                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12194                            args.length - opti);
12195                }
12196                synchronized (this) {
12197                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12198                }
12199            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12200                synchronized (this) {
12201                    dumpOomLocked(fd, pw, args, opti, true);
12202                }
12203            } else if ("provider".equals(cmd)) {
12204                String[] newArgs;
12205                String name;
12206                if (opti >= args.length) {
12207                    name = null;
12208                    newArgs = EMPTY_STRING_ARRAY;
12209                } else {
12210                    name = args[opti];
12211                    opti++;
12212                    newArgs = new String[args.length - opti];
12213                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12214                }
12215                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12216                    pw.println("No providers match: " + name);
12217                    pw.println("Use -h for help.");
12218                }
12219            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12220                synchronized (this) {
12221                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12222                }
12223            } else if ("service".equals(cmd)) {
12224                String[] newArgs;
12225                String name;
12226                if (opti >= args.length) {
12227                    name = null;
12228                    newArgs = EMPTY_STRING_ARRAY;
12229                } else {
12230                    name = args[opti];
12231                    opti++;
12232                    newArgs = new String[args.length - opti];
12233                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12234                            args.length - opti);
12235                }
12236                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12237                    pw.println("No services match: " + name);
12238                    pw.println("Use -h for help.");
12239                }
12240            } else if ("package".equals(cmd)) {
12241                String[] newArgs;
12242                if (opti >= args.length) {
12243                    pw.println("package: no package name specified");
12244                    pw.println("Use -h for help.");
12245                } else {
12246                    dumpPackage = args[opti];
12247                    opti++;
12248                    newArgs = new String[args.length - opti];
12249                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12250                            args.length - opti);
12251                    args = newArgs;
12252                    opti = 0;
12253                    more = true;
12254                }
12255            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12256                synchronized (this) {
12257                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12258                }
12259            } else {
12260                // Dumping a single activity?
12261                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12262                    pw.println("Bad activity command, or no activities match: " + cmd);
12263                    pw.println("Use -h for help.");
12264                }
12265            }
12266            if (!more) {
12267                Binder.restoreCallingIdentity(origId);
12268                return;
12269            }
12270        }
12271
12272        // No piece of data specified, dump everything.
12273        synchronized (this) {
12274            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12275            pw.println();
12276            if (dumpAll) {
12277                pw.println("-------------------------------------------------------------------------------");
12278            }
12279            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12280            pw.println();
12281            if (dumpAll) {
12282                pw.println("-------------------------------------------------------------------------------");
12283            }
12284            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12285            pw.println();
12286            if (dumpAll) {
12287                pw.println("-------------------------------------------------------------------------------");
12288            }
12289            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12290            pw.println();
12291            if (dumpAll) {
12292                pw.println("-------------------------------------------------------------------------------");
12293            }
12294            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12295            pw.println();
12296            if (dumpAll) {
12297                pw.println("-------------------------------------------------------------------------------");
12298            }
12299            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12300            pw.println();
12301            if (dumpAll) {
12302                pw.println("-------------------------------------------------------------------------------");
12303            }
12304            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12305        }
12306        Binder.restoreCallingIdentity(origId);
12307    }
12308
12309    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12310            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12311        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12312
12313        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12314                dumpPackage);
12315        boolean needSep = printedAnything;
12316
12317        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12318                dumpPackage, needSep, "  mFocusedActivity: ");
12319        if (printed) {
12320            printedAnything = true;
12321            needSep = false;
12322        }
12323
12324        if (dumpPackage == null) {
12325            if (needSep) {
12326                pw.println();
12327            }
12328            needSep = true;
12329            printedAnything = true;
12330            mStackSupervisor.dump(pw, "  ");
12331        }
12332
12333        if (!printedAnything) {
12334            pw.println("  (nothing)");
12335        }
12336    }
12337
12338    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12339            int opti, boolean dumpAll, String dumpPackage) {
12340        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
12341
12342        boolean printedAnything = false;
12343
12344        if (mRecentTasks.size() > 0) {
12345            boolean printedHeader = false;
12346
12347            final int N = mRecentTasks.size();
12348            for (int i=0; i<N; i++) {
12349                TaskRecord tr = mRecentTasks.get(i);
12350                if (dumpPackage != null) {
12351                    if (tr.realActivity == null ||
12352                            !dumpPackage.equals(tr.realActivity)) {
12353                        continue;
12354                    }
12355                }
12356                if (!printedHeader) {
12357                    pw.println("  Recent tasks:");
12358                    printedHeader = true;
12359                    printedAnything = true;
12360                }
12361                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12362                        pw.println(tr);
12363                if (dumpAll) {
12364                    mRecentTasks.get(i).dump(pw, "    ");
12365                }
12366            }
12367        }
12368
12369        if (!printedAnything) {
12370            pw.println("  (nothing)");
12371        }
12372    }
12373
12374    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12375            int opti, boolean dumpAll, String dumpPackage) {
12376        boolean needSep = false;
12377        boolean printedAnything = false;
12378        int numPers = 0;
12379
12380        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12381
12382        if (dumpAll) {
12383            final int NP = mProcessNames.getMap().size();
12384            for (int ip=0; ip<NP; ip++) {
12385                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12386                final int NA = procs.size();
12387                for (int ia=0; ia<NA; ia++) {
12388                    ProcessRecord r = procs.valueAt(ia);
12389                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12390                        continue;
12391                    }
12392                    if (!needSep) {
12393                        pw.println("  All known processes:");
12394                        needSep = true;
12395                        printedAnything = true;
12396                    }
12397                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12398                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12399                        pw.print(" "); pw.println(r);
12400                    r.dump(pw, "    ");
12401                    if (r.persistent) {
12402                        numPers++;
12403                    }
12404                }
12405            }
12406        }
12407
12408        if (mIsolatedProcesses.size() > 0) {
12409            boolean printed = false;
12410            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12411                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12412                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12413                    continue;
12414                }
12415                if (!printed) {
12416                    if (needSep) {
12417                        pw.println();
12418                    }
12419                    pw.println("  Isolated process list (sorted by uid):");
12420                    printedAnything = true;
12421                    printed = true;
12422                    needSep = true;
12423                }
12424                pw.println(String.format("%sIsolated #%2d: %s",
12425                        "    ", i, r.toString()));
12426            }
12427        }
12428
12429        if (mLruProcesses.size() > 0) {
12430            if (needSep) {
12431                pw.println();
12432            }
12433            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12434                    pw.print(" total, non-act at ");
12435                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12436                    pw.print(", non-svc at ");
12437                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12438                    pw.println("):");
12439            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12440            needSep = true;
12441            printedAnything = true;
12442        }
12443
12444        if (dumpAll || dumpPackage != null) {
12445            synchronized (mPidsSelfLocked) {
12446                boolean printed = false;
12447                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12448                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12449                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12450                        continue;
12451                    }
12452                    if (!printed) {
12453                        if (needSep) pw.println();
12454                        needSep = true;
12455                        pw.println("  PID mappings:");
12456                        printed = true;
12457                        printedAnything = true;
12458                    }
12459                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12460                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12461                }
12462            }
12463        }
12464
12465        if (mForegroundProcesses.size() > 0) {
12466            synchronized (mPidsSelfLocked) {
12467                boolean printed = false;
12468                for (int i=0; i<mForegroundProcesses.size(); i++) {
12469                    ProcessRecord r = mPidsSelfLocked.get(
12470                            mForegroundProcesses.valueAt(i).pid);
12471                    if (dumpPackage != null && (r == null
12472                            || !r.pkgList.containsKey(dumpPackage))) {
12473                        continue;
12474                    }
12475                    if (!printed) {
12476                        if (needSep) pw.println();
12477                        needSep = true;
12478                        pw.println("  Foreground Processes:");
12479                        printed = true;
12480                        printedAnything = true;
12481                    }
12482                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12483                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12484                }
12485            }
12486        }
12487
12488        if (mPersistentStartingProcesses.size() > 0) {
12489            if (needSep) pw.println();
12490            needSep = true;
12491            printedAnything = true;
12492            pw.println("  Persisent processes that are starting:");
12493            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12494                    "Starting Norm", "Restarting PERS", dumpPackage);
12495        }
12496
12497        if (mRemovedProcesses.size() > 0) {
12498            if (needSep) pw.println();
12499            needSep = true;
12500            printedAnything = true;
12501            pw.println("  Processes that are being removed:");
12502            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12503                    "Removed Norm", "Removed PERS", dumpPackage);
12504        }
12505
12506        if (mProcessesOnHold.size() > 0) {
12507            if (needSep) pw.println();
12508            needSep = true;
12509            printedAnything = true;
12510            pw.println("  Processes that are on old until the system is ready:");
12511            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12512                    "OnHold Norm", "OnHold PERS", dumpPackage);
12513        }
12514
12515        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12516
12517        if (mProcessCrashTimes.getMap().size() > 0) {
12518            boolean printed = false;
12519            long now = SystemClock.uptimeMillis();
12520            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12521            final int NP = pmap.size();
12522            for (int ip=0; ip<NP; ip++) {
12523                String pname = pmap.keyAt(ip);
12524                SparseArray<Long> uids = pmap.valueAt(ip);
12525                final int N = uids.size();
12526                for (int i=0; i<N; i++) {
12527                    int puid = uids.keyAt(i);
12528                    ProcessRecord r = mProcessNames.get(pname, puid);
12529                    if (dumpPackage != null && (r == null
12530                            || !r.pkgList.containsKey(dumpPackage))) {
12531                        continue;
12532                    }
12533                    if (!printed) {
12534                        if (needSep) pw.println();
12535                        needSep = true;
12536                        pw.println("  Time since processes crashed:");
12537                        printed = true;
12538                        printedAnything = true;
12539                    }
12540                    pw.print("    Process "); pw.print(pname);
12541                            pw.print(" uid "); pw.print(puid);
12542                            pw.print(": last crashed ");
12543                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12544                            pw.println(" ago");
12545                }
12546            }
12547        }
12548
12549        if (mBadProcesses.getMap().size() > 0) {
12550            boolean printed = false;
12551            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12552            final int NP = pmap.size();
12553            for (int ip=0; ip<NP; ip++) {
12554                String pname = pmap.keyAt(ip);
12555                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12556                final int N = uids.size();
12557                for (int i=0; i<N; i++) {
12558                    int puid = uids.keyAt(i);
12559                    ProcessRecord r = mProcessNames.get(pname, puid);
12560                    if (dumpPackage != null && (r == null
12561                            || !r.pkgList.containsKey(dumpPackage))) {
12562                        continue;
12563                    }
12564                    if (!printed) {
12565                        if (needSep) pw.println();
12566                        needSep = true;
12567                        pw.println("  Bad processes:");
12568                        printedAnything = true;
12569                    }
12570                    BadProcessInfo info = uids.valueAt(i);
12571                    pw.print("    Bad process "); pw.print(pname);
12572                            pw.print(" uid "); pw.print(puid);
12573                            pw.print(": crashed at time "); pw.println(info.time);
12574                    if (info.shortMsg != null) {
12575                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12576                    }
12577                    if (info.longMsg != null) {
12578                        pw.print("      Long msg: "); pw.println(info.longMsg);
12579                    }
12580                    if (info.stack != null) {
12581                        pw.println("      Stack:");
12582                        int lastPos = 0;
12583                        for (int pos=0; pos<info.stack.length(); pos++) {
12584                            if (info.stack.charAt(pos) == '\n') {
12585                                pw.print("        ");
12586                                pw.write(info.stack, lastPos, pos-lastPos);
12587                                pw.println();
12588                                lastPos = pos+1;
12589                            }
12590                        }
12591                        if (lastPos < info.stack.length()) {
12592                            pw.print("        ");
12593                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12594                            pw.println();
12595                        }
12596                    }
12597                }
12598            }
12599        }
12600
12601        if (dumpPackage == null) {
12602            pw.println();
12603            needSep = false;
12604            pw.println("  mStartedUsers:");
12605            for (int i=0; i<mStartedUsers.size(); i++) {
12606                UserStartedState uss = mStartedUsers.valueAt(i);
12607                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12608                        pw.print(": "); uss.dump("", pw);
12609            }
12610            pw.print("  mStartedUserArray: [");
12611            for (int i=0; i<mStartedUserArray.length; i++) {
12612                if (i > 0) pw.print(", ");
12613                pw.print(mStartedUserArray[i]);
12614            }
12615            pw.println("]");
12616            pw.print("  mUserLru: [");
12617            for (int i=0; i<mUserLru.size(); i++) {
12618                if (i > 0) pw.print(", ");
12619                pw.print(mUserLru.get(i));
12620            }
12621            pw.println("]");
12622            if (dumpAll) {
12623                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12624            }
12625            synchronized (mUserProfileGroupIdsSelfLocked) {
12626                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12627                    pw.println("  mUserProfileGroupIds:");
12628                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12629                        pw.print("    User #");
12630                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12631                        pw.print(" -> profile #");
12632                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12633                    }
12634                }
12635            }
12636        }
12637        if (mHomeProcess != null && (dumpPackage == null
12638                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12639            if (needSep) {
12640                pw.println();
12641                needSep = false;
12642            }
12643            pw.println("  mHomeProcess: " + mHomeProcess);
12644        }
12645        if (mPreviousProcess != null && (dumpPackage == null
12646                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12647            if (needSep) {
12648                pw.println();
12649                needSep = false;
12650            }
12651            pw.println("  mPreviousProcess: " + mPreviousProcess);
12652        }
12653        if (dumpAll) {
12654            StringBuilder sb = new StringBuilder(128);
12655            sb.append("  mPreviousProcessVisibleTime: ");
12656            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12657            pw.println(sb);
12658        }
12659        if (mHeavyWeightProcess != null && (dumpPackage == null
12660                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12661            if (needSep) {
12662                pw.println();
12663                needSep = false;
12664            }
12665            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12666        }
12667        if (dumpPackage == null) {
12668            pw.println("  mConfiguration: " + mConfiguration);
12669        }
12670        if (dumpAll) {
12671            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12672            if (mCompatModePackages.getPackages().size() > 0) {
12673                boolean printed = false;
12674                for (Map.Entry<String, Integer> entry
12675                        : mCompatModePackages.getPackages().entrySet()) {
12676                    String pkg = entry.getKey();
12677                    int mode = entry.getValue();
12678                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12679                        continue;
12680                    }
12681                    if (!printed) {
12682                        pw.println("  mScreenCompatPackages:");
12683                        printed = true;
12684                    }
12685                    pw.print("    "); pw.print(pkg); pw.print(": ");
12686                            pw.print(mode); pw.println();
12687                }
12688            }
12689        }
12690        if (dumpPackage == null) {
12691            if (mSleeping || mWentToSleep || mLockScreenShown) {
12692                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12693                        + " mLockScreenShown " + mLockScreenShown);
12694            }
12695            if (mShuttingDown || mRunningVoice) {
12696                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12697            }
12698        }
12699        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12700                || mOrigWaitForDebugger) {
12701            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12702                    || dumpPackage.equals(mOrigDebugApp)) {
12703                if (needSep) {
12704                    pw.println();
12705                    needSep = false;
12706                }
12707                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12708                        + " mDebugTransient=" + mDebugTransient
12709                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12710            }
12711        }
12712        if (mOpenGlTraceApp != null) {
12713            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12714                if (needSep) {
12715                    pw.println();
12716                    needSep = false;
12717                }
12718                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12719            }
12720        }
12721        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12722                || mProfileFd != null) {
12723            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12724                if (needSep) {
12725                    pw.println();
12726                    needSep = false;
12727                }
12728                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12729                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12730                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12731                        + mAutoStopProfiler);
12732                pw.println("  mProfileType=" + mProfileType);
12733            }
12734        }
12735        if (dumpPackage == null) {
12736            if (mAlwaysFinishActivities || mController != null) {
12737                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12738                        + " mController=" + mController);
12739            }
12740            if (dumpAll) {
12741                pw.println("  Total persistent processes: " + numPers);
12742                pw.println("  mProcessesReady=" + mProcessesReady
12743                        + " mSystemReady=" + mSystemReady);
12744                pw.println("  mBooting=" + mBooting
12745                        + " mBooted=" + mBooted
12746                        + " mFactoryTest=" + mFactoryTest);
12747                pw.print("  mLastPowerCheckRealtime=");
12748                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12749                        pw.println("");
12750                pw.print("  mLastPowerCheckUptime=");
12751                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12752                        pw.println("");
12753                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12754                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12755                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12756                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12757                        + " (" + mLruProcesses.size() + " total)"
12758                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12759                        + " mNumServiceProcs=" + mNumServiceProcs
12760                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12761                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12762                        + " mLastMemoryLevel" + mLastMemoryLevel
12763                        + " mLastNumProcesses" + mLastNumProcesses);
12764                long now = SystemClock.uptimeMillis();
12765                pw.print("  mLastIdleTime=");
12766                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12767                        pw.print(" mLowRamSinceLastIdle=");
12768                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12769                        pw.println();
12770            }
12771        }
12772
12773        if (!printedAnything) {
12774            pw.println("  (nothing)");
12775        }
12776    }
12777
12778    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12779            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12780        if (mProcessesToGc.size() > 0) {
12781            boolean printed = false;
12782            long now = SystemClock.uptimeMillis();
12783            for (int i=0; i<mProcessesToGc.size(); i++) {
12784                ProcessRecord proc = mProcessesToGc.get(i);
12785                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12786                    continue;
12787                }
12788                if (!printed) {
12789                    if (needSep) pw.println();
12790                    needSep = true;
12791                    pw.println("  Processes that are waiting to GC:");
12792                    printed = true;
12793                }
12794                pw.print("    Process "); pw.println(proc);
12795                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12796                        pw.print(", last gced=");
12797                        pw.print(now-proc.lastRequestedGc);
12798                        pw.print(" ms ago, last lowMem=");
12799                        pw.print(now-proc.lastLowMemory);
12800                        pw.println(" ms ago");
12801
12802            }
12803        }
12804        return needSep;
12805    }
12806
12807    void printOomLevel(PrintWriter pw, String name, int adj) {
12808        pw.print("    ");
12809        if (adj >= 0) {
12810            pw.print(' ');
12811            if (adj < 10) pw.print(' ');
12812        } else {
12813            if (adj > -10) pw.print(' ');
12814        }
12815        pw.print(adj);
12816        pw.print(": ");
12817        pw.print(name);
12818        pw.print(" (");
12819        pw.print(mProcessList.getMemLevel(adj)/1024);
12820        pw.println(" kB)");
12821    }
12822
12823    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12824            int opti, boolean dumpAll) {
12825        boolean needSep = false;
12826
12827        if (mLruProcesses.size() > 0) {
12828            if (needSep) pw.println();
12829            needSep = true;
12830            pw.println("  OOM levels:");
12831            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12832            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12833            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12834            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12835            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12836            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12837            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12838            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12839            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12840            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12841            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12842            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12843            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12844
12845            if (needSep) pw.println();
12846            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12847                    pw.print(" total, non-act at ");
12848                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12849                    pw.print(", non-svc at ");
12850                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12851                    pw.println("):");
12852            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12853            needSep = true;
12854        }
12855
12856        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12857
12858        pw.println();
12859        pw.println("  mHomeProcess: " + mHomeProcess);
12860        pw.println("  mPreviousProcess: " + mPreviousProcess);
12861        if (mHeavyWeightProcess != null) {
12862            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12863        }
12864
12865        return true;
12866    }
12867
12868    /**
12869     * There are three ways to call this:
12870     *  - no provider specified: dump all the providers
12871     *  - a flattened component name that matched an existing provider was specified as the
12872     *    first arg: dump that one provider
12873     *  - the first arg isn't the flattened component name of an existing provider:
12874     *    dump all providers whose component contains the first arg as a substring
12875     */
12876    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12877            int opti, boolean dumpAll) {
12878        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12879    }
12880
12881    static class ItemMatcher {
12882        ArrayList<ComponentName> components;
12883        ArrayList<String> strings;
12884        ArrayList<Integer> objects;
12885        boolean all;
12886
12887        ItemMatcher() {
12888            all = true;
12889        }
12890
12891        void build(String name) {
12892            ComponentName componentName = ComponentName.unflattenFromString(name);
12893            if (componentName != null) {
12894                if (components == null) {
12895                    components = new ArrayList<ComponentName>();
12896                }
12897                components.add(componentName);
12898                all = false;
12899            } else {
12900                int objectId = 0;
12901                // Not a '/' separated full component name; maybe an object ID?
12902                try {
12903                    objectId = Integer.parseInt(name, 16);
12904                    if (objects == null) {
12905                        objects = new ArrayList<Integer>();
12906                    }
12907                    objects.add(objectId);
12908                    all = false;
12909                } catch (RuntimeException e) {
12910                    // Not an integer; just do string match.
12911                    if (strings == null) {
12912                        strings = new ArrayList<String>();
12913                    }
12914                    strings.add(name);
12915                    all = false;
12916                }
12917            }
12918        }
12919
12920        int build(String[] args, int opti) {
12921            for (; opti<args.length; opti++) {
12922                String name = args[opti];
12923                if ("--".equals(name)) {
12924                    return opti+1;
12925                }
12926                build(name);
12927            }
12928            return opti;
12929        }
12930
12931        boolean match(Object object, ComponentName comp) {
12932            if (all) {
12933                return true;
12934            }
12935            if (components != null) {
12936                for (int i=0; i<components.size(); i++) {
12937                    if (components.get(i).equals(comp)) {
12938                        return true;
12939                    }
12940                }
12941            }
12942            if (objects != null) {
12943                for (int i=0; i<objects.size(); i++) {
12944                    if (System.identityHashCode(object) == objects.get(i)) {
12945                        return true;
12946                    }
12947                }
12948            }
12949            if (strings != null) {
12950                String flat = comp.flattenToString();
12951                for (int i=0; i<strings.size(); i++) {
12952                    if (flat.contains(strings.get(i))) {
12953                        return true;
12954                    }
12955                }
12956            }
12957            return false;
12958        }
12959    }
12960
12961    /**
12962     * There are three things that cmd can be:
12963     *  - a flattened component name that matches an existing activity
12964     *  - the cmd arg isn't the flattened component name of an existing activity:
12965     *    dump all activity whose component contains the cmd as a substring
12966     *  - A hex number of the ActivityRecord object instance.
12967     */
12968    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12969            int opti, boolean dumpAll) {
12970        ArrayList<ActivityRecord> activities;
12971
12972        synchronized (this) {
12973            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12974        }
12975
12976        if (activities.size() <= 0) {
12977            return false;
12978        }
12979
12980        String[] newArgs = new String[args.length - opti];
12981        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12982
12983        TaskRecord lastTask = null;
12984        boolean needSep = false;
12985        for (int i=activities.size()-1; i>=0; i--) {
12986            ActivityRecord r = activities.get(i);
12987            if (needSep) {
12988                pw.println();
12989            }
12990            needSep = true;
12991            synchronized (this) {
12992                if (lastTask != r.task) {
12993                    lastTask = r.task;
12994                    pw.print("TASK "); pw.print(lastTask.affinity);
12995                            pw.print(" id="); pw.println(lastTask.taskId);
12996                    if (dumpAll) {
12997                        lastTask.dump(pw, "  ");
12998                    }
12999                }
13000            }
13001            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13002        }
13003        return true;
13004    }
13005
13006    /**
13007     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13008     * there is a thread associated with the activity.
13009     */
13010    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13011            final ActivityRecord r, String[] args, boolean dumpAll) {
13012        String innerPrefix = prefix + "  ";
13013        synchronized (this) {
13014            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13015                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13016                    pw.print(" pid=");
13017                    if (r.app != null) pw.println(r.app.pid);
13018                    else pw.println("(not running)");
13019            if (dumpAll) {
13020                r.dump(pw, innerPrefix);
13021            }
13022        }
13023        if (r.app != null && r.app.thread != null) {
13024            // flush anything that is already in the PrintWriter since the thread is going
13025            // to write to the file descriptor directly
13026            pw.flush();
13027            try {
13028                TransferPipe tp = new TransferPipe();
13029                try {
13030                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13031                            r.appToken, innerPrefix, args);
13032                    tp.go(fd);
13033                } finally {
13034                    tp.kill();
13035                }
13036            } catch (IOException e) {
13037                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13038            } catch (RemoteException e) {
13039                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13040            }
13041        }
13042    }
13043
13044    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13045            int opti, boolean dumpAll, String dumpPackage) {
13046        boolean needSep = false;
13047        boolean onlyHistory = false;
13048        boolean printedAnything = false;
13049
13050        if ("history".equals(dumpPackage)) {
13051            if (opti < args.length && "-s".equals(args[opti])) {
13052                dumpAll = false;
13053            }
13054            onlyHistory = true;
13055            dumpPackage = null;
13056        }
13057
13058        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13059        if (!onlyHistory && dumpAll) {
13060            if (mRegisteredReceivers.size() > 0) {
13061                boolean printed = false;
13062                Iterator it = mRegisteredReceivers.values().iterator();
13063                while (it.hasNext()) {
13064                    ReceiverList r = (ReceiverList)it.next();
13065                    if (dumpPackage != null && (r.app == null ||
13066                            !dumpPackage.equals(r.app.info.packageName))) {
13067                        continue;
13068                    }
13069                    if (!printed) {
13070                        pw.println("  Registered Receivers:");
13071                        needSep = true;
13072                        printed = true;
13073                        printedAnything = true;
13074                    }
13075                    pw.print("  * "); pw.println(r);
13076                    r.dump(pw, "    ");
13077                }
13078            }
13079
13080            if (mReceiverResolver.dump(pw, needSep ?
13081                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13082                    "    ", dumpPackage, false)) {
13083                needSep = true;
13084                printedAnything = true;
13085            }
13086        }
13087
13088        for (BroadcastQueue q : mBroadcastQueues) {
13089            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13090            printedAnything |= needSep;
13091        }
13092
13093        needSep = true;
13094
13095        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13096            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13097                if (needSep) {
13098                    pw.println();
13099                }
13100                needSep = true;
13101                printedAnything = true;
13102                pw.print("  Sticky broadcasts for user ");
13103                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13104                StringBuilder sb = new StringBuilder(128);
13105                for (Map.Entry<String, ArrayList<Intent>> ent
13106                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13107                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13108                    if (dumpAll) {
13109                        pw.println(":");
13110                        ArrayList<Intent> intents = ent.getValue();
13111                        final int N = intents.size();
13112                        for (int i=0; i<N; i++) {
13113                            sb.setLength(0);
13114                            sb.append("    Intent: ");
13115                            intents.get(i).toShortString(sb, false, true, false, false);
13116                            pw.println(sb.toString());
13117                            Bundle bundle = intents.get(i).getExtras();
13118                            if (bundle != null) {
13119                                pw.print("      ");
13120                                pw.println(bundle.toString());
13121                            }
13122                        }
13123                    } else {
13124                        pw.println("");
13125                    }
13126                }
13127            }
13128        }
13129
13130        if (!onlyHistory && dumpAll) {
13131            pw.println();
13132            for (BroadcastQueue queue : mBroadcastQueues) {
13133                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13134                        + queue.mBroadcastsScheduled);
13135            }
13136            pw.println("  mHandler:");
13137            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13138            needSep = true;
13139            printedAnything = true;
13140        }
13141
13142        if (!printedAnything) {
13143            pw.println("  (nothing)");
13144        }
13145    }
13146
13147    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13148            int opti, boolean dumpAll, String dumpPackage) {
13149        boolean needSep;
13150        boolean printedAnything = false;
13151
13152        ItemMatcher matcher = new ItemMatcher();
13153        matcher.build(args, opti);
13154
13155        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13156
13157        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13158        printedAnything |= needSep;
13159
13160        if (mLaunchingProviders.size() > 0) {
13161            boolean printed = false;
13162            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13163                ContentProviderRecord r = mLaunchingProviders.get(i);
13164                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13165                    continue;
13166                }
13167                if (!printed) {
13168                    if (needSep) pw.println();
13169                    needSep = true;
13170                    pw.println("  Launching content providers:");
13171                    printed = true;
13172                    printedAnything = true;
13173                }
13174                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13175                        pw.println(r);
13176            }
13177        }
13178
13179        if (mGrantedUriPermissions.size() > 0) {
13180            boolean printed = false;
13181            int dumpUid = -2;
13182            if (dumpPackage != null) {
13183                try {
13184                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13185                } catch (NameNotFoundException e) {
13186                    dumpUid = -1;
13187                }
13188            }
13189            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13190                int uid = mGrantedUriPermissions.keyAt(i);
13191                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13192                    continue;
13193                }
13194                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13195                if (!printed) {
13196                    if (needSep) pw.println();
13197                    needSep = true;
13198                    pw.println("  Granted Uri Permissions:");
13199                    printed = true;
13200                    printedAnything = true;
13201                }
13202                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13203                for (UriPermission perm : perms.values()) {
13204                    pw.print("    "); pw.println(perm);
13205                    if (dumpAll) {
13206                        perm.dump(pw, "      ");
13207                    }
13208                }
13209            }
13210        }
13211
13212        if (!printedAnything) {
13213            pw.println("  (nothing)");
13214        }
13215    }
13216
13217    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13218            int opti, boolean dumpAll, String dumpPackage) {
13219        boolean printed = false;
13220
13221        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13222
13223        if (mIntentSenderRecords.size() > 0) {
13224            Iterator<WeakReference<PendingIntentRecord>> it
13225                    = mIntentSenderRecords.values().iterator();
13226            while (it.hasNext()) {
13227                WeakReference<PendingIntentRecord> ref = it.next();
13228                PendingIntentRecord rec = ref != null ? ref.get(): null;
13229                if (dumpPackage != null && (rec == null
13230                        || !dumpPackage.equals(rec.key.packageName))) {
13231                    continue;
13232                }
13233                printed = true;
13234                if (rec != null) {
13235                    pw.print("  * "); pw.println(rec);
13236                    if (dumpAll) {
13237                        rec.dump(pw, "    ");
13238                    }
13239                } else {
13240                    pw.print("  * "); pw.println(ref);
13241                }
13242            }
13243        }
13244
13245        if (!printed) {
13246            pw.println("  (nothing)");
13247        }
13248    }
13249
13250    private static final int dumpProcessList(PrintWriter pw,
13251            ActivityManagerService service, List list,
13252            String prefix, String normalLabel, String persistentLabel,
13253            String dumpPackage) {
13254        int numPers = 0;
13255        final int N = list.size()-1;
13256        for (int i=N; i>=0; i--) {
13257            ProcessRecord r = (ProcessRecord)list.get(i);
13258            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13259                continue;
13260            }
13261            pw.println(String.format("%s%s #%2d: %s",
13262                    prefix, (r.persistent ? persistentLabel : normalLabel),
13263                    i, r.toString()));
13264            if (r.persistent) {
13265                numPers++;
13266            }
13267        }
13268        return numPers;
13269    }
13270
13271    private static final boolean dumpProcessOomList(PrintWriter pw,
13272            ActivityManagerService service, List<ProcessRecord> origList,
13273            String prefix, String normalLabel, String persistentLabel,
13274            boolean inclDetails, String dumpPackage) {
13275
13276        ArrayList<Pair<ProcessRecord, Integer>> list
13277                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13278        for (int i=0; i<origList.size(); i++) {
13279            ProcessRecord r = origList.get(i);
13280            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13281                continue;
13282            }
13283            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13284        }
13285
13286        if (list.size() <= 0) {
13287            return false;
13288        }
13289
13290        Comparator<Pair<ProcessRecord, Integer>> comparator
13291                = new Comparator<Pair<ProcessRecord, Integer>>() {
13292            @Override
13293            public int compare(Pair<ProcessRecord, Integer> object1,
13294                    Pair<ProcessRecord, Integer> object2) {
13295                if (object1.first.setAdj != object2.first.setAdj) {
13296                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13297                }
13298                if (object1.second.intValue() != object2.second.intValue()) {
13299                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13300                }
13301                return 0;
13302            }
13303        };
13304
13305        Collections.sort(list, comparator);
13306
13307        final long curRealtime = SystemClock.elapsedRealtime();
13308        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13309        final long curUptime = SystemClock.uptimeMillis();
13310        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13311
13312        for (int i=list.size()-1; i>=0; i--) {
13313            ProcessRecord r = list.get(i).first;
13314            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13315            char schedGroup;
13316            switch (r.setSchedGroup) {
13317                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13318                    schedGroup = 'B';
13319                    break;
13320                case Process.THREAD_GROUP_DEFAULT:
13321                    schedGroup = 'F';
13322                    break;
13323                default:
13324                    schedGroup = '?';
13325                    break;
13326            }
13327            char foreground;
13328            if (r.foregroundActivities) {
13329                foreground = 'A';
13330            } else if (r.foregroundServices) {
13331                foreground = 'S';
13332            } else {
13333                foreground = ' ';
13334            }
13335            String procState = ProcessList.makeProcStateString(r.curProcState);
13336            pw.print(prefix);
13337            pw.print(r.persistent ? persistentLabel : normalLabel);
13338            pw.print(" #");
13339            int num = (origList.size()-1)-list.get(i).second;
13340            if (num < 10) pw.print(' ');
13341            pw.print(num);
13342            pw.print(": ");
13343            pw.print(oomAdj);
13344            pw.print(' ');
13345            pw.print(schedGroup);
13346            pw.print('/');
13347            pw.print(foreground);
13348            pw.print('/');
13349            pw.print(procState);
13350            pw.print(" trm:");
13351            if (r.trimMemoryLevel < 10) pw.print(' ');
13352            pw.print(r.trimMemoryLevel);
13353            pw.print(' ');
13354            pw.print(r.toShortString());
13355            pw.print(" (");
13356            pw.print(r.adjType);
13357            pw.println(')');
13358            if (r.adjSource != null || r.adjTarget != null) {
13359                pw.print(prefix);
13360                pw.print("    ");
13361                if (r.adjTarget instanceof ComponentName) {
13362                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13363                } else if (r.adjTarget != null) {
13364                    pw.print(r.adjTarget.toString());
13365                } else {
13366                    pw.print("{null}");
13367                }
13368                pw.print("<=");
13369                if (r.adjSource instanceof ProcessRecord) {
13370                    pw.print("Proc{");
13371                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13372                    pw.println("}");
13373                } else if (r.adjSource != null) {
13374                    pw.println(r.adjSource.toString());
13375                } else {
13376                    pw.println("{null}");
13377                }
13378            }
13379            if (inclDetails) {
13380                pw.print(prefix);
13381                pw.print("    ");
13382                pw.print("oom: max="); pw.print(r.maxAdj);
13383                pw.print(" curRaw="); pw.print(r.curRawAdj);
13384                pw.print(" setRaw="); pw.print(r.setRawAdj);
13385                pw.print(" cur="); pw.print(r.curAdj);
13386                pw.print(" set="); pw.println(r.setAdj);
13387                pw.print(prefix);
13388                pw.print("    ");
13389                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13390                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13391                pw.print(" lastPss="); pw.print(r.lastPss);
13392                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13393                pw.print(prefix);
13394                pw.print("    ");
13395                pw.print("cached="); pw.print(r.cached);
13396                pw.print(" empty="); pw.print(r.empty);
13397                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13398
13399                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13400                    if (r.lastWakeTime != 0) {
13401                        long wtime;
13402                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13403                        synchronized (stats) {
13404                            wtime = stats.getProcessWakeTime(r.info.uid,
13405                                    r.pid, curRealtime);
13406                        }
13407                        long timeUsed = wtime - r.lastWakeTime;
13408                        pw.print(prefix);
13409                        pw.print("    ");
13410                        pw.print("keep awake over ");
13411                        TimeUtils.formatDuration(realtimeSince, pw);
13412                        pw.print(" used ");
13413                        TimeUtils.formatDuration(timeUsed, pw);
13414                        pw.print(" (");
13415                        pw.print((timeUsed*100)/realtimeSince);
13416                        pw.println("%)");
13417                    }
13418                    if (r.lastCpuTime != 0) {
13419                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13420                        pw.print(prefix);
13421                        pw.print("    ");
13422                        pw.print("run cpu over ");
13423                        TimeUtils.formatDuration(uptimeSince, pw);
13424                        pw.print(" used ");
13425                        TimeUtils.formatDuration(timeUsed, pw);
13426                        pw.print(" (");
13427                        pw.print((timeUsed*100)/uptimeSince);
13428                        pw.println("%)");
13429                    }
13430                }
13431            }
13432        }
13433        return true;
13434    }
13435
13436    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
13437        ArrayList<ProcessRecord> procs;
13438        synchronized (this) {
13439            if (args != null && args.length > start
13440                    && args[start].charAt(0) != '-') {
13441                procs = new ArrayList<ProcessRecord>();
13442                int pid = -1;
13443                try {
13444                    pid = Integer.parseInt(args[start]);
13445                } catch (NumberFormatException e) {
13446                }
13447                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13448                    ProcessRecord proc = mLruProcesses.get(i);
13449                    if (proc.pid == pid) {
13450                        procs.add(proc);
13451                    } else if (proc.processName.equals(args[start])) {
13452                        procs.add(proc);
13453                    }
13454                }
13455                if (procs.size() <= 0) {
13456                    return null;
13457                }
13458            } else {
13459                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13460            }
13461        }
13462        return procs;
13463    }
13464
13465    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13466            PrintWriter pw, String[] args) {
13467        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13468        if (procs == null) {
13469            pw.println("No process found for: " + args[0]);
13470            return;
13471        }
13472
13473        long uptime = SystemClock.uptimeMillis();
13474        long realtime = SystemClock.elapsedRealtime();
13475        pw.println("Applications Graphics Acceleration Info:");
13476        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13477
13478        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13479            ProcessRecord r = procs.get(i);
13480            if (r.thread != null) {
13481                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13482                pw.flush();
13483                try {
13484                    TransferPipe tp = new TransferPipe();
13485                    try {
13486                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13487                        tp.go(fd);
13488                    } finally {
13489                        tp.kill();
13490                    }
13491                } catch (IOException e) {
13492                    pw.println("Failure while dumping the app: " + r);
13493                    pw.flush();
13494                } catch (RemoteException e) {
13495                    pw.println("Got a RemoteException while dumping the app " + r);
13496                    pw.flush();
13497                }
13498            }
13499        }
13500    }
13501
13502    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13503        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13504        if (procs == null) {
13505            pw.println("No process found for: " + args[0]);
13506            return;
13507        }
13508
13509        pw.println("Applications Database Info:");
13510
13511        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13512            ProcessRecord r = procs.get(i);
13513            if (r.thread != null) {
13514                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13515                pw.flush();
13516                try {
13517                    TransferPipe tp = new TransferPipe();
13518                    try {
13519                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13520                        tp.go(fd);
13521                    } finally {
13522                        tp.kill();
13523                    }
13524                } catch (IOException e) {
13525                    pw.println("Failure while dumping the app: " + r);
13526                    pw.flush();
13527                } catch (RemoteException e) {
13528                    pw.println("Got a RemoteException while dumping the app " + r);
13529                    pw.flush();
13530                }
13531            }
13532        }
13533    }
13534
13535    final static class MemItem {
13536        final boolean isProc;
13537        final String label;
13538        final String shortLabel;
13539        final long pss;
13540        final int id;
13541        final boolean hasActivities;
13542        ArrayList<MemItem> subitems;
13543
13544        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13545                boolean _hasActivities) {
13546            isProc = true;
13547            label = _label;
13548            shortLabel = _shortLabel;
13549            pss = _pss;
13550            id = _id;
13551            hasActivities = _hasActivities;
13552        }
13553
13554        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13555            isProc = false;
13556            label = _label;
13557            shortLabel = _shortLabel;
13558            pss = _pss;
13559            id = _id;
13560            hasActivities = false;
13561        }
13562    }
13563
13564    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13565            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13566        if (sort && !isCompact) {
13567            Collections.sort(items, new Comparator<MemItem>() {
13568                @Override
13569                public int compare(MemItem lhs, MemItem rhs) {
13570                    if (lhs.pss < rhs.pss) {
13571                        return 1;
13572                    } else if (lhs.pss > rhs.pss) {
13573                        return -1;
13574                    }
13575                    return 0;
13576                }
13577            });
13578        }
13579
13580        for (int i=0; i<items.size(); i++) {
13581            MemItem mi = items.get(i);
13582            if (!isCompact) {
13583                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13584            } else if (mi.isProc) {
13585                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13586                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13587                pw.println(mi.hasActivities ? ",a" : ",e");
13588            } else {
13589                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13590                pw.println(mi.pss);
13591            }
13592            if (mi.subitems != null) {
13593                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13594                        true, isCompact);
13595            }
13596        }
13597    }
13598
13599    // These are in KB.
13600    static final long[] DUMP_MEM_BUCKETS = new long[] {
13601        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13602        120*1024, 160*1024, 200*1024,
13603        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13604        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13605    };
13606
13607    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13608            boolean stackLike) {
13609        int start = label.lastIndexOf('.');
13610        if (start >= 0) start++;
13611        else start = 0;
13612        int end = label.length();
13613        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13614            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13615                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13616                out.append(bucket);
13617                out.append(stackLike ? "MB." : "MB ");
13618                out.append(label, start, end);
13619                return;
13620            }
13621        }
13622        out.append(memKB/1024);
13623        out.append(stackLike ? "MB." : "MB ");
13624        out.append(label, start, end);
13625    }
13626
13627    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13628            ProcessList.NATIVE_ADJ,
13629            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13630            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13631            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13632            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13633            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13634    };
13635    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13636            "Native",
13637            "System", "Persistent", "Foreground",
13638            "Visible", "Perceptible",
13639            "Heavy Weight", "Backup",
13640            "A Services", "Home",
13641            "Previous", "B Services", "Cached"
13642    };
13643    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13644            "native",
13645            "sys", "pers", "fore",
13646            "vis", "percept",
13647            "heavy", "backup",
13648            "servicea", "home",
13649            "prev", "serviceb", "cached"
13650    };
13651
13652    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13653            long realtime, boolean isCheckinRequest, boolean isCompact) {
13654        if (isCheckinRequest || isCompact) {
13655            // short checkin version
13656            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13657        } else {
13658            pw.println("Applications Memory Usage (kB):");
13659            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13660        }
13661    }
13662
13663    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13664            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13665        boolean dumpDetails = false;
13666        boolean dumpFullDetails = false;
13667        boolean dumpDalvik = false;
13668        boolean oomOnly = false;
13669        boolean isCompact = false;
13670        boolean localOnly = false;
13671
13672        int opti = 0;
13673        while (opti < args.length) {
13674            String opt = args[opti];
13675            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13676                break;
13677            }
13678            opti++;
13679            if ("-a".equals(opt)) {
13680                dumpDetails = true;
13681                dumpFullDetails = true;
13682                dumpDalvik = true;
13683            } else if ("-d".equals(opt)) {
13684                dumpDalvik = true;
13685            } else if ("-c".equals(opt)) {
13686                isCompact = true;
13687            } else if ("--oom".equals(opt)) {
13688                oomOnly = true;
13689            } else if ("--local".equals(opt)) {
13690                localOnly = true;
13691            } else if ("-h".equals(opt)) {
13692                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13693                pw.println("  -a: include all available information for each process.");
13694                pw.println("  -d: include dalvik details when dumping process details.");
13695                pw.println("  -c: dump in a compact machine-parseable representation.");
13696                pw.println("  --oom: only show processes organized by oom adj.");
13697                pw.println("  --local: only collect details locally, don't call process.");
13698                pw.println("If [process] is specified it can be the name or ");
13699                pw.println("pid of a specific process to dump.");
13700                return;
13701            } else {
13702                pw.println("Unknown argument: " + opt + "; use -h for help");
13703            }
13704        }
13705
13706        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13707        long uptime = SystemClock.uptimeMillis();
13708        long realtime = SystemClock.elapsedRealtime();
13709        final long[] tmpLong = new long[1];
13710
13711        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13712        if (procs == null) {
13713            // No Java processes.  Maybe they want to print a native process.
13714            if (args != null && args.length > opti
13715                    && args[opti].charAt(0) != '-') {
13716                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13717                        = new ArrayList<ProcessCpuTracker.Stats>();
13718                updateCpuStatsNow();
13719                int findPid = -1;
13720                try {
13721                    findPid = Integer.parseInt(args[opti]);
13722                } catch (NumberFormatException e) {
13723                }
13724                synchronized (mProcessCpuThread) {
13725                    final int N = mProcessCpuTracker.countStats();
13726                    for (int i=0; i<N; i++) {
13727                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13728                        if (st.pid == findPid || (st.baseName != null
13729                                && st.baseName.equals(args[opti]))) {
13730                            nativeProcs.add(st);
13731                        }
13732                    }
13733                }
13734                if (nativeProcs.size() > 0) {
13735                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13736                            isCompact);
13737                    Debug.MemoryInfo mi = null;
13738                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13739                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13740                        final int pid = r.pid;
13741                        if (!isCheckinRequest && dumpDetails) {
13742                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13743                        }
13744                        if (mi == null) {
13745                            mi = new Debug.MemoryInfo();
13746                        }
13747                        if (dumpDetails || (!brief && !oomOnly)) {
13748                            Debug.getMemoryInfo(pid, mi);
13749                        } else {
13750                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13751                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13752                        }
13753                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13754                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13755                        if (isCheckinRequest) {
13756                            pw.println();
13757                        }
13758                    }
13759                    return;
13760                }
13761            }
13762            pw.println("No process found for: " + args[opti]);
13763            return;
13764        }
13765
13766        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13767            dumpDetails = true;
13768        }
13769
13770        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13771
13772        String[] innerArgs = new String[args.length-opti];
13773        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13774
13775        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13776        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13777        long nativePss=0, dalvikPss=0, otherPss=0;
13778        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13779
13780        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13781        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13782                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13783
13784        long totalPss = 0;
13785        long cachedPss = 0;
13786
13787        Debug.MemoryInfo mi = null;
13788        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13789            final ProcessRecord r = procs.get(i);
13790            final IApplicationThread thread;
13791            final int pid;
13792            final int oomAdj;
13793            final boolean hasActivities;
13794            synchronized (this) {
13795                thread = r.thread;
13796                pid = r.pid;
13797                oomAdj = r.getSetAdjWithServices();
13798                hasActivities = r.activities.size() > 0;
13799            }
13800            if (thread != null) {
13801                if (!isCheckinRequest && dumpDetails) {
13802                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13803                }
13804                if (mi == null) {
13805                    mi = new Debug.MemoryInfo();
13806                }
13807                if (dumpDetails || (!brief && !oomOnly)) {
13808                    Debug.getMemoryInfo(pid, mi);
13809                } else {
13810                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13811                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13812                }
13813                if (dumpDetails) {
13814                    if (localOnly) {
13815                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13816                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13817                        if (isCheckinRequest) {
13818                            pw.println();
13819                        }
13820                    } else {
13821                        try {
13822                            pw.flush();
13823                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13824                                    dumpDalvik, innerArgs);
13825                        } catch (RemoteException e) {
13826                            if (!isCheckinRequest) {
13827                                pw.println("Got RemoteException!");
13828                                pw.flush();
13829                            }
13830                        }
13831                    }
13832                }
13833
13834                final long myTotalPss = mi.getTotalPss();
13835                final long myTotalUss = mi.getTotalUss();
13836
13837                synchronized (this) {
13838                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13839                        // Record this for posterity if the process has been stable.
13840                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13841                    }
13842                }
13843
13844                if (!isCheckinRequest && mi != null) {
13845                    totalPss += myTotalPss;
13846                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13847                            (hasActivities ? " / activities)" : ")"),
13848                            r.processName, myTotalPss, pid, hasActivities);
13849                    procMems.add(pssItem);
13850                    procMemsMap.put(pid, pssItem);
13851
13852                    nativePss += mi.nativePss;
13853                    dalvikPss += mi.dalvikPss;
13854                    otherPss += mi.otherPss;
13855                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13856                        long mem = mi.getOtherPss(j);
13857                        miscPss[j] += mem;
13858                        otherPss -= mem;
13859                    }
13860
13861                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13862                        cachedPss += myTotalPss;
13863                    }
13864
13865                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13866                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13867                                || oomIndex == (oomPss.length-1)) {
13868                            oomPss[oomIndex] += myTotalPss;
13869                            if (oomProcs[oomIndex] == null) {
13870                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13871                            }
13872                            oomProcs[oomIndex].add(pssItem);
13873                            break;
13874                        }
13875                    }
13876                }
13877            }
13878        }
13879
13880        long nativeProcTotalPss = 0;
13881
13882        if (!isCheckinRequest && procs.size() > 1) {
13883            // If we are showing aggregations, also look for native processes to
13884            // include so that our aggregations are more accurate.
13885            updateCpuStatsNow();
13886            synchronized (mProcessCpuThread) {
13887                final int N = mProcessCpuTracker.countStats();
13888                for (int i=0; i<N; i++) {
13889                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13890                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13891                        if (mi == null) {
13892                            mi = new Debug.MemoryInfo();
13893                        }
13894                        if (!brief && !oomOnly) {
13895                            Debug.getMemoryInfo(st.pid, mi);
13896                        } else {
13897                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13898                            mi.nativePrivateDirty = (int)tmpLong[0];
13899                        }
13900
13901                        final long myTotalPss = mi.getTotalPss();
13902                        totalPss += myTotalPss;
13903                        nativeProcTotalPss += myTotalPss;
13904
13905                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13906                                st.name, myTotalPss, st.pid, false);
13907                        procMems.add(pssItem);
13908
13909                        nativePss += mi.nativePss;
13910                        dalvikPss += mi.dalvikPss;
13911                        otherPss += mi.otherPss;
13912                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13913                            long mem = mi.getOtherPss(j);
13914                            miscPss[j] += mem;
13915                            otherPss -= mem;
13916                        }
13917                        oomPss[0] += myTotalPss;
13918                        if (oomProcs[0] == null) {
13919                            oomProcs[0] = new ArrayList<MemItem>();
13920                        }
13921                        oomProcs[0].add(pssItem);
13922                    }
13923                }
13924            }
13925
13926            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13927
13928            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13929            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13930            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13931            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13932                String label = Debug.MemoryInfo.getOtherLabel(j);
13933                catMems.add(new MemItem(label, label, miscPss[j], j));
13934            }
13935
13936            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13937            for (int j=0; j<oomPss.length; j++) {
13938                if (oomPss[j] != 0) {
13939                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13940                            : DUMP_MEM_OOM_LABEL[j];
13941                    MemItem item = new MemItem(label, label, oomPss[j],
13942                            DUMP_MEM_OOM_ADJ[j]);
13943                    item.subitems = oomProcs[j];
13944                    oomMems.add(item);
13945                }
13946            }
13947
13948            if (!brief && !oomOnly && !isCompact) {
13949                pw.println();
13950                pw.println("Total PSS by process:");
13951                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13952                pw.println();
13953            }
13954            if (!isCompact) {
13955                pw.println("Total PSS by OOM adjustment:");
13956            }
13957            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13958            if (!brief && !oomOnly) {
13959                PrintWriter out = categoryPw != null ? categoryPw : pw;
13960                if (!isCompact) {
13961                    out.println();
13962                    out.println("Total PSS by category:");
13963                }
13964                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13965            }
13966            if (!isCompact) {
13967                pw.println();
13968            }
13969            MemInfoReader memInfo = new MemInfoReader();
13970            memInfo.readMemInfo();
13971            if (nativeProcTotalPss > 0) {
13972                synchronized (this) {
13973                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13974                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13975                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13976                            nativeProcTotalPss);
13977                }
13978            }
13979            if (!brief) {
13980                if (!isCompact) {
13981                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13982                    pw.print(" kB (status ");
13983                    switch (mLastMemoryLevel) {
13984                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13985                            pw.println("normal)");
13986                            break;
13987                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13988                            pw.println("moderate)");
13989                            break;
13990                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13991                            pw.println("low)");
13992                            break;
13993                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13994                            pw.println("critical)");
13995                            break;
13996                        default:
13997                            pw.print(mLastMemoryLevel);
13998                            pw.println(")");
13999                            break;
14000                    }
14001                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14002                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14003                            pw.print(cachedPss); pw.print(" cached pss + ");
14004                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
14005                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14006                } else {
14007                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14008                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14009                            + memInfo.getFreeSizeKb()); pw.print(",");
14010                    pw.println(totalPss - cachedPss);
14011                }
14012            }
14013            if (!isCompact) {
14014                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14015                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
14016                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
14017                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14018                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
14019                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
14020                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
14021                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14022                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14023                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
14024                        - memInfo.getSlabSizeKb()); pw.println(" kB");
14025            }
14026            if (!brief) {
14027                if (memInfo.getZramTotalSizeKb() != 0) {
14028                    if (!isCompact) {
14029                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14030                                pw.print(" kB physical used for ");
14031                                pw.print(memInfo.getSwapTotalSizeKb()
14032                                        - memInfo.getSwapFreeSizeKb());
14033                                pw.print(" kB in swap (");
14034                                pw.print(memInfo.getSwapTotalSizeKb());
14035                                pw.println(" kB total swap)");
14036                    } else {
14037                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14038                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14039                                pw.println(memInfo.getSwapFreeSizeKb());
14040                    }
14041                }
14042                final int[] SINGLE_LONG_FORMAT = new int[] {
14043                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14044                };
14045                long[] longOut = new long[1];
14046                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14047                        SINGLE_LONG_FORMAT, null, longOut, null);
14048                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14049                longOut[0] = 0;
14050                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14051                        SINGLE_LONG_FORMAT, null, longOut, null);
14052                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14053                longOut[0] = 0;
14054                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14055                        SINGLE_LONG_FORMAT, null, longOut, null);
14056                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14057                longOut[0] = 0;
14058                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14059                        SINGLE_LONG_FORMAT, null, longOut, null);
14060                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14061                if (!isCompact) {
14062                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
14063                        pw.print("      KSM: "); pw.print(sharing);
14064                                pw.print(" kB saved from shared ");
14065                                pw.print(shared); pw.println(" kB");
14066                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
14067                                pw.print(voltile); pw.println(" kB volatile");
14068                    }
14069                    pw.print("   Tuning: ");
14070                    pw.print(ActivityManager.staticGetMemoryClass());
14071                    pw.print(" (large ");
14072                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14073                    pw.print("), oom ");
14074                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14075                    pw.print(" kB");
14076                    pw.print(", restore limit ");
14077                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14078                    pw.print(" kB");
14079                    if (ActivityManager.isLowRamDeviceStatic()) {
14080                        pw.print(" (low-ram)");
14081                    }
14082                    if (ActivityManager.isHighEndGfx()) {
14083                        pw.print(" (high-end-gfx)");
14084                    }
14085                    pw.println();
14086                } else {
14087                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
14088                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
14089                    pw.println(voltile);
14090                    pw.print("tuning,");
14091                    pw.print(ActivityManager.staticGetMemoryClass());
14092                    pw.print(',');
14093                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14094                    pw.print(',');
14095                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14096                    if (ActivityManager.isLowRamDeviceStatic()) {
14097                        pw.print(",low-ram");
14098                    }
14099                    if (ActivityManager.isHighEndGfx()) {
14100                        pw.print(",high-end-gfx");
14101                    }
14102                    pw.println();
14103                }
14104            }
14105        }
14106    }
14107
14108    /**
14109     * Searches array of arguments for the specified string
14110     * @param args array of argument strings
14111     * @param value value to search for
14112     * @return true if the value is contained in the array
14113     */
14114    private static boolean scanArgs(String[] args, String value) {
14115        if (args != null) {
14116            for (String arg : args) {
14117                if (value.equals(arg)) {
14118                    return true;
14119                }
14120            }
14121        }
14122        return false;
14123    }
14124
14125    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14126            ContentProviderRecord cpr, boolean always) {
14127        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14128
14129        if (!inLaunching || always) {
14130            synchronized (cpr) {
14131                cpr.launchingApp = null;
14132                cpr.notifyAll();
14133            }
14134            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14135            String names[] = cpr.info.authority.split(";");
14136            for (int j = 0; j < names.length; j++) {
14137                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14138            }
14139        }
14140
14141        for (int i=0; i<cpr.connections.size(); i++) {
14142            ContentProviderConnection conn = cpr.connections.get(i);
14143            if (conn.waiting) {
14144                // If this connection is waiting for the provider, then we don't
14145                // need to mess with its process unless we are always removing
14146                // or for some reason the provider is not currently launching.
14147                if (inLaunching && !always) {
14148                    continue;
14149                }
14150            }
14151            ProcessRecord capp = conn.client;
14152            conn.dead = true;
14153            if (conn.stableCount > 0) {
14154                if (!capp.persistent && capp.thread != null
14155                        && capp.pid != 0
14156                        && capp.pid != MY_PID) {
14157                    capp.kill("depends on provider "
14158                            + cpr.name.flattenToShortString()
14159                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14160                }
14161            } else if (capp.thread != null && conn.provider.provider != null) {
14162                try {
14163                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14164                } catch (RemoteException e) {
14165                }
14166                // In the protocol here, we don't expect the client to correctly
14167                // clean up this connection, we'll just remove it.
14168                cpr.connections.remove(i);
14169                conn.client.conProviders.remove(conn);
14170            }
14171        }
14172
14173        if (inLaunching && always) {
14174            mLaunchingProviders.remove(cpr);
14175        }
14176        return inLaunching;
14177    }
14178
14179    /**
14180     * Main code for cleaning up a process when it has gone away.  This is
14181     * called both as a result of the process dying, or directly when stopping
14182     * a process when running in single process mode.
14183     */
14184    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
14185            boolean restarting, boolean allowRestart, int index) {
14186        if (index >= 0) {
14187            removeLruProcessLocked(app);
14188            ProcessList.remove(app.pid);
14189        }
14190
14191        mProcessesToGc.remove(app);
14192        mPendingPssProcesses.remove(app);
14193
14194        // Dismiss any open dialogs.
14195        if (app.crashDialog != null && !app.forceCrashReport) {
14196            app.crashDialog.dismiss();
14197            app.crashDialog = null;
14198        }
14199        if (app.anrDialog != null) {
14200            app.anrDialog.dismiss();
14201            app.anrDialog = null;
14202        }
14203        if (app.waitDialog != null) {
14204            app.waitDialog.dismiss();
14205            app.waitDialog = null;
14206        }
14207
14208        app.crashing = false;
14209        app.notResponding = false;
14210
14211        app.resetPackageList(mProcessStats);
14212        app.unlinkDeathRecipient();
14213        app.makeInactive(mProcessStats);
14214        app.waitingToKill = null;
14215        app.forcingToForeground = null;
14216        updateProcessForegroundLocked(app, false, false);
14217        app.foregroundActivities = false;
14218        app.hasShownUi = false;
14219        app.treatLikeActivity = false;
14220        app.hasAboveClient = false;
14221        app.hasClientActivities = false;
14222
14223        mServices.killServicesLocked(app, allowRestart);
14224
14225        boolean restart = false;
14226
14227        // Remove published content providers.
14228        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14229            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14230            final boolean always = app.bad || !allowRestart;
14231            if (removeDyingProviderLocked(app, cpr, always) || always) {
14232                // We left the provider in the launching list, need to
14233                // restart it.
14234                restart = true;
14235            }
14236
14237            cpr.provider = null;
14238            cpr.proc = null;
14239        }
14240        app.pubProviders.clear();
14241
14242        // Take care of any launching providers waiting for this process.
14243        if (checkAppInLaunchingProvidersLocked(app, false)) {
14244            restart = true;
14245        }
14246
14247        // Unregister from connected content providers.
14248        if (!app.conProviders.isEmpty()) {
14249            for (int i=0; i<app.conProviders.size(); i++) {
14250                ContentProviderConnection conn = app.conProviders.get(i);
14251                conn.provider.connections.remove(conn);
14252            }
14253            app.conProviders.clear();
14254        }
14255
14256        // At this point there may be remaining entries in mLaunchingProviders
14257        // where we were the only one waiting, so they are no longer of use.
14258        // Look for these and clean up if found.
14259        // XXX Commented out for now.  Trying to figure out a way to reproduce
14260        // the actual situation to identify what is actually going on.
14261        if (false) {
14262            for (int i=0; i<mLaunchingProviders.size(); i++) {
14263                ContentProviderRecord cpr = (ContentProviderRecord)
14264                        mLaunchingProviders.get(i);
14265                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14266                    synchronized (cpr) {
14267                        cpr.launchingApp = null;
14268                        cpr.notifyAll();
14269                    }
14270                }
14271            }
14272        }
14273
14274        skipCurrentReceiverLocked(app);
14275
14276        // Unregister any receivers.
14277        for (int i=app.receivers.size()-1; i>=0; i--) {
14278            removeReceiverLocked(app.receivers.valueAt(i));
14279        }
14280        app.receivers.clear();
14281
14282        // If the app is undergoing backup, tell the backup manager about it
14283        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14284            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14285                    + mBackupTarget.appInfo + " died during backup");
14286            try {
14287                IBackupManager bm = IBackupManager.Stub.asInterface(
14288                        ServiceManager.getService(Context.BACKUP_SERVICE));
14289                bm.agentDisconnected(app.info.packageName);
14290            } catch (RemoteException e) {
14291                // can't happen; backup manager is local
14292            }
14293        }
14294
14295        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14296            ProcessChangeItem item = mPendingProcessChanges.get(i);
14297            if (item.pid == app.pid) {
14298                mPendingProcessChanges.remove(i);
14299                mAvailProcessChanges.add(item);
14300            }
14301        }
14302        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14303
14304        // If the caller is restarting this app, then leave it in its
14305        // current lists and let the caller take care of it.
14306        if (restarting) {
14307            return;
14308        }
14309
14310        if (!app.persistent || app.isolated) {
14311            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14312                    "Removing non-persistent process during cleanup: " + app);
14313            mProcessNames.remove(app.processName, app.uid);
14314            mIsolatedProcesses.remove(app.uid);
14315            if (mHeavyWeightProcess == app) {
14316                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14317                        mHeavyWeightProcess.userId, 0));
14318                mHeavyWeightProcess = null;
14319            }
14320        } else if (!app.removed) {
14321            // This app is persistent, so we need to keep its record around.
14322            // If it is not already on the pending app list, add it there
14323            // and start a new process for it.
14324            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14325                mPersistentStartingProcesses.add(app);
14326                restart = true;
14327            }
14328        }
14329        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14330                "Clean-up removing on hold: " + app);
14331        mProcessesOnHold.remove(app);
14332
14333        if (app == mHomeProcess) {
14334            mHomeProcess = null;
14335        }
14336        if (app == mPreviousProcess) {
14337            mPreviousProcess = null;
14338        }
14339
14340        if (restart && !app.isolated) {
14341            // We have components that still need to be running in the
14342            // process, so re-launch it.
14343            mProcessNames.put(app.processName, app.uid, app);
14344            startProcessLocked(app, "restart", app.processName);
14345        } else if (app.pid > 0 && app.pid != MY_PID) {
14346            // Goodbye!
14347            boolean removed;
14348            synchronized (mPidsSelfLocked) {
14349                mPidsSelfLocked.remove(app.pid);
14350                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14351            }
14352            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14353            if (app.isolated) {
14354                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14355            }
14356            app.setPid(0);
14357        }
14358    }
14359
14360    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14361        // Look through the content providers we are waiting to have launched,
14362        // and if any run in this process then either schedule a restart of
14363        // the process or kill the client waiting for it if this process has
14364        // gone bad.
14365        int NL = mLaunchingProviders.size();
14366        boolean restart = false;
14367        for (int i=0; i<NL; i++) {
14368            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14369            if (cpr.launchingApp == app) {
14370                if (!alwaysBad && !app.bad) {
14371                    restart = true;
14372                } else {
14373                    removeDyingProviderLocked(app, cpr, true);
14374                    // cpr should have been removed from mLaunchingProviders
14375                    NL = mLaunchingProviders.size();
14376                    i--;
14377                }
14378            }
14379        }
14380        return restart;
14381    }
14382
14383    // =========================================================
14384    // SERVICES
14385    // =========================================================
14386
14387    @Override
14388    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14389            int flags) {
14390        enforceNotIsolatedCaller("getServices");
14391        synchronized (this) {
14392            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14393        }
14394    }
14395
14396    @Override
14397    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14398        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14399        synchronized (this) {
14400            return mServices.getRunningServiceControlPanelLocked(name);
14401        }
14402    }
14403
14404    @Override
14405    public ComponentName startService(IApplicationThread caller, Intent service,
14406            String resolvedType, int userId) {
14407        enforceNotIsolatedCaller("startService");
14408        // Refuse possible leaked file descriptors
14409        if (service != null && service.hasFileDescriptors() == true) {
14410            throw new IllegalArgumentException("File descriptors passed in Intent");
14411        }
14412
14413        if (DEBUG_SERVICE)
14414            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14415        synchronized(this) {
14416            final int callingPid = Binder.getCallingPid();
14417            final int callingUid = Binder.getCallingUid();
14418            final long origId = Binder.clearCallingIdentity();
14419            ComponentName res = mServices.startServiceLocked(caller, service,
14420                    resolvedType, callingPid, callingUid, userId);
14421            Binder.restoreCallingIdentity(origId);
14422            return res;
14423        }
14424    }
14425
14426    ComponentName startServiceInPackage(int uid,
14427            Intent service, String resolvedType, int userId) {
14428        synchronized(this) {
14429            if (DEBUG_SERVICE)
14430                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14431            final long origId = Binder.clearCallingIdentity();
14432            ComponentName res = mServices.startServiceLocked(null, service,
14433                    resolvedType, -1, uid, userId);
14434            Binder.restoreCallingIdentity(origId);
14435            return res;
14436        }
14437    }
14438
14439    @Override
14440    public int stopService(IApplicationThread caller, Intent service,
14441            String resolvedType, int userId) {
14442        enforceNotIsolatedCaller("stopService");
14443        // Refuse possible leaked file descriptors
14444        if (service != null && service.hasFileDescriptors() == true) {
14445            throw new IllegalArgumentException("File descriptors passed in Intent");
14446        }
14447
14448        synchronized(this) {
14449            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14450        }
14451    }
14452
14453    @Override
14454    public IBinder peekService(Intent service, String resolvedType) {
14455        enforceNotIsolatedCaller("peekService");
14456        // Refuse possible leaked file descriptors
14457        if (service != null && service.hasFileDescriptors() == true) {
14458            throw new IllegalArgumentException("File descriptors passed in Intent");
14459        }
14460        synchronized(this) {
14461            return mServices.peekServiceLocked(service, resolvedType);
14462        }
14463    }
14464
14465    @Override
14466    public boolean stopServiceToken(ComponentName className, IBinder token,
14467            int startId) {
14468        synchronized(this) {
14469            return mServices.stopServiceTokenLocked(className, token, startId);
14470        }
14471    }
14472
14473    @Override
14474    public void setServiceForeground(ComponentName className, IBinder token,
14475            int id, Notification notification, boolean removeNotification) {
14476        synchronized(this) {
14477            mServices.setServiceForegroundLocked(className, token, id, notification,
14478                    removeNotification);
14479        }
14480    }
14481
14482    @Override
14483    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14484            boolean requireFull, String name, String callerPackage) {
14485        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14486                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14487    }
14488
14489    int unsafeConvertIncomingUser(int userId) {
14490        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14491                ? mCurrentUserId : userId;
14492    }
14493
14494    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14495            int allowMode, String name, String callerPackage) {
14496        final int callingUserId = UserHandle.getUserId(callingUid);
14497        if (callingUserId == userId) {
14498            return userId;
14499        }
14500
14501        // Note that we may be accessing mCurrentUserId outside of a lock...
14502        // shouldn't be a big deal, if this is being called outside
14503        // of a locked context there is intrinsically a race with
14504        // the value the caller will receive and someone else changing it.
14505        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14506        // we will switch to the calling user if access to the current user fails.
14507        int targetUserId = unsafeConvertIncomingUser(userId);
14508
14509        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14510            final boolean allow;
14511            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14512                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14513                // If the caller has this permission, they always pass go.  And collect $200.
14514                allow = true;
14515            } else if (allowMode == ALLOW_FULL_ONLY) {
14516                // We require full access, sucks to be you.
14517                allow = false;
14518            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14519                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14520                // If the caller does not have either permission, they are always doomed.
14521                allow = false;
14522            } else if (allowMode == ALLOW_NON_FULL) {
14523                // We are blanket allowing non-full access, you lucky caller!
14524                allow = true;
14525            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14526                // We may or may not allow this depending on whether the two users are
14527                // in the same profile.
14528                synchronized (mUserProfileGroupIdsSelfLocked) {
14529                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14530                            UserInfo.NO_PROFILE_GROUP_ID);
14531                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14532                            UserInfo.NO_PROFILE_GROUP_ID);
14533                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14534                            && callingProfile == targetProfile;
14535                }
14536            } else {
14537                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14538            }
14539            if (!allow) {
14540                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14541                    // In this case, they would like to just execute as their
14542                    // owner user instead of failing.
14543                    targetUserId = callingUserId;
14544                } else {
14545                    StringBuilder builder = new StringBuilder(128);
14546                    builder.append("Permission Denial: ");
14547                    builder.append(name);
14548                    if (callerPackage != null) {
14549                        builder.append(" from ");
14550                        builder.append(callerPackage);
14551                    }
14552                    builder.append(" asks to run as user ");
14553                    builder.append(userId);
14554                    builder.append(" but is calling from user ");
14555                    builder.append(UserHandle.getUserId(callingUid));
14556                    builder.append("; this requires ");
14557                    builder.append(INTERACT_ACROSS_USERS_FULL);
14558                    if (allowMode != ALLOW_FULL_ONLY) {
14559                        builder.append(" or ");
14560                        builder.append(INTERACT_ACROSS_USERS);
14561                    }
14562                    String msg = builder.toString();
14563                    Slog.w(TAG, msg);
14564                    throw new SecurityException(msg);
14565                }
14566            }
14567        }
14568        if (!allowAll && targetUserId < 0) {
14569            throw new IllegalArgumentException(
14570                    "Call does not support special user #" + targetUserId);
14571        }
14572        return targetUserId;
14573    }
14574
14575    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14576            String className, int flags) {
14577        boolean result = false;
14578        // For apps that don't have pre-defined UIDs, check for permission
14579        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14580            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14581                if (ActivityManager.checkUidPermission(
14582                        INTERACT_ACROSS_USERS,
14583                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14584                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14585                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14586                            + " requests FLAG_SINGLE_USER, but app does not hold "
14587                            + INTERACT_ACROSS_USERS;
14588                    Slog.w(TAG, msg);
14589                    throw new SecurityException(msg);
14590                }
14591                // Permission passed
14592                result = true;
14593            }
14594        } else if ("system".equals(componentProcessName)) {
14595            result = true;
14596        } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14597                && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14598            // Phone app is allowed to export singleuser providers.
14599            result = true;
14600        } else {
14601            // App with pre-defined UID, check if it's a persistent app
14602            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14603        }
14604        if (DEBUG_MU) {
14605            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14606                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14607        }
14608        return result;
14609    }
14610
14611    /**
14612     * Checks to see if the caller is in the same app as the singleton
14613     * component, or the component is in a special app. It allows special apps
14614     * to export singleton components but prevents exporting singleton
14615     * components for regular apps.
14616     */
14617    boolean isValidSingletonCall(int callingUid, int componentUid) {
14618        int componentAppId = UserHandle.getAppId(componentUid);
14619        return UserHandle.isSameApp(callingUid, componentUid)
14620                || componentAppId == Process.SYSTEM_UID
14621                || componentAppId == Process.PHONE_UID
14622                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14623                        == PackageManager.PERMISSION_GRANTED;
14624    }
14625
14626    public int bindService(IApplicationThread caller, IBinder token,
14627            Intent service, String resolvedType,
14628            IServiceConnection connection, int flags, int userId) {
14629        enforceNotIsolatedCaller("bindService");
14630        // Refuse possible leaked file descriptors
14631        if (service != null && service.hasFileDescriptors() == true) {
14632            throw new IllegalArgumentException("File descriptors passed in Intent");
14633        }
14634
14635        synchronized(this) {
14636            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14637                    connection, flags, userId);
14638        }
14639    }
14640
14641    public boolean unbindService(IServiceConnection connection) {
14642        synchronized (this) {
14643            return mServices.unbindServiceLocked(connection);
14644        }
14645    }
14646
14647    public void publishService(IBinder token, Intent intent, IBinder service) {
14648        // Refuse possible leaked file descriptors
14649        if (intent != null && intent.hasFileDescriptors() == true) {
14650            throw new IllegalArgumentException("File descriptors passed in Intent");
14651        }
14652
14653        synchronized(this) {
14654            if (!(token instanceof ServiceRecord)) {
14655                throw new IllegalArgumentException("Invalid service token");
14656            }
14657            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14658        }
14659    }
14660
14661    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14662        // Refuse possible leaked file descriptors
14663        if (intent != null && intent.hasFileDescriptors() == true) {
14664            throw new IllegalArgumentException("File descriptors passed in Intent");
14665        }
14666
14667        synchronized(this) {
14668            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14669        }
14670    }
14671
14672    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14673        synchronized(this) {
14674            if (!(token instanceof ServiceRecord)) {
14675                throw new IllegalArgumentException("Invalid service token");
14676            }
14677            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14678        }
14679    }
14680
14681    // =========================================================
14682    // BACKUP AND RESTORE
14683    // =========================================================
14684
14685    // Cause the target app to be launched if necessary and its backup agent
14686    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14687    // activity manager to announce its creation.
14688    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14689        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14690        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14691
14692        synchronized(this) {
14693            // !!! TODO: currently no check here that we're already bound
14694            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14695            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14696            synchronized (stats) {
14697                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14698            }
14699
14700            // Backup agent is now in use, its package can't be stopped.
14701            try {
14702                AppGlobals.getPackageManager().setPackageStoppedState(
14703                        app.packageName, false, UserHandle.getUserId(app.uid));
14704            } catch (RemoteException e) {
14705            } catch (IllegalArgumentException e) {
14706                Slog.w(TAG, "Failed trying to unstop package "
14707                        + app.packageName + ": " + e);
14708            }
14709
14710            BackupRecord r = new BackupRecord(ss, app, backupMode);
14711            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14712                    ? new ComponentName(app.packageName, app.backupAgentName)
14713                    : new ComponentName("android", "FullBackupAgent");
14714            // startProcessLocked() returns existing proc's record if it's already running
14715            ProcessRecord proc = startProcessLocked(app.processName, app,
14716                    false, 0, "backup", hostingName, false, false, false);
14717            if (proc == null) {
14718                Slog.e(TAG, "Unable to start backup agent process " + r);
14719                return false;
14720            }
14721
14722            r.app = proc;
14723            mBackupTarget = r;
14724            mBackupAppName = app.packageName;
14725
14726            // Try not to kill the process during backup
14727            updateOomAdjLocked(proc);
14728
14729            // If the process is already attached, schedule the creation of the backup agent now.
14730            // If it is not yet live, this will be done when it attaches to the framework.
14731            if (proc.thread != null) {
14732                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14733                try {
14734                    proc.thread.scheduleCreateBackupAgent(app,
14735                            compatibilityInfoForPackageLocked(app), backupMode);
14736                } catch (RemoteException e) {
14737                    // Will time out on the backup manager side
14738                }
14739            } else {
14740                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14741            }
14742            // Invariants: at this point, the target app process exists and the application
14743            // is either already running or in the process of coming up.  mBackupTarget and
14744            // mBackupAppName describe the app, so that when it binds back to the AM we
14745            // know that it's scheduled for a backup-agent operation.
14746        }
14747
14748        return true;
14749    }
14750
14751    @Override
14752    public void clearPendingBackup() {
14753        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14754        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14755
14756        synchronized (this) {
14757            mBackupTarget = null;
14758            mBackupAppName = null;
14759        }
14760    }
14761
14762    // A backup agent has just come up
14763    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14764        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14765                + " = " + agent);
14766
14767        synchronized(this) {
14768            if (!agentPackageName.equals(mBackupAppName)) {
14769                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14770                return;
14771            }
14772        }
14773
14774        long oldIdent = Binder.clearCallingIdentity();
14775        try {
14776            IBackupManager bm = IBackupManager.Stub.asInterface(
14777                    ServiceManager.getService(Context.BACKUP_SERVICE));
14778            bm.agentConnected(agentPackageName, agent);
14779        } catch (RemoteException e) {
14780            // can't happen; the backup manager service is local
14781        } catch (Exception e) {
14782            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14783            e.printStackTrace();
14784        } finally {
14785            Binder.restoreCallingIdentity(oldIdent);
14786        }
14787    }
14788
14789    // done with this agent
14790    public void unbindBackupAgent(ApplicationInfo appInfo) {
14791        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14792        if (appInfo == null) {
14793            Slog.w(TAG, "unbind backup agent for null app");
14794            return;
14795        }
14796
14797        synchronized(this) {
14798            try {
14799                if (mBackupAppName == null) {
14800                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14801                    return;
14802                }
14803
14804                if (!mBackupAppName.equals(appInfo.packageName)) {
14805                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14806                    return;
14807                }
14808
14809                // Not backing this app up any more; reset its OOM adjustment
14810                final ProcessRecord proc = mBackupTarget.app;
14811                updateOomAdjLocked(proc);
14812
14813                // If the app crashed during backup, 'thread' will be null here
14814                if (proc.thread != null) {
14815                    try {
14816                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14817                                compatibilityInfoForPackageLocked(appInfo));
14818                    } catch (Exception e) {
14819                        Slog.e(TAG, "Exception when unbinding backup agent:");
14820                        e.printStackTrace();
14821                    }
14822                }
14823            } finally {
14824                mBackupTarget = null;
14825                mBackupAppName = null;
14826            }
14827        }
14828    }
14829    // =========================================================
14830    // BROADCASTS
14831    // =========================================================
14832
14833    private final List getStickiesLocked(String action, IntentFilter filter,
14834            List cur, int userId) {
14835        final ContentResolver resolver = mContext.getContentResolver();
14836        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14837        if (stickies == null) {
14838            return cur;
14839        }
14840        final ArrayList<Intent> list = stickies.get(action);
14841        if (list == null) {
14842            return cur;
14843        }
14844        int N = list.size();
14845        for (int i=0; i<N; i++) {
14846            Intent intent = list.get(i);
14847            if (filter.match(resolver, intent, true, TAG) >= 0) {
14848                if (cur == null) {
14849                    cur = new ArrayList<Intent>();
14850                }
14851                cur.add(intent);
14852            }
14853        }
14854        return cur;
14855    }
14856
14857    boolean isPendingBroadcastProcessLocked(int pid) {
14858        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14859                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14860    }
14861
14862    void skipPendingBroadcastLocked(int pid) {
14863            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14864            for (BroadcastQueue queue : mBroadcastQueues) {
14865                queue.skipPendingBroadcastLocked(pid);
14866            }
14867    }
14868
14869    // The app just attached; send any pending broadcasts that it should receive
14870    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14871        boolean didSomething = false;
14872        for (BroadcastQueue queue : mBroadcastQueues) {
14873            didSomething |= queue.sendPendingBroadcastsLocked(app);
14874        }
14875        return didSomething;
14876    }
14877
14878    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14879            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14880        enforceNotIsolatedCaller("registerReceiver");
14881        int callingUid;
14882        int callingPid;
14883        synchronized(this) {
14884            ProcessRecord callerApp = null;
14885            if (caller != null) {
14886                callerApp = getRecordForAppLocked(caller);
14887                if (callerApp == null) {
14888                    throw new SecurityException(
14889                            "Unable to find app for caller " + caller
14890                            + " (pid=" + Binder.getCallingPid()
14891                            + ") when registering receiver " + receiver);
14892                }
14893                if (callerApp.info.uid != Process.SYSTEM_UID &&
14894                        !callerApp.pkgList.containsKey(callerPackage) &&
14895                        !"android".equals(callerPackage)) {
14896                    throw new SecurityException("Given caller package " + callerPackage
14897                            + " is not running in process " + callerApp);
14898                }
14899                callingUid = callerApp.info.uid;
14900                callingPid = callerApp.pid;
14901            } else {
14902                callerPackage = null;
14903                callingUid = Binder.getCallingUid();
14904                callingPid = Binder.getCallingPid();
14905            }
14906
14907            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14908                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14909
14910            List allSticky = null;
14911
14912            // Look for any matching sticky broadcasts...
14913            Iterator actions = filter.actionsIterator();
14914            if (actions != null) {
14915                while (actions.hasNext()) {
14916                    String action = (String)actions.next();
14917                    allSticky = getStickiesLocked(action, filter, allSticky,
14918                            UserHandle.USER_ALL);
14919                    allSticky = getStickiesLocked(action, filter, allSticky,
14920                            UserHandle.getUserId(callingUid));
14921                }
14922            } else {
14923                allSticky = getStickiesLocked(null, filter, allSticky,
14924                        UserHandle.USER_ALL);
14925                allSticky = getStickiesLocked(null, filter, allSticky,
14926                        UserHandle.getUserId(callingUid));
14927            }
14928
14929            // The first sticky in the list is returned directly back to
14930            // the client.
14931            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14932
14933            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14934                    + ": " + sticky);
14935
14936            if (receiver == null) {
14937                return sticky;
14938            }
14939
14940            ReceiverList rl
14941                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14942            if (rl == null) {
14943                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14944                        userId, receiver);
14945                if (rl.app != null) {
14946                    rl.app.receivers.add(rl);
14947                } else {
14948                    try {
14949                        receiver.asBinder().linkToDeath(rl, 0);
14950                    } catch (RemoteException e) {
14951                        return sticky;
14952                    }
14953                    rl.linkedToDeath = true;
14954                }
14955                mRegisteredReceivers.put(receiver.asBinder(), rl);
14956            } else if (rl.uid != callingUid) {
14957                throw new IllegalArgumentException(
14958                        "Receiver requested to register for uid " + callingUid
14959                        + " was previously registered for uid " + rl.uid);
14960            } else if (rl.pid != callingPid) {
14961                throw new IllegalArgumentException(
14962                        "Receiver requested to register for pid " + callingPid
14963                        + " was previously registered for pid " + rl.pid);
14964            } else if (rl.userId != userId) {
14965                throw new IllegalArgumentException(
14966                        "Receiver requested to register for user " + userId
14967                        + " was previously registered for user " + rl.userId);
14968            }
14969            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14970                    permission, callingUid, userId);
14971            rl.add(bf);
14972            if (!bf.debugCheck()) {
14973                Slog.w(TAG, "==> For Dynamic broadast");
14974            }
14975            mReceiverResolver.addFilter(bf);
14976
14977            // Enqueue broadcasts for all existing stickies that match
14978            // this filter.
14979            if (allSticky != null) {
14980                ArrayList receivers = new ArrayList();
14981                receivers.add(bf);
14982
14983                int N = allSticky.size();
14984                for (int i=0; i<N; i++) {
14985                    Intent intent = (Intent)allSticky.get(i);
14986                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14987                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14988                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14989                            null, null, false, true, true, -1);
14990                    queue.enqueueParallelBroadcastLocked(r);
14991                    queue.scheduleBroadcastsLocked();
14992                }
14993            }
14994
14995            return sticky;
14996        }
14997    }
14998
14999    public void unregisterReceiver(IIntentReceiver receiver) {
15000        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15001
15002        final long origId = Binder.clearCallingIdentity();
15003        try {
15004            boolean doTrim = false;
15005
15006            synchronized(this) {
15007                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15008                if (rl != null) {
15009                    if (rl.curBroadcast != null) {
15010                        BroadcastRecord r = rl.curBroadcast;
15011                        final boolean doNext = finishReceiverLocked(
15012                                receiver.asBinder(), r.resultCode, r.resultData,
15013                                r.resultExtras, r.resultAbort);
15014                        if (doNext) {
15015                            doTrim = true;
15016                            r.queue.processNextBroadcast(false);
15017                        }
15018                    }
15019
15020                    if (rl.app != null) {
15021                        rl.app.receivers.remove(rl);
15022                    }
15023                    removeReceiverLocked(rl);
15024                    if (rl.linkedToDeath) {
15025                        rl.linkedToDeath = false;
15026                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15027                    }
15028                }
15029            }
15030
15031            // If we actually concluded any broadcasts, we might now be able
15032            // to trim the recipients' apps from our working set
15033            if (doTrim) {
15034                trimApplications();
15035                return;
15036            }
15037
15038        } finally {
15039            Binder.restoreCallingIdentity(origId);
15040        }
15041    }
15042
15043    void removeReceiverLocked(ReceiverList rl) {
15044        mRegisteredReceivers.remove(rl.receiver.asBinder());
15045        int N = rl.size();
15046        for (int i=0; i<N; i++) {
15047            mReceiverResolver.removeFilter(rl.get(i));
15048        }
15049    }
15050
15051    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15052        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15053            ProcessRecord r = mLruProcesses.get(i);
15054            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15055                try {
15056                    r.thread.dispatchPackageBroadcast(cmd, packages);
15057                } catch (RemoteException ex) {
15058                }
15059            }
15060        }
15061    }
15062
15063    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15064            int[] users) {
15065        List<ResolveInfo> receivers = null;
15066        try {
15067            HashSet<ComponentName> singleUserReceivers = null;
15068            boolean scannedFirstReceivers = false;
15069            for (int user : users) {
15070                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15071                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15072                if (user != 0 && newReceivers != null) {
15073                    // If this is not the primary user, we need to check for
15074                    // any receivers that should be filtered out.
15075                    for (int i=0; i<newReceivers.size(); i++) {
15076                        ResolveInfo ri = newReceivers.get(i);
15077                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15078                            newReceivers.remove(i);
15079                            i--;
15080                        }
15081                    }
15082                }
15083                if (newReceivers != null && newReceivers.size() == 0) {
15084                    newReceivers = null;
15085                }
15086                if (receivers == null) {
15087                    receivers = newReceivers;
15088                } else if (newReceivers != null) {
15089                    // We need to concatenate the additional receivers
15090                    // found with what we have do far.  This would be easy,
15091                    // but we also need to de-dup any receivers that are
15092                    // singleUser.
15093                    if (!scannedFirstReceivers) {
15094                        // Collect any single user receivers we had already retrieved.
15095                        scannedFirstReceivers = true;
15096                        for (int i=0; i<receivers.size(); i++) {
15097                            ResolveInfo ri = receivers.get(i);
15098                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15099                                ComponentName cn = new ComponentName(
15100                                        ri.activityInfo.packageName, ri.activityInfo.name);
15101                                if (singleUserReceivers == null) {
15102                                    singleUserReceivers = new HashSet<ComponentName>();
15103                                }
15104                                singleUserReceivers.add(cn);
15105                            }
15106                        }
15107                    }
15108                    // Add the new results to the existing results, tracking
15109                    // and de-dupping single user receivers.
15110                    for (int i=0; i<newReceivers.size(); i++) {
15111                        ResolveInfo ri = newReceivers.get(i);
15112                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15113                            ComponentName cn = new ComponentName(
15114                                    ri.activityInfo.packageName, ri.activityInfo.name);
15115                            if (singleUserReceivers == null) {
15116                                singleUserReceivers = new HashSet<ComponentName>();
15117                            }
15118                            if (!singleUserReceivers.contains(cn)) {
15119                                singleUserReceivers.add(cn);
15120                                receivers.add(ri);
15121                            }
15122                        } else {
15123                            receivers.add(ri);
15124                        }
15125                    }
15126                }
15127            }
15128        } catch (RemoteException ex) {
15129            // pm is in same process, this will never happen.
15130        }
15131        return receivers;
15132    }
15133
15134    private final int broadcastIntentLocked(ProcessRecord callerApp,
15135            String callerPackage, Intent intent, String resolvedType,
15136            IIntentReceiver resultTo, int resultCode, String resultData,
15137            Bundle map, String requiredPermission, int appOp,
15138            boolean ordered, boolean sticky, int callingPid, int callingUid,
15139            int userId) {
15140        intent = new Intent(intent);
15141
15142        // By default broadcasts do not go to stopped apps.
15143        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15144
15145        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15146            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15147            + " ordered=" + ordered + " userid=" + userId);
15148        if ((resultTo != null) && !ordered) {
15149            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15150        }
15151
15152        userId = handleIncomingUser(callingPid, callingUid, userId,
15153                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15154
15155        // Make sure that the user who is receiving this broadcast is started.
15156        // If not, we will just skip it.
15157
15158
15159        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15160            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15161                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15162                Slog.w(TAG, "Skipping broadcast of " + intent
15163                        + ": user " + userId + " is stopped");
15164                return ActivityManager.BROADCAST_SUCCESS;
15165            }
15166        }
15167
15168        /*
15169         * Prevent non-system code (defined here to be non-persistent
15170         * processes) from sending protected broadcasts.
15171         */
15172        int callingAppId = UserHandle.getAppId(callingUid);
15173        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15174            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15175            || callingAppId == Process.NFC_UID || callingUid == 0) {
15176            // Always okay.
15177        } else if (callerApp == null || !callerApp.persistent) {
15178            try {
15179                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15180                        intent.getAction())) {
15181                    String msg = "Permission Denial: not allowed to send broadcast "
15182                            + intent.getAction() + " from pid="
15183                            + callingPid + ", uid=" + callingUid;
15184                    Slog.w(TAG, msg);
15185                    throw new SecurityException(msg);
15186                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15187                    // Special case for compatibility: we don't want apps to send this,
15188                    // but historically it has not been protected and apps may be using it
15189                    // to poke their own app widget.  So, instead of making it protected,
15190                    // just limit it to the caller.
15191                    if (callerApp == null) {
15192                        String msg = "Permission Denial: not allowed to send broadcast "
15193                                + intent.getAction() + " from unknown caller.";
15194                        Slog.w(TAG, msg);
15195                        throw new SecurityException(msg);
15196                    } else if (intent.getComponent() != null) {
15197                        // They are good enough to send to an explicit component...  verify
15198                        // it is being sent to the calling app.
15199                        if (!intent.getComponent().getPackageName().equals(
15200                                callerApp.info.packageName)) {
15201                            String msg = "Permission Denial: not allowed to send broadcast "
15202                                    + intent.getAction() + " to "
15203                                    + intent.getComponent().getPackageName() + " from "
15204                                    + callerApp.info.packageName;
15205                            Slog.w(TAG, msg);
15206                            throw new SecurityException(msg);
15207                        }
15208                    } else {
15209                        // Limit broadcast to their own package.
15210                        intent.setPackage(callerApp.info.packageName);
15211                    }
15212                }
15213            } catch (RemoteException e) {
15214                Slog.w(TAG, "Remote exception", e);
15215                return ActivityManager.BROADCAST_SUCCESS;
15216            }
15217        }
15218
15219        // Handle special intents: if this broadcast is from the package
15220        // manager about a package being removed, we need to remove all of
15221        // its activities from the history stack.
15222        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15223                intent.getAction());
15224        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15225                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15226                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15227                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15228                || uidRemoved) {
15229            if (checkComponentPermission(
15230                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15231                    callingPid, callingUid, -1, true)
15232                    == PackageManager.PERMISSION_GRANTED) {
15233                if (uidRemoved) {
15234                    final Bundle intentExtras = intent.getExtras();
15235                    final int uid = intentExtras != null
15236                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15237                    if (uid >= 0) {
15238                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15239                        synchronized (bs) {
15240                            bs.removeUidStatsLocked(uid);
15241                        }
15242                        mAppOpsService.uidRemoved(uid);
15243                    }
15244                } else {
15245                    // If resources are unavailable just force stop all
15246                    // those packages and flush the attribute cache as well.
15247                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15248                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15249                        if (list != null && (list.length > 0)) {
15250                            for (String pkg : list) {
15251                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15252                                        "storage unmount");
15253                            }
15254                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15255                            sendPackageBroadcastLocked(
15256                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15257                        }
15258                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15259                            intent.getAction())) {
15260                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15261                    } else {
15262                        Uri data = intent.getData();
15263                        String ssp;
15264                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15265                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15266                                    intent.getAction());
15267                            boolean fullUninstall = removed &&
15268                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15269                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15270                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15271                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15272                                        false, fullUninstall, userId,
15273                                        removed ? "pkg removed" : "pkg changed");
15274                            }
15275                            if (removed) {
15276                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15277                                        new String[] {ssp}, userId);
15278                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15279                                    mAppOpsService.packageRemoved(
15280                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15281
15282                                    // Remove all permissions granted from/to this package
15283                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15284                                }
15285                            }
15286                        }
15287                    }
15288                }
15289            } else {
15290                String msg = "Permission Denial: " + intent.getAction()
15291                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15292                        + ", uid=" + callingUid + ")"
15293                        + " requires "
15294                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15295                Slog.w(TAG, msg);
15296                throw new SecurityException(msg);
15297            }
15298
15299        // Special case for adding a package: by default turn on compatibility
15300        // mode.
15301        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15302            Uri data = intent.getData();
15303            String ssp;
15304            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15305                mCompatModePackages.handlePackageAddedLocked(ssp,
15306                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15307            }
15308        }
15309
15310        /*
15311         * If this is the time zone changed action, queue up a message that will reset the timezone
15312         * of all currently running processes. This message will get queued up before the broadcast
15313         * happens.
15314         */
15315        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15316            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15317        }
15318
15319        /*
15320         * If the user set the time, let all running processes know.
15321         */
15322        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15323            final int is24Hour = intent.getBooleanExtra(
15324                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15325            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15326            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15327            synchronized (stats) {
15328                stats.noteCurrentTimeChangedLocked();
15329            }
15330        }
15331
15332        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15333            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15334        }
15335
15336        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15337            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15338            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15339        }
15340
15341        // Add to the sticky list if requested.
15342        if (sticky) {
15343            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15344                    callingPid, callingUid)
15345                    != PackageManager.PERMISSION_GRANTED) {
15346                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15347                        + callingPid + ", uid=" + callingUid
15348                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15349                Slog.w(TAG, msg);
15350                throw new SecurityException(msg);
15351            }
15352            if (requiredPermission != null) {
15353                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15354                        + " and enforce permission " + requiredPermission);
15355                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15356            }
15357            if (intent.getComponent() != null) {
15358                throw new SecurityException(
15359                        "Sticky broadcasts can't target a specific component");
15360            }
15361            // We use userId directly here, since the "all" target is maintained
15362            // as a separate set of sticky broadcasts.
15363            if (userId != UserHandle.USER_ALL) {
15364                // But first, if this is not a broadcast to all users, then
15365                // make sure it doesn't conflict with an existing broadcast to
15366                // all users.
15367                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15368                        UserHandle.USER_ALL);
15369                if (stickies != null) {
15370                    ArrayList<Intent> list = stickies.get(intent.getAction());
15371                    if (list != null) {
15372                        int N = list.size();
15373                        int i;
15374                        for (i=0; i<N; i++) {
15375                            if (intent.filterEquals(list.get(i))) {
15376                                throw new IllegalArgumentException(
15377                                        "Sticky broadcast " + intent + " for user "
15378                                        + userId + " conflicts with existing global broadcast");
15379                            }
15380                        }
15381                    }
15382                }
15383            }
15384            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15385            if (stickies == null) {
15386                stickies = new ArrayMap<String, ArrayList<Intent>>();
15387                mStickyBroadcasts.put(userId, stickies);
15388            }
15389            ArrayList<Intent> list = stickies.get(intent.getAction());
15390            if (list == null) {
15391                list = new ArrayList<Intent>();
15392                stickies.put(intent.getAction(), list);
15393            }
15394            int N = list.size();
15395            int i;
15396            for (i=0; i<N; i++) {
15397                if (intent.filterEquals(list.get(i))) {
15398                    // This sticky already exists, replace it.
15399                    list.set(i, new Intent(intent));
15400                    break;
15401                }
15402            }
15403            if (i >= N) {
15404                list.add(new Intent(intent));
15405            }
15406        }
15407
15408        int[] users;
15409        if (userId == UserHandle.USER_ALL) {
15410            // Caller wants broadcast to go to all started users.
15411            users = mStartedUserArray;
15412        } else {
15413            // Caller wants broadcast to go to one specific user.
15414            users = new int[] {userId};
15415        }
15416
15417        // Figure out who all will receive this broadcast.
15418        List receivers = null;
15419        List<BroadcastFilter> registeredReceivers = null;
15420        // Need to resolve the intent to interested receivers...
15421        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15422                 == 0) {
15423            receivers = collectReceiverComponents(intent, resolvedType, users);
15424        }
15425        if (intent.getComponent() == null) {
15426            registeredReceivers = mReceiverResolver.queryIntent(intent,
15427                    resolvedType, false, userId);
15428        }
15429
15430        final boolean replacePending =
15431                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15432
15433        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15434                + " replacePending=" + replacePending);
15435
15436        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15437        if (!ordered && NR > 0) {
15438            // If we are not serializing this broadcast, then send the
15439            // registered receivers separately so they don't wait for the
15440            // components to be launched.
15441            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15442            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15443                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15444                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15445                    ordered, sticky, false, userId);
15446            if (DEBUG_BROADCAST) Slog.v(
15447                    TAG, "Enqueueing parallel broadcast " + r);
15448            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15449            if (!replaced) {
15450                queue.enqueueParallelBroadcastLocked(r);
15451                queue.scheduleBroadcastsLocked();
15452            }
15453            registeredReceivers = null;
15454            NR = 0;
15455        }
15456
15457        // Merge into one list.
15458        int ir = 0;
15459        if (receivers != null) {
15460            // A special case for PACKAGE_ADDED: do not allow the package
15461            // being added to see this broadcast.  This prevents them from
15462            // using this as a back door to get run as soon as they are
15463            // installed.  Maybe in the future we want to have a special install
15464            // broadcast or such for apps, but we'd like to deliberately make
15465            // this decision.
15466            String skipPackages[] = null;
15467            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15468                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15469                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15470                Uri data = intent.getData();
15471                if (data != null) {
15472                    String pkgName = data.getSchemeSpecificPart();
15473                    if (pkgName != null) {
15474                        skipPackages = new String[] { pkgName };
15475                    }
15476                }
15477            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15478                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15479            }
15480            if (skipPackages != null && (skipPackages.length > 0)) {
15481                for (String skipPackage : skipPackages) {
15482                    if (skipPackage != null) {
15483                        int NT = receivers.size();
15484                        for (int it=0; it<NT; it++) {
15485                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15486                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15487                                receivers.remove(it);
15488                                it--;
15489                                NT--;
15490                            }
15491                        }
15492                    }
15493                }
15494            }
15495
15496            int NT = receivers != null ? receivers.size() : 0;
15497            int it = 0;
15498            ResolveInfo curt = null;
15499            BroadcastFilter curr = null;
15500            while (it < NT && ir < NR) {
15501                if (curt == null) {
15502                    curt = (ResolveInfo)receivers.get(it);
15503                }
15504                if (curr == null) {
15505                    curr = registeredReceivers.get(ir);
15506                }
15507                if (curr.getPriority() >= curt.priority) {
15508                    // Insert this broadcast record into the final list.
15509                    receivers.add(it, curr);
15510                    ir++;
15511                    curr = null;
15512                    it++;
15513                    NT++;
15514                } else {
15515                    // Skip to the next ResolveInfo in the final list.
15516                    it++;
15517                    curt = null;
15518                }
15519            }
15520        }
15521        while (ir < NR) {
15522            if (receivers == null) {
15523                receivers = new ArrayList();
15524            }
15525            receivers.add(registeredReceivers.get(ir));
15526            ir++;
15527        }
15528
15529        if ((receivers != null && receivers.size() > 0)
15530                || resultTo != null) {
15531            BroadcastQueue queue = broadcastQueueForIntent(intent);
15532            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15533                    callerPackage, callingPid, callingUid, resolvedType,
15534                    requiredPermission, appOp, receivers, resultTo, resultCode,
15535                    resultData, map, ordered, sticky, false, userId);
15536            if (DEBUG_BROADCAST) Slog.v(
15537                    TAG, "Enqueueing ordered broadcast " + r
15538                    + ": prev had " + queue.mOrderedBroadcasts.size());
15539            if (DEBUG_BROADCAST) {
15540                int seq = r.intent.getIntExtra("seq", -1);
15541                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15542            }
15543            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15544            if (!replaced) {
15545                queue.enqueueOrderedBroadcastLocked(r);
15546                queue.scheduleBroadcastsLocked();
15547            }
15548        }
15549
15550        return ActivityManager.BROADCAST_SUCCESS;
15551    }
15552
15553    final Intent verifyBroadcastLocked(Intent intent) {
15554        // Refuse possible leaked file descriptors
15555        if (intent != null && intent.hasFileDescriptors() == true) {
15556            throw new IllegalArgumentException("File descriptors passed in Intent");
15557        }
15558
15559        int flags = intent.getFlags();
15560
15561        if (!mProcessesReady) {
15562            // if the caller really truly claims to know what they're doing, go
15563            // ahead and allow the broadcast without launching any receivers
15564            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15565                intent = new Intent(intent);
15566                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15567            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15568                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15569                        + " before boot completion");
15570                throw new IllegalStateException("Cannot broadcast before boot completed");
15571            }
15572        }
15573
15574        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15575            throw new IllegalArgumentException(
15576                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15577        }
15578
15579        return intent;
15580    }
15581
15582    public final int broadcastIntent(IApplicationThread caller,
15583            Intent intent, String resolvedType, IIntentReceiver resultTo,
15584            int resultCode, String resultData, Bundle map,
15585            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15586        enforceNotIsolatedCaller("broadcastIntent");
15587        synchronized(this) {
15588            intent = verifyBroadcastLocked(intent);
15589
15590            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15591            final int callingPid = Binder.getCallingPid();
15592            final int callingUid = Binder.getCallingUid();
15593            final long origId = Binder.clearCallingIdentity();
15594            int res = broadcastIntentLocked(callerApp,
15595                    callerApp != null ? callerApp.info.packageName : null,
15596                    intent, resolvedType, resultTo,
15597                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15598                    callingPid, callingUid, userId);
15599            Binder.restoreCallingIdentity(origId);
15600            return res;
15601        }
15602    }
15603
15604    int broadcastIntentInPackage(String packageName, int uid,
15605            Intent intent, String resolvedType, IIntentReceiver resultTo,
15606            int resultCode, String resultData, Bundle map,
15607            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15608        synchronized(this) {
15609            intent = verifyBroadcastLocked(intent);
15610
15611            final long origId = Binder.clearCallingIdentity();
15612            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15613                    resultTo, resultCode, resultData, map, requiredPermission,
15614                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15615            Binder.restoreCallingIdentity(origId);
15616            return res;
15617        }
15618    }
15619
15620    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15621        // Refuse possible leaked file descriptors
15622        if (intent != null && intent.hasFileDescriptors() == true) {
15623            throw new IllegalArgumentException("File descriptors passed in Intent");
15624        }
15625
15626        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15627                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15628
15629        synchronized(this) {
15630            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15631                    != PackageManager.PERMISSION_GRANTED) {
15632                String msg = "Permission Denial: unbroadcastIntent() from pid="
15633                        + Binder.getCallingPid()
15634                        + ", uid=" + Binder.getCallingUid()
15635                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15636                Slog.w(TAG, msg);
15637                throw new SecurityException(msg);
15638            }
15639            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15640            if (stickies != null) {
15641                ArrayList<Intent> list = stickies.get(intent.getAction());
15642                if (list != null) {
15643                    int N = list.size();
15644                    int i;
15645                    for (i=0; i<N; i++) {
15646                        if (intent.filterEquals(list.get(i))) {
15647                            list.remove(i);
15648                            break;
15649                        }
15650                    }
15651                    if (list.size() <= 0) {
15652                        stickies.remove(intent.getAction());
15653                    }
15654                }
15655                if (stickies.size() <= 0) {
15656                    mStickyBroadcasts.remove(userId);
15657                }
15658            }
15659        }
15660    }
15661
15662    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15663            String resultData, Bundle resultExtras, boolean resultAbort) {
15664        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15665        if (r == null) {
15666            Slog.w(TAG, "finishReceiver called but not found on queue");
15667            return false;
15668        }
15669
15670        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15671    }
15672
15673    void backgroundServicesFinishedLocked(int userId) {
15674        for (BroadcastQueue queue : mBroadcastQueues) {
15675            queue.backgroundServicesFinishedLocked(userId);
15676        }
15677    }
15678
15679    public void finishReceiver(IBinder who, int resultCode, String resultData,
15680            Bundle resultExtras, boolean resultAbort) {
15681        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15682
15683        // Refuse possible leaked file descriptors
15684        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15685            throw new IllegalArgumentException("File descriptors passed in Bundle");
15686        }
15687
15688        final long origId = Binder.clearCallingIdentity();
15689        try {
15690            boolean doNext = false;
15691            BroadcastRecord r;
15692
15693            synchronized(this) {
15694                r = broadcastRecordForReceiverLocked(who);
15695                if (r != null) {
15696                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15697                        resultData, resultExtras, resultAbort, true);
15698                }
15699            }
15700
15701            if (doNext) {
15702                r.queue.processNextBroadcast(false);
15703            }
15704            trimApplications();
15705        } finally {
15706            Binder.restoreCallingIdentity(origId);
15707        }
15708    }
15709
15710    // =========================================================
15711    // INSTRUMENTATION
15712    // =========================================================
15713
15714    public boolean startInstrumentation(ComponentName className,
15715            String profileFile, int flags, Bundle arguments,
15716            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15717            int userId, String abiOverride) {
15718        enforceNotIsolatedCaller("startInstrumentation");
15719        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15720                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15721        // Refuse possible leaked file descriptors
15722        if (arguments != null && arguments.hasFileDescriptors()) {
15723            throw new IllegalArgumentException("File descriptors passed in Bundle");
15724        }
15725
15726        synchronized(this) {
15727            InstrumentationInfo ii = null;
15728            ApplicationInfo ai = null;
15729            try {
15730                ii = mContext.getPackageManager().getInstrumentationInfo(
15731                    className, STOCK_PM_FLAGS);
15732                ai = AppGlobals.getPackageManager().getApplicationInfo(
15733                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15734            } catch (PackageManager.NameNotFoundException e) {
15735            } catch (RemoteException e) {
15736            }
15737            if (ii == null) {
15738                reportStartInstrumentationFailure(watcher, className,
15739                        "Unable to find instrumentation info for: " + className);
15740                return false;
15741            }
15742            if (ai == null) {
15743                reportStartInstrumentationFailure(watcher, className,
15744                        "Unable to find instrumentation target package: " + ii.targetPackage);
15745                return false;
15746            }
15747
15748            int match = mContext.getPackageManager().checkSignatures(
15749                    ii.targetPackage, ii.packageName);
15750            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15751                String msg = "Permission Denial: starting instrumentation "
15752                        + className + " from pid="
15753                        + Binder.getCallingPid()
15754                        + ", uid=" + Binder.getCallingPid()
15755                        + " not allowed because package " + ii.packageName
15756                        + " does not have a signature matching the target "
15757                        + ii.targetPackage;
15758                reportStartInstrumentationFailure(watcher, className, msg);
15759                throw new SecurityException(msg);
15760            }
15761
15762            final long origId = Binder.clearCallingIdentity();
15763            // Instrumentation can kill and relaunch even persistent processes
15764            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15765                    "start instr");
15766            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15767            app.instrumentationClass = className;
15768            app.instrumentationInfo = ai;
15769            app.instrumentationProfileFile = profileFile;
15770            app.instrumentationArguments = arguments;
15771            app.instrumentationWatcher = watcher;
15772            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15773            app.instrumentationResultClass = className;
15774            Binder.restoreCallingIdentity(origId);
15775        }
15776
15777        return true;
15778    }
15779
15780    /**
15781     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15782     * error to the logs, but if somebody is watching, send the report there too.  This enables
15783     * the "am" command to report errors with more information.
15784     *
15785     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15786     * @param cn The component name of the instrumentation.
15787     * @param report The error report.
15788     */
15789    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15790            ComponentName cn, String report) {
15791        Slog.w(TAG, report);
15792        try {
15793            if (watcher != null) {
15794                Bundle results = new Bundle();
15795                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15796                results.putString("Error", report);
15797                watcher.instrumentationStatus(cn, -1, results);
15798            }
15799        } catch (RemoteException e) {
15800            Slog.w(TAG, e);
15801        }
15802    }
15803
15804    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15805        if (app.instrumentationWatcher != null) {
15806            try {
15807                // NOTE:  IInstrumentationWatcher *must* be oneway here
15808                app.instrumentationWatcher.instrumentationFinished(
15809                    app.instrumentationClass,
15810                    resultCode,
15811                    results);
15812            } catch (RemoteException e) {
15813            }
15814        }
15815        if (app.instrumentationUiAutomationConnection != null) {
15816            try {
15817                app.instrumentationUiAutomationConnection.shutdown();
15818            } catch (RemoteException re) {
15819                /* ignore */
15820            }
15821            // Only a UiAutomation can set this flag and now that
15822            // it is finished we make sure it is reset to its default.
15823            mUserIsMonkey = false;
15824        }
15825        app.instrumentationWatcher = null;
15826        app.instrumentationUiAutomationConnection = null;
15827        app.instrumentationClass = null;
15828        app.instrumentationInfo = null;
15829        app.instrumentationProfileFile = null;
15830        app.instrumentationArguments = null;
15831
15832        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15833                "finished inst");
15834    }
15835
15836    public void finishInstrumentation(IApplicationThread target,
15837            int resultCode, Bundle results) {
15838        int userId = UserHandle.getCallingUserId();
15839        // Refuse possible leaked file descriptors
15840        if (results != null && results.hasFileDescriptors()) {
15841            throw new IllegalArgumentException("File descriptors passed in Intent");
15842        }
15843
15844        synchronized(this) {
15845            ProcessRecord app = getRecordForAppLocked(target);
15846            if (app == null) {
15847                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15848                return;
15849            }
15850            final long origId = Binder.clearCallingIdentity();
15851            finishInstrumentationLocked(app, resultCode, results);
15852            Binder.restoreCallingIdentity(origId);
15853        }
15854    }
15855
15856    // =========================================================
15857    // CONFIGURATION
15858    // =========================================================
15859
15860    public ConfigurationInfo getDeviceConfigurationInfo() {
15861        ConfigurationInfo config = new ConfigurationInfo();
15862        synchronized (this) {
15863            config.reqTouchScreen = mConfiguration.touchscreen;
15864            config.reqKeyboardType = mConfiguration.keyboard;
15865            config.reqNavigation = mConfiguration.navigation;
15866            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15867                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15868                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15869            }
15870            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15871                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15872                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15873            }
15874            config.reqGlEsVersion = GL_ES_VERSION;
15875        }
15876        return config;
15877    }
15878
15879    ActivityStack getFocusedStack() {
15880        return mStackSupervisor.getFocusedStack();
15881    }
15882
15883    public Configuration getConfiguration() {
15884        Configuration ci;
15885        synchronized(this) {
15886            ci = new Configuration(mConfiguration);
15887        }
15888        return ci;
15889    }
15890
15891    public void updatePersistentConfiguration(Configuration values) {
15892        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15893                "updateConfiguration()");
15894        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15895                "updateConfiguration()");
15896        if (values == null) {
15897            throw new NullPointerException("Configuration must not be null");
15898        }
15899
15900        synchronized(this) {
15901            final long origId = Binder.clearCallingIdentity();
15902            updateConfigurationLocked(values, null, true, false);
15903            Binder.restoreCallingIdentity(origId);
15904        }
15905    }
15906
15907    public void updateConfiguration(Configuration values) {
15908        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15909                "updateConfiguration()");
15910
15911        synchronized(this) {
15912            if (values == null && mWindowManager != null) {
15913                // sentinel: fetch the current configuration from the window manager
15914                values = mWindowManager.computeNewConfiguration();
15915            }
15916
15917            if (mWindowManager != null) {
15918                mProcessList.applyDisplaySize(mWindowManager);
15919            }
15920
15921            final long origId = Binder.clearCallingIdentity();
15922            if (values != null) {
15923                Settings.System.clearConfiguration(values);
15924            }
15925            updateConfigurationLocked(values, null, false, false);
15926            Binder.restoreCallingIdentity(origId);
15927        }
15928    }
15929
15930    /**
15931     * Do either or both things: (1) change the current configuration, and (2)
15932     * make sure the given activity is running with the (now) current
15933     * configuration.  Returns true if the activity has been left running, or
15934     * false if <var>starting</var> is being destroyed to match the new
15935     * configuration.
15936     * @param persistent TODO
15937     */
15938    boolean updateConfigurationLocked(Configuration values,
15939            ActivityRecord starting, boolean persistent, boolean initLocale) {
15940        int changes = 0;
15941
15942        if (values != null) {
15943            Configuration newConfig = new Configuration(mConfiguration);
15944            changes = newConfig.updateFrom(values);
15945            if (changes != 0) {
15946                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15947                    Slog.i(TAG, "Updating configuration to: " + values);
15948                }
15949
15950                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15951
15952                if (values.locale != null && !initLocale) {
15953                    saveLocaleLocked(values.locale,
15954                                     !values.locale.equals(mConfiguration.locale),
15955                                     values.userSetLocale);
15956                }
15957
15958                mConfigurationSeq++;
15959                if (mConfigurationSeq <= 0) {
15960                    mConfigurationSeq = 1;
15961                }
15962                newConfig.seq = mConfigurationSeq;
15963                mConfiguration = newConfig;
15964                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15965                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
15966                //mUsageStatsService.noteStartConfig(newConfig);
15967
15968                final Configuration configCopy = new Configuration(mConfiguration);
15969
15970                // TODO: If our config changes, should we auto dismiss any currently
15971                // showing dialogs?
15972                mShowDialogs = shouldShowDialogs(newConfig);
15973
15974                AttributeCache ac = AttributeCache.instance();
15975                if (ac != null) {
15976                    ac.updateConfiguration(configCopy);
15977                }
15978
15979                // Make sure all resources in our process are updated
15980                // right now, so that anyone who is going to retrieve
15981                // resource values after we return will be sure to get
15982                // the new ones.  This is especially important during
15983                // boot, where the first config change needs to guarantee
15984                // all resources have that config before following boot
15985                // code is executed.
15986                mSystemThread.applyConfigurationToResources(configCopy);
15987
15988                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15989                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15990                    msg.obj = new Configuration(configCopy);
15991                    mHandler.sendMessage(msg);
15992                }
15993
15994                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15995                    ProcessRecord app = mLruProcesses.get(i);
15996                    try {
15997                        if (app.thread != null) {
15998                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15999                                    + app.processName + " new config " + mConfiguration);
16000                            app.thread.scheduleConfigurationChanged(configCopy);
16001                        }
16002                    } catch (Exception e) {
16003                    }
16004                }
16005                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16006                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16007                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16008                        | Intent.FLAG_RECEIVER_FOREGROUND);
16009                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16010                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16011                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16012                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16013                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16014                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16015                    broadcastIntentLocked(null, null, intent,
16016                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16017                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16018                }
16019            }
16020        }
16021
16022        boolean kept = true;
16023        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16024        // mainStack is null during startup.
16025        if (mainStack != null) {
16026            if (changes != 0 && starting == null) {
16027                // If the configuration changed, and the caller is not already
16028                // in the process of starting an activity, then find the top
16029                // activity to check if its configuration needs to change.
16030                starting = mainStack.topRunningActivityLocked(null);
16031            }
16032
16033            if (starting != null) {
16034                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16035                // And we need to make sure at this point that all other activities
16036                // are made visible with the correct configuration.
16037                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16038            }
16039        }
16040
16041        if (values != null && mWindowManager != null) {
16042            mWindowManager.setNewConfiguration(mConfiguration);
16043        }
16044
16045        return kept;
16046    }
16047
16048    /**
16049     * Decide based on the configuration whether we should shouw the ANR,
16050     * crash, etc dialogs.  The idea is that if there is no affordnace to
16051     * press the on-screen buttons, we shouldn't show the dialog.
16052     *
16053     * A thought: SystemUI might also want to get told about this, the Power
16054     * dialog / global actions also might want different behaviors.
16055     */
16056    private static final boolean shouldShowDialogs(Configuration config) {
16057        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16058                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16059    }
16060
16061    /**
16062     * Save the locale.  You must be inside a synchronized (this) block.
16063     */
16064    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16065        if(isDiff) {
16066            SystemProperties.set("user.language", l.getLanguage());
16067            SystemProperties.set("user.region", l.getCountry());
16068        }
16069
16070        if(isPersist) {
16071            SystemProperties.set("persist.sys.language", l.getLanguage());
16072            SystemProperties.set("persist.sys.country", l.getCountry());
16073            SystemProperties.set("persist.sys.localevar", l.getVariant());
16074        }
16075    }
16076
16077    @Override
16078    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16079        synchronized (this) {
16080            ActivityRecord srec = ActivityRecord.forToken(token);
16081            if (srec.task != null && srec.task.stack != null) {
16082                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16083            }
16084        }
16085        return false;
16086    }
16087
16088    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16089            Intent resultData) {
16090
16091        synchronized (this) {
16092            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16093            if (stack != null) {
16094                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16095            }
16096            return false;
16097        }
16098    }
16099
16100    public int getLaunchedFromUid(IBinder activityToken) {
16101        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16102        if (srec == null) {
16103            return -1;
16104        }
16105        return srec.launchedFromUid;
16106    }
16107
16108    public String getLaunchedFromPackage(IBinder activityToken) {
16109        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16110        if (srec == null) {
16111            return null;
16112        }
16113        return srec.launchedFromPackage;
16114    }
16115
16116    // =========================================================
16117    // LIFETIME MANAGEMENT
16118    // =========================================================
16119
16120    // Returns which broadcast queue the app is the current [or imminent] receiver
16121    // on, or 'null' if the app is not an active broadcast recipient.
16122    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16123        BroadcastRecord r = app.curReceiver;
16124        if (r != null) {
16125            return r.queue;
16126        }
16127
16128        // It's not the current receiver, but it might be starting up to become one
16129        synchronized (this) {
16130            for (BroadcastQueue queue : mBroadcastQueues) {
16131                r = queue.mPendingBroadcast;
16132                if (r != null && r.curApp == app) {
16133                    // found it; report which queue it's in
16134                    return queue;
16135                }
16136            }
16137        }
16138
16139        return null;
16140    }
16141
16142    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16143            boolean doingAll, long now) {
16144        if (mAdjSeq == app.adjSeq) {
16145            // This adjustment has already been computed.
16146            return app.curRawAdj;
16147        }
16148
16149        if (app.thread == null) {
16150            app.adjSeq = mAdjSeq;
16151            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16152            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16153            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16154        }
16155
16156        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16157        app.adjSource = null;
16158        app.adjTarget = null;
16159        app.empty = false;
16160        app.cached = false;
16161
16162        final int activitiesSize = app.activities.size();
16163
16164        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16165            // The max adjustment doesn't allow this app to be anything
16166            // below foreground, so it is not worth doing work for it.
16167            app.adjType = "fixed";
16168            app.adjSeq = mAdjSeq;
16169            app.curRawAdj = app.maxAdj;
16170            app.foregroundActivities = false;
16171            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16172            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16173            // System processes can do UI, and when they do we want to have
16174            // them trim their memory after the user leaves the UI.  To
16175            // facilitate this, here we need to determine whether or not it
16176            // is currently showing UI.
16177            app.systemNoUi = true;
16178            if (app == TOP_APP) {
16179                app.systemNoUi = false;
16180            } else if (activitiesSize > 0) {
16181                for (int j = 0; j < activitiesSize; j++) {
16182                    final ActivityRecord r = app.activities.get(j);
16183                    if (r.visible) {
16184                        app.systemNoUi = false;
16185                    }
16186                }
16187            }
16188            if (!app.systemNoUi) {
16189                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16190            }
16191            return (app.curAdj=app.maxAdj);
16192        }
16193
16194        app.systemNoUi = false;
16195
16196        // Determine the importance of the process, starting with most
16197        // important to least, and assign an appropriate OOM adjustment.
16198        int adj;
16199        int schedGroup;
16200        int procState;
16201        boolean foregroundActivities = false;
16202        BroadcastQueue queue;
16203        if (app == TOP_APP) {
16204            // The last app on the list is the foreground app.
16205            adj = ProcessList.FOREGROUND_APP_ADJ;
16206            schedGroup = Process.THREAD_GROUP_DEFAULT;
16207            app.adjType = "top-activity";
16208            foregroundActivities = true;
16209            procState = ActivityManager.PROCESS_STATE_TOP;
16210        } else if (app.instrumentationClass != null) {
16211            // Don't want to kill running instrumentation.
16212            adj = ProcessList.FOREGROUND_APP_ADJ;
16213            schedGroup = Process.THREAD_GROUP_DEFAULT;
16214            app.adjType = "instrumentation";
16215            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16216        } else if ((queue = isReceivingBroadcast(app)) != null) {
16217            // An app that is currently receiving a broadcast also
16218            // counts as being in the foreground for OOM killer purposes.
16219            // It's placed in a sched group based on the nature of the
16220            // broadcast as reflected by which queue it's active in.
16221            adj = ProcessList.FOREGROUND_APP_ADJ;
16222            schedGroup = (queue == mFgBroadcastQueue)
16223                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16224            app.adjType = "broadcast";
16225            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16226        } else if (app.executingServices.size() > 0) {
16227            // An app that is currently executing a service callback also
16228            // counts as being in the foreground.
16229            adj = ProcessList.FOREGROUND_APP_ADJ;
16230            schedGroup = app.execServicesFg ?
16231                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16232            app.adjType = "exec-service";
16233            procState = ActivityManager.PROCESS_STATE_SERVICE;
16234            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16235        } else {
16236            // As far as we know the process is empty.  We may change our mind later.
16237            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16238            // At this point we don't actually know the adjustment.  Use the cached adj
16239            // value that the caller wants us to.
16240            adj = cachedAdj;
16241            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16242            app.cached = true;
16243            app.empty = true;
16244            app.adjType = "cch-empty";
16245        }
16246
16247        // Examine all activities if not already foreground.
16248        if (!foregroundActivities && activitiesSize > 0) {
16249            for (int j = 0; j < activitiesSize; j++) {
16250                final ActivityRecord r = app.activities.get(j);
16251                if (r.app != app) {
16252                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16253                            + app + "?!?");
16254                    continue;
16255                }
16256                if (r.visible) {
16257                    // App has a visible activity; only upgrade adjustment.
16258                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16259                        adj = ProcessList.VISIBLE_APP_ADJ;
16260                        app.adjType = "visible";
16261                    }
16262                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16263                        procState = ActivityManager.PROCESS_STATE_TOP;
16264                    }
16265                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16266                    app.cached = false;
16267                    app.empty = false;
16268                    foregroundActivities = true;
16269                    break;
16270                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16271                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16272                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16273                        app.adjType = "pausing";
16274                    }
16275                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16276                        procState = ActivityManager.PROCESS_STATE_TOP;
16277                    }
16278                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16279                    app.cached = false;
16280                    app.empty = false;
16281                    foregroundActivities = true;
16282                } else if (r.state == ActivityState.STOPPING) {
16283                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16284                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16285                        app.adjType = "stopping";
16286                    }
16287                    // For the process state, we will at this point consider the
16288                    // process to be cached.  It will be cached either as an activity
16289                    // or empty depending on whether the activity is finishing.  We do
16290                    // this so that we can treat the process as cached for purposes of
16291                    // memory trimming (determing current memory level, trim command to
16292                    // send to process) since there can be an arbitrary number of stopping
16293                    // processes and they should soon all go into the cached state.
16294                    if (!r.finishing) {
16295                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16296                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16297                        }
16298                    }
16299                    app.cached = false;
16300                    app.empty = false;
16301                    foregroundActivities = true;
16302                } else {
16303                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16304                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16305                        app.adjType = "cch-act";
16306                    }
16307                }
16308            }
16309        }
16310
16311        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16312            if (app.foregroundServices) {
16313                // The user is aware of this app, so make it visible.
16314                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16315                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16316                app.cached = false;
16317                app.adjType = "fg-service";
16318                schedGroup = Process.THREAD_GROUP_DEFAULT;
16319            } else if (app.forcingToForeground != null) {
16320                // The user is aware of this app, so make it visible.
16321                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16322                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16323                app.cached = false;
16324                app.adjType = "force-fg";
16325                app.adjSource = app.forcingToForeground;
16326                schedGroup = Process.THREAD_GROUP_DEFAULT;
16327            }
16328        }
16329
16330        if (app == mHeavyWeightProcess) {
16331            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16332                // We don't want to kill the current heavy-weight process.
16333                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16334                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16335                app.cached = false;
16336                app.adjType = "heavy";
16337            }
16338            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16339                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16340            }
16341        }
16342
16343        if (app == mHomeProcess) {
16344            if (adj > ProcessList.HOME_APP_ADJ) {
16345                // This process is hosting what we currently consider to be the
16346                // home app, so we don't want to let it go into the background.
16347                adj = ProcessList.HOME_APP_ADJ;
16348                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16349                app.cached = false;
16350                app.adjType = "home";
16351            }
16352            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16353                procState = ActivityManager.PROCESS_STATE_HOME;
16354            }
16355        }
16356
16357        if (app == mPreviousProcess && app.activities.size() > 0) {
16358            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16359                // This was the previous process that showed UI to the user.
16360                // We want to try to keep it around more aggressively, to give
16361                // a good experience around switching between two apps.
16362                adj = ProcessList.PREVIOUS_APP_ADJ;
16363                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16364                app.cached = false;
16365                app.adjType = "previous";
16366            }
16367            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16368                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16369            }
16370        }
16371
16372        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16373                + " reason=" + app.adjType);
16374
16375        // By default, we use the computed adjustment.  It may be changed if
16376        // there are applications dependent on our services or providers, but
16377        // this gives us a baseline and makes sure we don't get into an
16378        // infinite recursion.
16379        app.adjSeq = mAdjSeq;
16380        app.curRawAdj = adj;
16381        app.hasStartedServices = false;
16382
16383        if (mBackupTarget != null && app == mBackupTarget.app) {
16384            // If possible we want to avoid killing apps while they're being backed up
16385            if (adj > ProcessList.BACKUP_APP_ADJ) {
16386                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16387                adj = ProcessList.BACKUP_APP_ADJ;
16388                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16389                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16390                }
16391                app.adjType = "backup";
16392                app.cached = false;
16393            }
16394            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16395                procState = ActivityManager.PROCESS_STATE_BACKUP;
16396            }
16397        }
16398
16399        boolean mayBeTop = false;
16400
16401        for (int is = app.services.size()-1;
16402                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16403                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16404                        || procState > ActivityManager.PROCESS_STATE_TOP);
16405                is--) {
16406            ServiceRecord s = app.services.valueAt(is);
16407            if (s.startRequested) {
16408                app.hasStartedServices = true;
16409                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16410                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16411                }
16412                if (app.hasShownUi && app != mHomeProcess) {
16413                    // If this process has shown some UI, let it immediately
16414                    // go to the LRU list because it may be pretty heavy with
16415                    // UI stuff.  We'll tag it with a label just to help
16416                    // debug and understand what is going on.
16417                    if (adj > ProcessList.SERVICE_ADJ) {
16418                        app.adjType = "cch-started-ui-services";
16419                    }
16420                } else {
16421                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16422                        // This service has seen some activity within
16423                        // recent memory, so we will keep its process ahead
16424                        // of the background processes.
16425                        if (adj > ProcessList.SERVICE_ADJ) {
16426                            adj = ProcessList.SERVICE_ADJ;
16427                            app.adjType = "started-services";
16428                            app.cached = false;
16429                        }
16430                    }
16431                    // If we have let the service slide into the background
16432                    // state, still have some text describing what it is doing
16433                    // even though the service no longer has an impact.
16434                    if (adj > ProcessList.SERVICE_ADJ) {
16435                        app.adjType = "cch-started-services";
16436                    }
16437                }
16438            }
16439            for (int conni = s.connections.size()-1;
16440                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16441                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16442                            || procState > ActivityManager.PROCESS_STATE_TOP);
16443                    conni--) {
16444                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16445                for (int i = 0;
16446                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16447                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16448                                || procState > ActivityManager.PROCESS_STATE_TOP);
16449                        i++) {
16450                    // XXX should compute this based on the max of
16451                    // all connected clients.
16452                    ConnectionRecord cr = clist.get(i);
16453                    if (cr.binding.client == app) {
16454                        // Binding to ourself is not interesting.
16455                        continue;
16456                    }
16457                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16458                        ProcessRecord client = cr.binding.client;
16459                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16460                                TOP_APP, doingAll, now);
16461                        int clientProcState = client.curProcState;
16462                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16463                            // If the other app is cached for any reason, for purposes here
16464                            // we are going to consider it empty.  The specific cached state
16465                            // doesn't propagate except under certain conditions.
16466                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16467                        }
16468                        String adjType = null;
16469                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16470                            // Not doing bind OOM management, so treat
16471                            // this guy more like a started service.
16472                            if (app.hasShownUi && app != mHomeProcess) {
16473                                // If this process has shown some UI, let it immediately
16474                                // go to the LRU list because it may be pretty heavy with
16475                                // UI stuff.  We'll tag it with a label just to help
16476                                // debug and understand what is going on.
16477                                if (adj > clientAdj) {
16478                                    adjType = "cch-bound-ui-services";
16479                                }
16480                                app.cached = false;
16481                                clientAdj = adj;
16482                                clientProcState = procState;
16483                            } else {
16484                                if (now >= (s.lastActivity
16485                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16486                                    // This service has not seen activity within
16487                                    // recent memory, so allow it to drop to the
16488                                    // LRU list if there is no other reason to keep
16489                                    // it around.  We'll also tag it with a label just
16490                                    // to help debug and undertand what is going on.
16491                                    if (adj > clientAdj) {
16492                                        adjType = "cch-bound-services";
16493                                    }
16494                                    clientAdj = adj;
16495                                }
16496                            }
16497                        }
16498                        if (adj > clientAdj) {
16499                            // If this process has recently shown UI, and
16500                            // the process that is binding to it is less
16501                            // important than being visible, then we don't
16502                            // care about the binding as much as we care
16503                            // about letting this process get into the LRU
16504                            // list to be killed and restarted if needed for
16505                            // memory.
16506                            if (app.hasShownUi && app != mHomeProcess
16507                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16508                                adjType = "cch-bound-ui-services";
16509                            } else {
16510                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16511                                        |Context.BIND_IMPORTANT)) != 0) {
16512                                    adj = clientAdj;
16513                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16514                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16515                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16516                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16517                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16518                                    adj = clientAdj;
16519                                } else {
16520                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16521                                        adj = ProcessList.VISIBLE_APP_ADJ;
16522                                    }
16523                                }
16524                                if (!client.cached) {
16525                                    app.cached = false;
16526                                }
16527                                adjType = "service";
16528                            }
16529                        }
16530                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16531                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16532                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16533                            }
16534                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16535                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16536                                    // Special handling of clients who are in the top state.
16537                                    // We *may* want to consider this process to be in the
16538                                    // top state as well, but only if there is not another
16539                                    // reason for it to be running.  Being on the top is a
16540                                    // special state, meaning you are specifically running
16541                                    // for the current top app.  If the process is already
16542                                    // running in the background for some other reason, it
16543                                    // is more important to continue considering it to be
16544                                    // in the background state.
16545                                    mayBeTop = true;
16546                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16547                                } else {
16548                                    // Special handling for above-top states (persistent
16549                                    // processes).  These should not bring the current process
16550                                    // into the top state, since they are not on top.  Instead
16551                                    // give them the best state after that.
16552                                    clientProcState =
16553                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16554                                }
16555                            }
16556                        } else {
16557                            if (clientProcState <
16558                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16559                                clientProcState =
16560                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16561                            }
16562                        }
16563                        if (procState > clientProcState) {
16564                            procState = clientProcState;
16565                        }
16566                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16567                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16568                            app.pendingUiClean = true;
16569                        }
16570                        if (adjType != null) {
16571                            app.adjType = adjType;
16572                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16573                                    .REASON_SERVICE_IN_USE;
16574                            app.adjSource = cr.binding.client;
16575                            app.adjSourceProcState = clientProcState;
16576                            app.adjTarget = s.name;
16577                        }
16578                    }
16579                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16580                        app.treatLikeActivity = true;
16581                    }
16582                    final ActivityRecord a = cr.activity;
16583                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16584                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16585                                (a.visible || a.state == ActivityState.RESUMED
16586                                 || a.state == ActivityState.PAUSING)) {
16587                            adj = ProcessList.FOREGROUND_APP_ADJ;
16588                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16589                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16590                            }
16591                            app.cached = false;
16592                            app.adjType = "service";
16593                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16594                                    .REASON_SERVICE_IN_USE;
16595                            app.adjSource = a;
16596                            app.adjSourceProcState = procState;
16597                            app.adjTarget = s.name;
16598                        }
16599                    }
16600                }
16601            }
16602        }
16603
16604        for (int provi = app.pubProviders.size()-1;
16605                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16606                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16607                        || procState > ActivityManager.PROCESS_STATE_TOP);
16608                provi--) {
16609            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16610            for (int i = cpr.connections.size()-1;
16611                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16612                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16613                            || procState > ActivityManager.PROCESS_STATE_TOP);
16614                    i--) {
16615                ContentProviderConnection conn = cpr.connections.get(i);
16616                ProcessRecord client = conn.client;
16617                if (client == app) {
16618                    // Being our own client is not interesting.
16619                    continue;
16620                }
16621                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16622                int clientProcState = client.curProcState;
16623                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16624                    // If the other app is cached for any reason, for purposes here
16625                    // we are going to consider it empty.
16626                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16627                }
16628                if (adj > clientAdj) {
16629                    if (app.hasShownUi && app != mHomeProcess
16630                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16631                        app.adjType = "cch-ui-provider";
16632                    } else {
16633                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16634                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16635                        app.adjType = "provider";
16636                    }
16637                    app.cached &= client.cached;
16638                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16639                            .REASON_PROVIDER_IN_USE;
16640                    app.adjSource = client;
16641                    app.adjSourceProcState = clientProcState;
16642                    app.adjTarget = cpr.name;
16643                }
16644                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16645                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16646                        // Special handling of clients who are in the top state.
16647                        // We *may* want to consider this process to be in the
16648                        // top state as well, but only if there is not another
16649                        // reason for it to be running.  Being on the top is a
16650                        // special state, meaning you are specifically running
16651                        // for the current top app.  If the process is already
16652                        // running in the background for some other reason, it
16653                        // is more important to continue considering it to be
16654                        // in the background state.
16655                        mayBeTop = true;
16656                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16657                    } else {
16658                        // Special handling for above-top states (persistent
16659                        // processes).  These should not bring the current process
16660                        // into the top state, since they are not on top.  Instead
16661                        // give them the best state after that.
16662                        clientProcState =
16663                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16664                    }
16665                }
16666                if (procState > clientProcState) {
16667                    procState = clientProcState;
16668                }
16669                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16670                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16671                }
16672            }
16673            // If the provider has external (non-framework) process
16674            // dependencies, ensure that its adjustment is at least
16675            // FOREGROUND_APP_ADJ.
16676            if (cpr.hasExternalProcessHandles()) {
16677                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16678                    adj = ProcessList.FOREGROUND_APP_ADJ;
16679                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16680                    app.cached = false;
16681                    app.adjType = "provider";
16682                    app.adjTarget = cpr.name;
16683                }
16684                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16685                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16686                }
16687            }
16688        }
16689
16690        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16691            // A client of one of our services or providers is in the top state.  We
16692            // *may* want to be in the top state, but not if we are already running in
16693            // the background for some other reason.  For the decision here, we are going
16694            // to pick out a few specific states that we want to remain in when a client
16695            // is top (states that tend to be longer-term) and otherwise allow it to go
16696            // to the top state.
16697            switch (procState) {
16698                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16699                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16700                case ActivityManager.PROCESS_STATE_SERVICE:
16701                    // These all are longer-term states, so pull them up to the top
16702                    // of the background states, but not all the way to the top state.
16703                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16704                    break;
16705                default:
16706                    // Otherwise, top is a better choice, so take it.
16707                    procState = ActivityManager.PROCESS_STATE_TOP;
16708                    break;
16709            }
16710        }
16711
16712        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16713            if (app.hasClientActivities) {
16714                // This is a cached process, but with client activities.  Mark it so.
16715                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16716                app.adjType = "cch-client-act";
16717            } else if (app.treatLikeActivity) {
16718                // This is a cached process, but somebody wants us to treat it like it has
16719                // an activity, okay!
16720                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16721                app.adjType = "cch-as-act";
16722            }
16723        }
16724
16725        if (adj == ProcessList.SERVICE_ADJ) {
16726            if (doingAll) {
16727                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16728                mNewNumServiceProcs++;
16729                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16730                if (!app.serviceb) {
16731                    // This service isn't far enough down on the LRU list to
16732                    // normally be a B service, but if we are low on RAM and it
16733                    // is large we want to force it down since we would prefer to
16734                    // keep launcher over it.
16735                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16736                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16737                        app.serviceHighRam = true;
16738                        app.serviceb = true;
16739                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16740                    } else {
16741                        mNewNumAServiceProcs++;
16742                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16743                    }
16744                } else {
16745                    app.serviceHighRam = false;
16746                }
16747            }
16748            if (app.serviceb) {
16749                adj = ProcessList.SERVICE_B_ADJ;
16750            }
16751        }
16752
16753        app.curRawAdj = adj;
16754
16755        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16756        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16757        if (adj > app.maxAdj) {
16758            adj = app.maxAdj;
16759            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16760                schedGroup = Process.THREAD_GROUP_DEFAULT;
16761            }
16762        }
16763
16764        // Do final modification to adj.  Everything we do between here and applying
16765        // the final setAdj must be done in this function, because we will also use
16766        // it when computing the final cached adj later.  Note that we don't need to
16767        // worry about this for max adj above, since max adj will always be used to
16768        // keep it out of the cached vaues.
16769        app.curAdj = app.modifyRawOomAdj(adj);
16770        app.curSchedGroup = schedGroup;
16771        app.curProcState = procState;
16772        app.foregroundActivities = foregroundActivities;
16773
16774        return app.curRawAdj;
16775    }
16776
16777    /**
16778     * Schedule PSS collection of a process.
16779     */
16780    void requestPssLocked(ProcessRecord proc, int procState) {
16781        if (mPendingPssProcesses.contains(proc)) {
16782            return;
16783        }
16784        if (mPendingPssProcesses.size() == 0) {
16785            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16786        }
16787        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16788        proc.pssProcState = procState;
16789        mPendingPssProcesses.add(proc);
16790    }
16791
16792    /**
16793     * Schedule PSS collection of all processes.
16794     */
16795    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16796        if (!always) {
16797            if (now < (mLastFullPssTime +
16798                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16799                return;
16800            }
16801        }
16802        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16803        mLastFullPssTime = now;
16804        mFullPssPending = true;
16805        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16806        mPendingPssProcesses.clear();
16807        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16808            ProcessRecord app = mLruProcesses.get(i);
16809            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16810                app.pssProcState = app.setProcState;
16811                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16812                        isSleeping(), now);
16813                mPendingPssProcesses.add(app);
16814            }
16815        }
16816        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16817    }
16818
16819    /**
16820     * Ask a given process to GC right now.
16821     */
16822    final void performAppGcLocked(ProcessRecord app) {
16823        try {
16824            app.lastRequestedGc = SystemClock.uptimeMillis();
16825            if (app.thread != null) {
16826                if (app.reportLowMemory) {
16827                    app.reportLowMemory = false;
16828                    app.thread.scheduleLowMemory();
16829                } else {
16830                    app.thread.processInBackground();
16831                }
16832            }
16833        } catch (Exception e) {
16834            // whatever.
16835        }
16836    }
16837
16838    /**
16839     * Returns true if things are idle enough to perform GCs.
16840     */
16841    private final boolean canGcNowLocked() {
16842        boolean processingBroadcasts = false;
16843        for (BroadcastQueue q : mBroadcastQueues) {
16844            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16845                processingBroadcasts = true;
16846            }
16847        }
16848        return !processingBroadcasts
16849                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16850    }
16851
16852    /**
16853     * Perform GCs on all processes that are waiting for it, but only
16854     * if things are idle.
16855     */
16856    final void performAppGcsLocked() {
16857        final int N = mProcessesToGc.size();
16858        if (N <= 0) {
16859            return;
16860        }
16861        if (canGcNowLocked()) {
16862            while (mProcessesToGc.size() > 0) {
16863                ProcessRecord proc = mProcessesToGc.remove(0);
16864                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
16865                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
16866                            <= SystemClock.uptimeMillis()) {
16867                        // To avoid spamming the system, we will GC processes one
16868                        // at a time, waiting a few seconds between each.
16869                        performAppGcLocked(proc);
16870                        scheduleAppGcsLocked();
16871                        return;
16872                    } else {
16873                        // It hasn't been long enough since we last GCed this
16874                        // process...  put it in the list to wait for its time.
16875                        addProcessToGcListLocked(proc);
16876                        break;
16877                    }
16878                }
16879            }
16880
16881            scheduleAppGcsLocked();
16882        }
16883    }
16884
16885    /**
16886     * If all looks good, perform GCs on all processes waiting for them.
16887     */
16888    final void performAppGcsIfAppropriateLocked() {
16889        if (canGcNowLocked()) {
16890            performAppGcsLocked();
16891            return;
16892        }
16893        // Still not idle, wait some more.
16894        scheduleAppGcsLocked();
16895    }
16896
16897    /**
16898     * Schedule the execution of all pending app GCs.
16899     */
16900    final void scheduleAppGcsLocked() {
16901        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16902
16903        if (mProcessesToGc.size() > 0) {
16904            // Schedule a GC for the time to the next process.
16905            ProcessRecord proc = mProcessesToGc.get(0);
16906            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16907
16908            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16909            long now = SystemClock.uptimeMillis();
16910            if (when < (now+GC_TIMEOUT)) {
16911                when = now + GC_TIMEOUT;
16912            }
16913            mHandler.sendMessageAtTime(msg, when);
16914        }
16915    }
16916
16917    /**
16918     * Add a process to the array of processes waiting to be GCed.  Keeps the
16919     * list in sorted order by the last GC time.  The process can't already be
16920     * on the list.
16921     */
16922    final void addProcessToGcListLocked(ProcessRecord proc) {
16923        boolean added = false;
16924        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16925            if (mProcessesToGc.get(i).lastRequestedGc <
16926                    proc.lastRequestedGc) {
16927                added = true;
16928                mProcessesToGc.add(i+1, proc);
16929                break;
16930            }
16931        }
16932        if (!added) {
16933            mProcessesToGc.add(0, proc);
16934        }
16935    }
16936
16937    /**
16938     * Set up to ask a process to GC itself.  This will either do it
16939     * immediately, or put it on the list of processes to gc the next
16940     * time things are idle.
16941     */
16942    final void scheduleAppGcLocked(ProcessRecord app) {
16943        long now = SystemClock.uptimeMillis();
16944        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16945            return;
16946        }
16947        if (!mProcessesToGc.contains(app)) {
16948            addProcessToGcListLocked(app);
16949            scheduleAppGcsLocked();
16950        }
16951    }
16952
16953    final void checkExcessivePowerUsageLocked(boolean doKills) {
16954        updateCpuStatsNow();
16955
16956        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16957        boolean doWakeKills = doKills;
16958        boolean doCpuKills = doKills;
16959        if (mLastPowerCheckRealtime == 0) {
16960            doWakeKills = false;
16961        }
16962        if (mLastPowerCheckUptime == 0) {
16963            doCpuKills = false;
16964        }
16965        if (stats.isScreenOn()) {
16966            doWakeKills = false;
16967        }
16968        final long curRealtime = SystemClock.elapsedRealtime();
16969        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16970        final long curUptime = SystemClock.uptimeMillis();
16971        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16972        mLastPowerCheckRealtime = curRealtime;
16973        mLastPowerCheckUptime = curUptime;
16974        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16975            doWakeKills = false;
16976        }
16977        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16978            doCpuKills = false;
16979        }
16980        int i = mLruProcesses.size();
16981        while (i > 0) {
16982            i--;
16983            ProcessRecord app = mLruProcesses.get(i);
16984            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16985                long wtime;
16986                synchronized (stats) {
16987                    wtime = stats.getProcessWakeTime(app.info.uid,
16988                            app.pid, curRealtime);
16989                }
16990                long wtimeUsed = wtime - app.lastWakeTime;
16991                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16992                if (DEBUG_POWER) {
16993                    StringBuilder sb = new StringBuilder(128);
16994                    sb.append("Wake for ");
16995                    app.toShortString(sb);
16996                    sb.append(": over ");
16997                    TimeUtils.formatDuration(realtimeSince, sb);
16998                    sb.append(" used ");
16999                    TimeUtils.formatDuration(wtimeUsed, sb);
17000                    sb.append(" (");
17001                    sb.append((wtimeUsed*100)/realtimeSince);
17002                    sb.append("%)");
17003                    Slog.i(TAG, sb.toString());
17004                    sb.setLength(0);
17005                    sb.append("CPU for ");
17006                    app.toShortString(sb);
17007                    sb.append(": over ");
17008                    TimeUtils.formatDuration(uptimeSince, sb);
17009                    sb.append(" used ");
17010                    TimeUtils.formatDuration(cputimeUsed, sb);
17011                    sb.append(" (");
17012                    sb.append((cputimeUsed*100)/uptimeSince);
17013                    sb.append("%)");
17014                    Slog.i(TAG, sb.toString());
17015                }
17016                // If a process has held a wake lock for more
17017                // than 50% of the time during this period,
17018                // that sounds bad.  Kill!
17019                if (doWakeKills && realtimeSince > 0
17020                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17021                    synchronized (stats) {
17022                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17023                                realtimeSince, wtimeUsed);
17024                    }
17025                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17026                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17027                } else if (doCpuKills && uptimeSince > 0
17028                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17029                    synchronized (stats) {
17030                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17031                                uptimeSince, cputimeUsed);
17032                    }
17033                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17034                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17035                } else {
17036                    app.lastWakeTime = wtime;
17037                    app.lastCpuTime = app.curCpuTime;
17038                }
17039            }
17040        }
17041    }
17042
17043    private final boolean applyOomAdjLocked(ProcessRecord app,
17044            ProcessRecord TOP_APP, boolean doingAll, long now) {
17045        boolean success = true;
17046
17047        if (app.curRawAdj != app.setRawAdj) {
17048            app.setRawAdj = app.curRawAdj;
17049        }
17050
17051        int changes = 0;
17052
17053        if (app.curAdj != app.setAdj) {
17054            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17055            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17056                TAG, "Set " + app.pid + " " + app.processName +
17057                " adj " + app.curAdj + ": " + app.adjType);
17058            app.setAdj = app.curAdj;
17059        }
17060
17061        if (app.setSchedGroup != app.curSchedGroup) {
17062            app.setSchedGroup = app.curSchedGroup;
17063            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17064                    "Setting process group of " + app.processName
17065                    + " to " + app.curSchedGroup);
17066            if (app.waitingToKill != null &&
17067                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17068                app.kill(app.waitingToKill, true);
17069                success = false;
17070            } else {
17071                if (true) {
17072                    long oldId = Binder.clearCallingIdentity();
17073                    try {
17074                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17075                    } catch (Exception e) {
17076                        Slog.w(TAG, "Failed setting process group of " + app.pid
17077                                + " to " + app.curSchedGroup);
17078                        e.printStackTrace();
17079                    } finally {
17080                        Binder.restoreCallingIdentity(oldId);
17081                    }
17082                } else {
17083                    if (app.thread != null) {
17084                        try {
17085                            app.thread.setSchedulingGroup(app.curSchedGroup);
17086                        } catch (RemoteException e) {
17087                        }
17088                    }
17089                }
17090                Process.setSwappiness(app.pid,
17091                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17092            }
17093        }
17094        if (app.repForegroundActivities != app.foregroundActivities) {
17095            app.repForegroundActivities = app.foregroundActivities;
17096            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17097        }
17098        if (app.repProcState != app.curProcState) {
17099            app.repProcState = app.curProcState;
17100            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17101            if (app.thread != null) {
17102                try {
17103                    if (false) {
17104                        //RuntimeException h = new RuntimeException("here");
17105                        Slog.i(TAG, "Sending new process state " + app.repProcState
17106                                + " to " + app /*, h*/);
17107                    }
17108                    app.thread.setProcessState(app.repProcState);
17109                } catch (RemoteException e) {
17110                }
17111            }
17112        }
17113        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17114                app.setProcState)) {
17115            app.lastStateTime = now;
17116            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17117                    isSleeping(), now);
17118            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17119                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17120                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17121                    + (app.nextPssTime-now) + ": " + app);
17122        } else {
17123            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17124                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17125                requestPssLocked(app, app.setProcState);
17126                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17127                        isSleeping(), now);
17128            } else if (false && DEBUG_PSS) {
17129                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17130            }
17131        }
17132        if (app.setProcState != app.curProcState) {
17133            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17134                    "Proc state change of " + app.processName
17135                    + " to " + app.curProcState);
17136            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17137            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17138            if (setImportant && !curImportant) {
17139                // This app is no longer something we consider important enough to allow to
17140                // use arbitrary amounts of battery power.  Note
17141                // its current wake lock time to later know to kill it if
17142                // it is not behaving well.
17143                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17144                synchronized (stats) {
17145                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17146                            app.pid, SystemClock.elapsedRealtime());
17147                }
17148                app.lastCpuTime = app.curCpuTime;
17149
17150            }
17151            app.setProcState = app.curProcState;
17152            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17153                app.notCachedSinceIdle = false;
17154            }
17155            if (!doingAll) {
17156                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17157            } else {
17158                app.procStateChanged = true;
17159            }
17160        }
17161
17162        if (changes != 0) {
17163            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17164            int i = mPendingProcessChanges.size()-1;
17165            ProcessChangeItem item = null;
17166            while (i >= 0) {
17167                item = mPendingProcessChanges.get(i);
17168                if (item.pid == app.pid) {
17169                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17170                    break;
17171                }
17172                i--;
17173            }
17174            if (i < 0) {
17175                // No existing item in pending changes; need a new one.
17176                final int NA = mAvailProcessChanges.size();
17177                if (NA > 0) {
17178                    item = mAvailProcessChanges.remove(NA-1);
17179                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17180                } else {
17181                    item = new ProcessChangeItem();
17182                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17183                }
17184                item.changes = 0;
17185                item.pid = app.pid;
17186                item.uid = app.info.uid;
17187                if (mPendingProcessChanges.size() == 0) {
17188                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17189                            "*** Enqueueing dispatch processes changed!");
17190                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17191                }
17192                mPendingProcessChanges.add(item);
17193            }
17194            item.changes |= changes;
17195            item.processState = app.repProcState;
17196            item.foregroundActivities = app.repForegroundActivities;
17197            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17198                    + Integer.toHexString(System.identityHashCode(item))
17199                    + " " + app.toShortString() + ": changes=" + item.changes
17200                    + " procState=" + item.processState
17201                    + " foreground=" + item.foregroundActivities
17202                    + " type=" + app.adjType + " source=" + app.adjSource
17203                    + " target=" + app.adjTarget);
17204        }
17205
17206        return success;
17207    }
17208
17209    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17210        if (proc.thread != null) {
17211            if (proc.baseProcessTracker != null) {
17212                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17213            }
17214            if (proc.repProcState >= 0) {
17215                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17216                        proc.repProcState);
17217            }
17218        }
17219    }
17220
17221    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17222            ProcessRecord TOP_APP, boolean doingAll, long now) {
17223        if (app.thread == null) {
17224            return false;
17225        }
17226
17227        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17228
17229        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17230    }
17231
17232    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17233            boolean oomAdj) {
17234        if (isForeground != proc.foregroundServices) {
17235            proc.foregroundServices = isForeground;
17236            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17237                    proc.info.uid);
17238            if (isForeground) {
17239                if (curProcs == null) {
17240                    curProcs = new ArrayList<ProcessRecord>();
17241                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17242                }
17243                if (!curProcs.contains(proc)) {
17244                    curProcs.add(proc);
17245                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17246                            proc.info.packageName, proc.info.uid);
17247                }
17248            } else {
17249                if (curProcs != null) {
17250                    if (curProcs.remove(proc)) {
17251                        mBatteryStatsService.noteEvent(
17252                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17253                                proc.info.packageName, proc.info.uid);
17254                        if (curProcs.size() <= 0) {
17255                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17256                        }
17257                    }
17258                }
17259            }
17260            if (oomAdj) {
17261                updateOomAdjLocked();
17262            }
17263        }
17264    }
17265
17266    private final ActivityRecord resumedAppLocked() {
17267        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17268        String pkg;
17269        int uid;
17270        if (act != null) {
17271            pkg = act.packageName;
17272            uid = act.info.applicationInfo.uid;
17273        } else {
17274            pkg = null;
17275            uid = -1;
17276        }
17277        // Has the UID or resumed package name changed?
17278        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17279                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17280            if (mCurResumedPackage != null) {
17281                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17282                        mCurResumedPackage, mCurResumedUid);
17283            }
17284            mCurResumedPackage = pkg;
17285            mCurResumedUid = uid;
17286            if (mCurResumedPackage != null) {
17287                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17288                        mCurResumedPackage, mCurResumedUid);
17289            }
17290        }
17291        return act;
17292    }
17293
17294    final boolean updateOomAdjLocked(ProcessRecord app) {
17295        final ActivityRecord TOP_ACT = resumedAppLocked();
17296        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17297        final boolean wasCached = app.cached;
17298
17299        mAdjSeq++;
17300
17301        // This is the desired cached adjusment we want to tell it to use.
17302        // If our app is currently cached, we know it, and that is it.  Otherwise,
17303        // we don't know it yet, and it needs to now be cached we will then
17304        // need to do a complete oom adj.
17305        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17306                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17307        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17308                SystemClock.uptimeMillis());
17309        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17310            // Changed to/from cached state, so apps after it in the LRU
17311            // list may also be changed.
17312            updateOomAdjLocked();
17313        }
17314        return success;
17315    }
17316
17317    final void updateOomAdjLocked() {
17318        final ActivityRecord TOP_ACT = resumedAppLocked();
17319        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17320        final long now = SystemClock.uptimeMillis();
17321        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17322        final int N = mLruProcesses.size();
17323
17324        if (false) {
17325            RuntimeException e = new RuntimeException();
17326            e.fillInStackTrace();
17327            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17328        }
17329
17330        mAdjSeq++;
17331        mNewNumServiceProcs = 0;
17332        mNewNumAServiceProcs = 0;
17333
17334        final int emptyProcessLimit;
17335        final int cachedProcessLimit;
17336        if (mProcessLimit <= 0) {
17337            emptyProcessLimit = cachedProcessLimit = 0;
17338        } else if (mProcessLimit == 1) {
17339            emptyProcessLimit = 1;
17340            cachedProcessLimit = 0;
17341        } else {
17342            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17343            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17344        }
17345
17346        // Let's determine how many processes we have running vs.
17347        // how many slots we have for background processes; we may want
17348        // to put multiple processes in a slot of there are enough of
17349        // them.
17350        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17351                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17352        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17353        if (numEmptyProcs > cachedProcessLimit) {
17354            // If there are more empty processes than our limit on cached
17355            // processes, then use the cached process limit for the factor.
17356            // This ensures that the really old empty processes get pushed
17357            // down to the bottom, so if we are running low on memory we will
17358            // have a better chance at keeping around more cached processes
17359            // instead of a gazillion empty processes.
17360            numEmptyProcs = cachedProcessLimit;
17361        }
17362        int emptyFactor = numEmptyProcs/numSlots;
17363        if (emptyFactor < 1) emptyFactor = 1;
17364        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17365        if (cachedFactor < 1) cachedFactor = 1;
17366        int stepCached = 0;
17367        int stepEmpty = 0;
17368        int numCached = 0;
17369        int numEmpty = 0;
17370        int numTrimming = 0;
17371
17372        mNumNonCachedProcs = 0;
17373        mNumCachedHiddenProcs = 0;
17374
17375        // First update the OOM adjustment for each of the
17376        // application processes based on their current state.
17377        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17378        int nextCachedAdj = curCachedAdj+1;
17379        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17380        int nextEmptyAdj = curEmptyAdj+2;
17381        for (int i=N-1; i>=0; i--) {
17382            ProcessRecord app = mLruProcesses.get(i);
17383            if (!app.killedByAm && app.thread != null) {
17384                app.procStateChanged = false;
17385                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17386
17387                // If we haven't yet assigned the final cached adj
17388                // to the process, do that now.
17389                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17390                    switch (app.curProcState) {
17391                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17392                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17393                            // This process is a cached process holding activities...
17394                            // assign it the next cached value for that type, and then
17395                            // step that cached level.
17396                            app.curRawAdj = curCachedAdj;
17397                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17398                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17399                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17400                                    + ")");
17401                            if (curCachedAdj != nextCachedAdj) {
17402                                stepCached++;
17403                                if (stepCached >= cachedFactor) {
17404                                    stepCached = 0;
17405                                    curCachedAdj = nextCachedAdj;
17406                                    nextCachedAdj += 2;
17407                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17408                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17409                                    }
17410                                }
17411                            }
17412                            break;
17413                        default:
17414                            // For everything else, assign next empty cached process
17415                            // level and bump that up.  Note that this means that
17416                            // long-running services that have dropped down to the
17417                            // cached level will be treated as empty (since their process
17418                            // state is still as a service), which is what we want.
17419                            app.curRawAdj = curEmptyAdj;
17420                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17421                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17422                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17423                                    + ")");
17424                            if (curEmptyAdj != nextEmptyAdj) {
17425                                stepEmpty++;
17426                                if (stepEmpty >= emptyFactor) {
17427                                    stepEmpty = 0;
17428                                    curEmptyAdj = nextEmptyAdj;
17429                                    nextEmptyAdj += 2;
17430                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17431                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17432                                    }
17433                                }
17434                            }
17435                            break;
17436                    }
17437                }
17438
17439                applyOomAdjLocked(app, TOP_APP, true, now);
17440
17441                // Count the number of process types.
17442                switch (app.curProcState) {
17443                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17444                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17445                        mNumCachedHiddenProcs++;
17446                        numCached++;
17447                        if (numCached > cachedProcessLimit) {
17448                            app.kill("cached #" + numCached, true);
17449                        }
17450                        break;
17451                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17452                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17453                                && app.lastActivityTime < oldTime) {
17454                            app.kill("empty for "
17455                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17456                                    / 1000) + "s", true);
17457                        } else {
17458                            numEmpty++;
17459                            if (numEmpty > emptyProcessLimit) {
17460                                app.kill("empty #" + numEmpty, true);
17461                            }
17462                        }
17463                        break;
17464                    default:
17465                        mNumNonCachedProcs++;
17466                        break;
17467                }
17468
17469                if (app.isolated && app.services.size() <= 0) {
17470                    // If this is an isolated process, and there are no
17471                    // services running in it, then the process is no longer
17472                    // needed.  We agressively kill these because we can by
17473                    // definition not re-use the same process again, and it is
17474                    // good to avoid having whatever code was running in them
17475                    // left sitting around after no longer needed.
17476                    app.kill("isolated not needed", true);
17477                }
17478
17479                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17480                        && !app.killedByAm) {
17481                    numTrimming++;
17482                }
17483            }
17484        }
17485
17486        mNumServiceProcs = mNewNumServiceProcs;
17487
17488        // Now determine the memory trimming level of background processes.
17489        // Unfortunately we need to start at the back of the list to do this
17490        // properly.  We only do this if the number of background apps we
17491        // are managing to keep around is less than half the maximum we desire;
17492        // if we are keeping a good number around, we'll let them use whatever
17493        // memory they want.
17494        final int numCachedAndEmpty = numCached + numEmpty;
17495        int memFactor;
17496        if (numCached <= ProcessList.TRIM_CACHED_APPS
17497                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17498            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17499                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17500            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17501                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17502            } else {
17503                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17504            }
17505        } else {
17506            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17507        }
17508        // We always allow the memory level to go up (better).  We only allow it to go
17509        // down if we are in a state where that is allowed, *and* the total number of processes
17510        // has gone down since last time.
17511        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17512                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17513                + " last=" + mLastNumProcesses);
17514        if (memFactor > mLastMemoryLevel) {
17515            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17516                memFactor = mLastMemoryLevel;
17517                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17518            }
17519        }
17520        mLastMemoryLevel = memFactor;
17521        mLastNumProcesses = mLruProcesses.size();
17522        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17523        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17524        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17525            if (mLowRamStartTime == 0) {
17526                mLowRamStartTime = now;
17527            }
17528            int step = 0;
17529            int fgTrimLevel;
17530            switch (memFactor) {
17531                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17532                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17533                    break;
17534                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17535                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17536                    break;
17537                default:
17538                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17539                    break;
17540            }
17541            int factor = numTrimming/3;
17542            int minFactor = 2;
17543            if (mHomeProcess != null) minFactor++;
17544            if (mPreviousProcess != null) minFactor++;
17545            if (factor < minFactor) factor = minFactor;
17546            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17547            for (int i=N-1; i>=0; i--) {
17548                ProcessRecord app = mLruProcesses.get(i);
17549                if (allChanged || app.procStateChanged) {
17550                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17551                    app.procStateChanged = false;
17552                }
17553                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17554                        && !app.killedByAm) {
17555                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17556                        try {
17557                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17558                                    "Trimming memory of " + app.processName
17559                                    + " to " + curLevel);
17560                            app.thread.scheduleTrimMemory(curLevel);
17561                        } catch (RemoteException e) {
17562                        }
17563                        if (false) {
17564                            // For now we won't do this; our memory trimming seems
17565                            // to be good enough at this point that destroying
17566                            // activities causes more harm than good.
17567                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17568                                    && app != mHomeProcess && app != mPreviousProcess) {
17569                                // Need to do this on its own message because the stack may not
17570                                // be in a consistent state at this point.
17571                                // For these apps we will also finish their activities
17572                                // to help them free memory.
17573                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17574                            }
17575                        }
17576                    }
17577                    app.trimMemoryLevel = curLevel;
17578                    step++;
17579                    if (step >= factor) {
17580                        step = 0;
17581                        switch (curLevel) {
17582                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17583                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17584                                break;
17585                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17586                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17587                                break;
17588                        }
17589                    }
17590                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17591                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17592                            && app.thread != null) {
17593                        try {
17594                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17595                                    "Trimming memory of heavy-weight " + app.processName
17596                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17597                            app.thread.scheduleTrimMemory(
17598                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17599                        } catch (RemoteException e) {
17600                        }
17601                    }
17602                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17603                } else {
17604                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17605                            || app.systemNoUi) && app.pendingUiClean) {
17606                        // If this application is now in the background and it
17607                        // had done UI, then give it the special trim level to
17608                        // have it free UI resources.
17609                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17610                        if (app.trimMemoryLevel < level && app.thread != null) {
17611                            try {
17612                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17613                                        "Trimming memory of bg-ui " + app.processName
17614                                        + " to " + level);
17615                                app.thread.scheduleTrimMemory(level);
17616                            } catch (RemoteException e) {
17617                            }
17618                        }
17619                        app.pendingUiClean = false;
17620                    }
17621                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17622                        try {
17623                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17624                                    "Trimming memory of fg " + app.processName
17625                                    + " to " + fgTrimLevel);
17626                            app.thread.scheduleTrimMemory(fgTrimLevel);
17627                        } catch (RemoteException e) {
17628                        }
17629                    }
17630                    app.trimMemoryLevel = fgTrimLevel;
17631                }
17632            }
17633        } else {
17634            if (mLowRamStartTime != 0) {
17635                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17636                mLowRamStartTime = 0;
17637            }
17638            for (int i=N-1; i>=0; i--) {
17639                ProcessRecord app = mLruProcesses.get(i);
17640                if (allChanged || app.procStateChanged) {
17641                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17642                    app.procStateChanged = false;
17643                }
17644                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17645                        || app.systemNoUi) && app.pendingUiClean) {
17646                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17647                            && app.thread != null) {
17648                        try {
17649                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17650                                    "Trimming memory of ui hidden " + app.processName
17651                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17652                            app.thread.scheduleTrimMemory(
17653                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17654                        } catch (RemoteException e) {
17655                        }
17656                    }
17657                    app.pendingUiClean = false;
17658                }
17659                app.trimMemoryLevel = 0;
17660            }
17661        }
17662
17663        if (mAlwaysFinishActivities) {
17664            // Need to do this on its own message because the stack may not
17665            // be in a consistent state at this point.
17666            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17667        }
17668
17669        if (allChanged) {
17670            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17671        }
17672
17673        if (mProcessStats.shouldWriteNowLocked(now)) {
17674            mHandler.post(new Runnable() {
17675                @Override public void run() {
17676                    synchronized (ActivityManagerService.this) {
17677                        mProcessStats.writeStateAsyncLocked();
17678                    }
17679                }
17680            });
17681        }
17682
17683        if (DEBUG_OOM_ADJ) {
17684            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17685        }
17686    }
17687
17688    final void trimApplications() {
17689        synchronized (this) {
17690            int i;
17691
17692            // First remove any unused application processes whose package
17693            // has been removed.
17694            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17695                final ProcessRecord app = mRemovedProcesses.get(i);
17696                if (app.activities.size() == 0
17697                        && app.curReceiver == null && app.services.size() == 0) {
17698                    Slog.i(
17699                        TAG, "Exiting empty application process "
17700                        + app.processName + " ("
17701                        + (app.thread != null ? app.thread.asBinder() : null)
17702                        + ")\n");
17703                    if (app.pid > 0 && app.pid != MY_PID) {
17704                        app.kill("empty", false);
17705                    } else {
17706                        try {
17707                            app.thread.scheduleExit();
17708                        } catch (Exception e) {
17709                            // Ignore exceptions.
17710                        }
17711                    }
17712                    cleanUpApplicationRecordLocked(app, false, true, -1);
17713                    mRemovedProcesses.remove(i);
17714
17715                    if (app.persistent) {
17716                        addAppLocked(app.info, false, null /* ABI override */);
17717                    }
17718                }
17719            }
17720
17721            // Now update the oom adj for all processes.
17722            updateOomAdjLocked();
17723        }
17724    }
17725
17726    /** This method sends the specified signal to each of the persistent apps */
17727    public void signalPersistentProcesses(int sig) throws RemoteException {
17728        if (sig != Process.SIGNAL_USR1) {
17729            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17730        }
17731
17732        synchronized (this) {
17733            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17734                    != PackageManager.PERMISSION_GRANTED) {
17735                throw new SecurityException("Requires permission "
17736                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17737            }
17738
17739            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17740                ProcessRecord r = mLruProcesses.get(i);
17741                if (r.thread != null && r.persistent) {
17742                    Process.sendSignal(r.pid, sig);
17743                }
17744            }
17745        }
17746    }
17747
17748    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
17749        if (proc == null || proc == mProfileProc) {
17750            proc = mProfileProc;
17751            profileType = mProfileType;
17752            clearProfilerLocked();
17753        }
17754        if (proc == null) {
17755            return;
17756        }
17757        try {
17758            proc.thread.profilerControl(false, null, profileType);
17759        } catch (RemoteException e) {
17760            throw new IllegalStateException("Process disappeared");
17761        }
17762    }
17763
17764    private void clearProfilerLocked() {
17765        if (mProfileFd != null) {
17766            try {
17767                mProfileFd.close();
17768            } catch (IOException e) {
17769            }
17770        }
17771        mProfileApp = null;
17772        mProfileProc = null;
17773        mProfileFile = null;
17774        mProfileType = 0;
17775        mAutoStopProfiler = false;
17776        mSamplingInterval = 0;
17777    }
17778
17779    public boolean profileControl(String process, int userId, boolean start,
17780            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
17781
17782        try {
17783            synchronized (this) {
17784                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17785                // its own permission.
17786                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17787                        != PackageManager.PERMISSION_GRANTED) {
17788                    throw new SecurityException("Requires permission "
17789                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17790                }
17791
17792                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
17793                    throw new IllegalArgumentException("null profile info or fd");
17794                }
17795
17796                ProcessRecord proc = null;
17797                if (process != null) {
17798                    proc = findProcessLocked(process, userId, "profileControl");
17799                }
17800
17801                if (start && (proc == null || proc.thread == null)) {
17802                    throw new IllegalArgumentException("Unknown process: " + process);
17803                }
17804
17805                if (start) {
17806                    stopProfilerLocked(null, 0);
17807                    setProfileApp(proc.info, proc.processName, profilerInfo);
17808                    mProfileProc = proc;
17809                    mProfileType = profileType;
17810                    ParcelFileDescriptor fd = profilerInfo.profileFd;
17811                    try {
17812                        fd = fd.dup();
17813                    } catch (IOException e) {
17814                        fd = null;
17815                    }
17816                    profilerInfo.profileFd = fd;
17817                    proc.thread.profilerControl(start, profilerInfo, profileType);
17818                    fd = null;
17819                    mProfileFd = null;
17820                } else {
17821                    stopProfilerLocked(proc, profileType);
17822                    if (profilerInfo != null && profilerInfo.profileFd != null) {
17823                        try {
17824                            profilerInfo.profileFd.close();
17825                        } catch (IOException e) {
17826                        }
17827                    }
17828                }
17829
17830                return true;
17831            }
17832        } catch (RemoteException e) {
17833            throw new IllegalStateException("Process disappeared");
17834        } finally {
17835            if (profilerInfo != null && profilerInfo.profileFd != null) {
17836                try {
17837                    profilerInfo.profileFd.close();
17838                } catch (IOException e) {
17839                }
17840            }
17841        }
17842    }
17843
17844    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17845        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17846                userId, true, ALLOW_FULL_ONLY, callName, null);
17847        ProcessRecord proc = null;
17848        try {
17849            int pid = Integer.parseInt(process);
17850            synchronized (mPidsSelfLocked) {
17851                proc = mPidsSelfLocked.get(pid);
17852            }
17853        } catch (NumberFormatException e) {
17854        }
17855
17856        if (proc == null) {
17857            ArrayMap<String, SparseArray<ProcessRecord>> all
17858                    = mProcessNames.getMap();
17859            SparseArray<ProcessRecord> procs = all.get(process);
17860            if (procs != null && procs.size() > 0) {
17861                proc = procs.valueAt(0);
17862                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17863                    for (int i=1; i<procs.size(); i++) {
17864                        ProcessRecord thisProc = procs.valueAt(i);
17865                        if (thisProc.userId == userId) {
17866                            proc = thisProc;
17867                            break;
17868                        }
17869                    }
17870                }
17871            }
17872        }
17873
17874        return proc;
17875    }
17876
17877    public boolean dumpHeap(String process, int userId, boolean managed,
17878            String path, ParcelFileDescriptor fd) throws RemoteException {
17879
17880        try {
17881            synchronized (this) {
17882                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17883                // its own permission (same as profileControl).
17884                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17885                        != PackageManager.PERMISSION_GRANTED) {
17886                    throw new SecurityException("Requires permission "
17887                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17888                }
17889
17890                if (fd == null) {
17891                    throw new IllegalArgumentException("null fd");
17892                }
17893
17894                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17895                if (proc == null || proc.thread == null) {
17896                    throw new IllegalArgumentException("Unknown process: " + process);
17897                }
17898
17899                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17900                if (!isDebuggable) {
17901                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17902                        throw new SecurityException("Process not debuggable: " + proc);
17903                    }
17904                }
17905
17906                proc.thread.dumpHeap(managed, path, fd);
17907                fd = null;
17908                return true;
17909            }
17910        } catch (RemoteException e) {
17911            throw new IllegalStateException("Process disappeared");
17912        } finally {
17913            if (fd != null) {
17914                try {
17915                    fd.close();
17916                } catch (IOException e) {
17917                }
17918            }
17919        }
17920    }
17921
17922    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17923    public void monitor() {
17924        synchronized (this) { }
17925    }
17926
17927    void onCoreSettingsChange(Bundle settings) {
17928        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17929            ProcessRecord processRecord = mLruProcesses.get(i);
17930            try {
17931                if (processRecord.thread != null) {
17932                    processRecord.thread.setCoreSettings(settings);
17933                }
17934            } catch (RemoteException re) {
17935                /* ignore */
17936            }
17937        }
17938    }
17939
17940    // Multi-user methods
17941
17942    /**
17943     * Start user, if its not already running, but don't bring it to foreground.
17944     */
17945    @Override
17946    public boolean startUserInBackground(final int userId) {
17947        return startUser(userId, /* foreground */ false);
17948    }
17949
17950    /**
17951     * Start user, if its not already running, and bring it to foreground.
17952     */
17953    boolean startUserInForeground(final int userId, Dialog dlg) {
17954        boolean result = startUser(userId, /* foreground */ true);
17955        dlg.dismiss();
17956        return result;
17957    }
17958
17959    /**
17960     * Refreshes the list of users related to the current user when either a
17961     * user switch happens or when a new related user is started in the
17962     * background.
17963     */
17964    private void updateCurrentProfileIdsLocked() {
17965        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17966                mCurrentUserId, false /* enabledOnly */);
17967        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17968        for (int i = 0; i < currentProfileIds.length; i++) {
17969            currentProfileIds[i] = profiles.get(i).id;
17970        }
17971        mCurrentProfileIds = currentProfileIds;
17972
17973        synchronized (mUserProfileGroupIdsSelfLocked) {
17974            mUserProfileGroupIdsSelfLocked.clear();
17975            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17976            for (int i = 0; i < users.size(); i++) {
17977                UserInfo user = users.get(i);
17978                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17979                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17980                }
17981            }
17982        }
17983    }
17984
17985    private Set getProfileIdsLocked(int userId) {
17986        Set userIds = new HashSet<Integer>();
17987        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17988                userId, false /* enabledOnly */);
17989        for (UserInfo user : profiles) {
17990            userIds.add(Integer.valueOf(user.id));
17991        }
17992        return userIds;
17993    }
17994
17995    @Override
17996    public boolean switchUser(final int userId) {
17997        String userName;
17998        synchronized (this) {
17999            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18000            if (userInfo == null) {
18001                Slog.w(TAG, "No user info for user #" + userId);
18002                return false;
18003            }
18004            if (userInfo.isManagedProfile()) {
18005                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18006                return false;
18007            }
18008            userName = userInfo.name;
18009            mTargetUserId = userId;
18010        }
18011        mHandler.removeMessages(START_USER_SWITCH_MSG);
18012        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18013        return true;
18014    }
18015
18016    private void showUserSwitchDialog(int userId, String userName) {
18017        // The dialog will show and then initiate the user switch by calling startUserInForeground
18018        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18019                true /* above system */);
18020        d.show();
18021    }
18022
18023    private boolean startUser(final int userId, final boolean foreground) {
18024        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18025                != PackageManager.PERMISSION_GRANTED) {
18026            String msg = "Permission Denial: switchUser() from pid="
18027                    + Binder.getCallingPid()
18028                    + ", uid=" + Binder.getCallingUid()
18029                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18030            Slog.w(TAG, msg);
18031            throw new SecurityException(msg);
18032        }
18033
18034        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18035
18036        final long ident = Binder.clearCallingIdentity();
18037        try {
18038            synchronized (this) {
18039                final int oldUserId = mCurrentUserId;
18040                if (oldUserId == userId) {
18041                    return true;
18042                }
18043
18044                mStackSupervisor.setLockTaskModeLocked(null, false);
18045
18046                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18047                if (userInfo == null) {
18048                    Slog.w(TAG, "No user info for user #" + userId);
18049                    return false;
18050                }
18051                if (foreground && userInfo.isManagedProfile()) {
18052                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18053                    return false;
18054                }
18055
18056                if (foreground) {
18057                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18058                            R.anim.screen_user_enter);
18059                }
18060
18061                boolean needStart = false;
18062
18063                // If the user we are switching to is not currently started, then
18064                // we need to start it now.
18065                if (mStartedUsers.get(userId) == null) {
18066                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18067                    updateStartedUserArrayLocked();
18068                    needStart = true;
18069                }
18070
18071                final Integer userIdInt = Integer.valueOf(userId);
18072                mUserLru.remove(userIdInt);
18073                mUserLru.add(userIdInt);
18074
18075                if (foreground) {
18076                    mCurrentUserId = userId;
18077                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18078                    updateCurrentProfileIdsLocked();
18079                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18080                    // Once the internal notion of the active user has switched, we lock the device
18081                    // with the option to show the user switcher on the keyguard.
18082                    mWindowManager.lockNow(null);
18083                } else {
18084                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18085                    updateCurrentProfileIdsLocked();
18086                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18087                    mUserLru.remove(currentUserIdInt);
18088                    mUserLru.add(currentUserIdInt);
18089                }
18090
18091                final UserStartedState uss = mStartedUsers.get(userId);
18092
18093                // Make sure user is in the started state.  If it is currently
18094                // stopping, we need to knock that off.
18095                if (uss.mState == UserStartedState.STATE_STOPPING) {
18096                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18097                    // so we can just fairly silently bring the user back from
18098                    // the almost-dead.
18099                    uss.mState = UserStartedState.STATE_RUNNING;
18100                    updateStartedUserArrayLocked();
18101                    needStart = true;
18102                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18103                    // This means ACTION_SHUTDOWN has been sent, so we will
18104                    // need to treat this as a new boot of the user.
18105                    uss.mState = UserStartedState.STATE_BOOTING;
18106                    updateStartedUserArrayLocked();
18107                    needStart = true;
18108                }
18109
18110                if (uss.mState == UserStartedState.STATE_BOOTING) {
18111                    // Booting up a new user, need to tell system services about it.
18112                    // Note that this is on the same handler as scheduling of broadcasts,
18113                    // which is important because it needs to go first.
18114                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18115                }
18116
18117                if (foreground) {
18118                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18119                            oldUserId));
18120                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18121                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18122                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18123                            oldUserId, userId, uss));
18124                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18125                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18126                }
18127
18128                if (needStart) {
18129                    // Send USER_STARTED broadcast
18130                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18131                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18132                            | Intent.FLAG_RECEIVER_FOREGROUND);
18133                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18134                    broadcastIntentLocked(null, null, intent,
18135                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18136                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18137                }
18138
18139                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18140                    if (userId != UserHandle.USER_OWNER) {
18141                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18142                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18143                        broadcastIntentLocked(null, null, intent, null,
18144                                new IIntentReceiver.Stub() {
18145                                    public void performReceive(Intent intent, int resultCode,
18146                                            String data, Bundle extras, boolean ordered,
18147                                            boolean sticky, int sendingUser) {
18148                                        onUserInitialized(uss, foreground, oldUserId, userId);
18149                                    }
18150                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18151                                true, false, MY_PID, Process.SYSTEM_UID,
18152                                userId);
18153                        uss.initializing = true;
18154                    } else {
18155                        getUserManagerLocked().makeInitialized(userInfo.id);
18156                    }
18157                }
18158
18159                if (foreground) {
18160                    if (!uss.initializing) {
18161                        moveUserToForeground(uss, oldUserId, userId);
18162                    }
18163                } else {
18164                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18165                }
18166
18167                if (needStart) {
18168                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18169                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18170                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18171                    broadcastIntentLocked(null, null, intent,
18172                            null, new IIntentReceiver.Stub() {
18173                                @Override
18174                                public void performReceive(Intent intent, int resultCode, String data,
18175                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18176                                        throws RemoteException {
18177                                }
18178                            }, 0, null, null,
18179                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18180                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18181                }
18182            }
18183        } finally {
18184            Binder.restoreCallingIdentity(ident);
18185        }
18186
18187        return true;
18188    }
18189
18190    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18191        long ident = Binder.clearCallingIdentity();
18192        try {
18193            Intent intent;
18194            if (oldUserId >= 0) {
18195                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18196                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18197                int count = profiles.size();
18198                for (int i = 0; i < count; i++) {
18199                    int profileUserId = profiles.get(i).id;
18200                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18201                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18202                            | Intent.FLAG_RECEIVER_FOREGROUND);
18203                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18204                    broadcastIntentLocked(null, null, intent,
18205                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18206                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18207                }
18208            }
18209            if (newUserId >= 0) {
18210                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18211                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18212                int count = profiles.size();
18213                for (int i = 0; i < count; i++) {
18214                    int profileUserId = profiles.get(i).id;
18215                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18216                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18217                            | Intent.FLAG_RECEIVER_FOREGROUND);
18218                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18219                    broadcastIntentLocked(null, null, intent,
18220                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18221                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18222                }
18223                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18224                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18225                        | Intent.FLAG_RECEIVER_FOREGROUND);
18226                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18227                broadcastIntentLocked(null, null, intent,
18228                        null, null, 0, null, null,
18229                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18230                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18231            }
18232        } finally {
18233            Binder.restoreCallingIdentity(ident);
18234        }
18235    }
18236
18237    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18238            final int newUserId) {
18239        final int N = mUserSwitchObservers.beginBroadcast();
18240        if (N > 0) {
18241            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18242                int mCount = 0;
18243                @Override
18244                public void sendResult(Bundle data) throws RemoteException {
18245                    synchronized (ActivityManagerService.this) {
18246                        if (mCurUserSwitchCallback == this) {
18247                            mCount++;
18248                            if (mCount == N) {
18249                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18250                            }
18251                        }
18252                    }
18253                }
18254            };
18255            synchronized (this) {
18256                uss.switching = true;
18257                mCurUserSwitchCallback = callback;
18258            }
18259            for (int i=0; i<N; i++) {
18260                try {
18261                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18262                            newUserId, callback);
18263                } catch (RemoteException e) {
18264                }
18265            }
18266        } else {
18267            synchronized (this) {
18268                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18269            }
18270        }
18271        mUserSwitchObservers.finishBroadcast();
18272    }
18273
18274    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18275        synchronized (this) {
18276            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18277            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18278        }
18279    }
18280
18281    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18282        mCurUserSwitchCallback = null;
18283        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18284        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18285                oldUserId, newUserId, uss));
18286    }
18287
18288    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18289        synchronized (this) {
18290            if (foreground) {
18291                moveUserToForeground(uss, oldUserId, newUserId);
18292            }
18293        }
18294
18295        completeSwitchAndInitalize(uss, newUserId, true, false);
18296    }
18297
18298    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18299        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18300        if (homeInFront) {
18301            startHomeActivityLocked(newUserId);
18302        } else {
18303            mStackSupervisor.resumeTopActivitiesLocked();
18304        }
18305        EventLogTags.writeAmSwitchUser(newUserId);
18306        getUserManagerLocked().userForeground(newUserId);
18307        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18308    }
18309
18310    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18311        completeSwitchAndInitalize(uss, newUserId, false, true);
18312    }
18313
18314    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18315            boolean clearInitializing, boolean clearSwitching) {
18316        boolean unfrozen = false;
18317        synchronized (this) {
18318            if (clearInitializing) {
18319                uss.initializing = false;
18320                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18321            }
18322            if (clearSwitching) {
18323                uss.switching = false;
18324            }
18325            if (!uss.switching && !uss.initializing) {
18326                mWindowManager.stopFreezingScreen();
18327                unfrozen = true;
18328            }
18329        }
18330        if (unfrozen) {
18331            final int N = mUserSwitchObservers.beginBroadcast();
18332            for (int i=0; i<N; i++) {
18333                try {
18334                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18335                } catch (RemoteException e) {
18336                }
18337            }
18338            mUserSwitchObservers.finishBroadcast();
18339        }
18340    }
18341
18342    void scheduleStartProfilesLocked() {
18343        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18344            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18345                    DateUtils.SECOND_IN_MILLIS);
18346        }
18347    }
18348
18349    void startProfilesLocked() {
18350        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18351        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18352                mCurrentUserId, false /* enabledOnly */);
18353        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18354        for (UserInfo user : profiles) {
18355            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18356                    && user.id != mCurrentUserId) {
18357                toStart.add(user);
18358            }
18359        }
18360        final int n = toStart.size();
18361        int i = 0;
18362        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18363            startUserInBackground(toStart.get(i).id);
18364        }
18365        if (i < n) {
18366            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18367        }
18368    }
18369
18370    void finishUserBoot(UserStartedState uss) {
18371        synchronized (this) {
18372            if (uss.mState == UserStartedState.STATE_BOOTING
18373                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18374                uss.mState = UserStartedState.STATE_RUNNING;
18375                final int userId = uss.mHandle.getIdentifier();
18376                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18377                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18378                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18379                broadcastIntentLocked(null, null, intent,
18380                        null, null, 0, null, null,
18381                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18382                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18383            }
18384        }
18385    }
18386
18387    void finishUserSwitch(UserStartedState uss) {
18388        synchronized (this) {
18389            finishUserBoot(uss);
18390
18391            startProfilesLocked();
18392
18393            int num = mUserLru.size();
18394            int i = 0;
18395            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18396                Integer oldUserId = mUserLru.get(i);
18397                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18398                if (oldUss == null) {
18399                    // Shouldn't happen, but be sane if it does.
18400                    mUserLru.remove(i);
18401                    num--;
18402                    continue;
18403                }
18404                if (oldUss.mState == UserStartedState.STATE_STOPPING
18405                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18406                    // This user is already stopping, doesn't count.
18407                    num--;
18408                    i++;
18409                    continue;
18410                }
18411                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18412                    // Owner and current can't be stopped, but count as running.
18413                    i++;
18414                    continue;
18415                }
18416                // This is a user to be stopped.
18417                stopUserLocked(oldUserId, null);
18418                num--;
18419                i++;
18420            }
18421        }
18422    }
18423
18424    @Override
18425    public int stopUser(final int userId, final IStopUserCallback callback) {
18426        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18427                != PackageManager.PERMISSION_GRANTED) {
18428            String msg = "Permission Denial: switchUser() from pid="
18429                    + Binder.getCallingPid()
18430                    + ", uid=" + Binder.getCallingUid()
18431                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18432            Slog.w(TAG, msg);
18433            throw new SecurityException(msg);
18434        }
18435        if (userId <= 0) {
18436            throw new IllegalArgumentException("Can't stop primary user " + userId);
18437        }
18438        synchronized (this) {
18439            return stopUserLocked(userId, callback);
18440        }
18441    }
18442
18443    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18444        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18445        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18446            return ActivityManager.USER_OP_IS_CURRENT;
18447        }
18448
18449        final UserStartedState uss = mStartedUsers.get(userId);
18450        if (uss == null) {
18451            // User is not started, nothing to do...  but we do need to
18452            // callback if requested.
18453            if (callback != null) {
18454                mHandler.post(new Runnable() {
18455                    @Override
18456                    public void run() {
18457                        try {
18458                            callback.userStopped(userId);
18459                        } catch (RemoteException e) {
18460                        }
18461                    }
18462                });
18463            }
18464            return ActivityManager.USER_OP_SUCCESS;
18465        }
18466
18467        if (callback != null) {
18468            uss.mStopCallbacks.add(callback);
18469        }
18470
18471        if (uss.mState != UserStartedState.STATE_STOPPING
18472                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18473            uss.mState = UserStartedState.STATE_STOPPING;
18474            updateStartedUserArrayLocked();
18475
18476            long ident = Binder.clearCallingIdentity();
18477            try {
18478                // We are going to broadcast ACTION_USER_STOPPING and then
18479                // once that is done send a final ACTION_SHUTDOWN and then
18480                // stop the user.
18481                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18482                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18483                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18484                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18485                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18486                // This is the result receiver for the final shutdown broadcast.
18487                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18488                    @Override
18489                    public void performReceive(Intent intent, int resultCode, String data,
18490                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18491                        finishUserStop(uss);
18492                    }
18493                };
18494                // This is the result receiver for the initial stopping broadcast.
18495                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18496                    @Override
18497                    public void performReceive(Intent intent, int resultCode, String data,
18498                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18499                        // On to the next.
18500                        synchronized (ActivityManagerService.this) {
18501                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18502                                // Whoops, we are being started back up.  Abort, abort!
18503                                return;
18504                            }
18505                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18506                        }
18507                        mBatteryStatsService.noteEvent(
18508                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18509                                Integer.toString(userId), userId);
18510                        mSystemServiceManager.stopUser(userId);
18511                        broadcastIntentLocked(null, null, shutdownIntent,
18512                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18513                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18514                    }
18515                };
18516                // Kick things off.
18517                broadcastIntentLocked(null, null, stoppingIntent,
18518                        null, stoppingReceiver, 0, null, null,
18519                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18520                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18521            } finally {
18522                Binder.restoreCallingIdentity(ident);
18523            }
18524        }
18525
18526        return ActivityManager.USER_OP_SUCCESS;
18527    }
18528
18529    void finishUserStop(UserStartedState uss) {
18530        final int userId = uss.mHandle.getIdentifier();
18531        boolean stopped;
18532        ArrayList<IStopUserCallback> callbacks;
18533        synchronized (this) {
18534            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18535            if (mStartedUsers.get(userId) != uss) {
18536                stopped = false;
18537            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18538                stopped = false;
18539            } else {
18540                stopped = true;
18541                // User can no longer run.
18542                mStartedUsers.remove(userId);
18543                mUserLru.remove(Integer.valueOf(userId));
18544                updateStartedUserArrayLocked();
18545
18546                // Clean up all state and processes associated with the user.
18547                // Kill all the processes for the user.
18548                forceStopUserLocked(userId, "finish user");
18549            }
18550
18551            // Explicitly remove the old information in mRecentTasks.
18552            removeRecentTasksForUserLocked(userId);
18553        }
18554
18555        for (int i=0; i<callbacks.size(); i++) {
18556            try {
18557                if (stopped) callbacks.get(i).userStopped(userId);
18558                else callbacks.get(i).userStopAborted(userId);
18559            } catch (RemoteException e) {
18560            }
18561        }
18562
18563        if (stopped) {
18564            mSystemServiceManager.cleanupUser(userId);
18565            synchronized (this) {
18566                mStackSupervisor.removeUserLocked(userId);
18567            }
18568        }
18569    }
18570
18571    @Override
18572    public UserInfo getCurrentUser() {
18573        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18574                != PackageManager.PERMISSION_GRANTED) && (
18575                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18576                != PackageManager.PERMISSION_GRANTED)) {
18577            String msg = "Permission Denial: getCurrentUser() from pid="
18578                    + Binder.getCallingPid()
18579                    + ", uid=" + Binder.getCallingUid()
18580                    + " requires " + INTERACT_ACROSS_USERS;
18581            Slog.w(TAG, msg);
18582            throw new SecurityException(msg);
18583        }
18584        synchronized (this) {
18585            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18586            return getUserManagerLocked().getUserInfo(userId);
18587        }
18588    }
18589
18590    int getCurrentUserIdLocked() {
18591        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18592    }
18593
18594    @Override
18595    public boolean isUserRunning(int userId, boolean orStopped) {
18596        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18597                != PackageManager.PERMISSION_GRANTED) {
18598            String msg = "Permission Denial: isUserRunning() from pid="
18599                    + Binder.getCallingPid()
18600                    + ", uid=" + Binder.getCallingUid()
18601                    + " requires " + INTERACT_ACROSS_USERS;
18602            Slog.w(TAG, msg);
18603            throw new SecurityException(msg);
18604        }
18605        synchronized (this) {
18606            return isUserRunningLocked(userId, orStopped);
18607        }
18608    }
18609
18610    boolean isUserRunningLocked(int userId, boolean orStopped) {
18611        UserStartedState state = mStartedUsers.get(userId);
18612        if (state == null) {
18613            return false;
18614        }
18615        if (orStopped) {
18616            return true;
18617        }
18618        return state.mState != UserStartedState.STATE_STOPPING
18619                && state.mState != UserStartedState.STATE_SHUTDOWN;
18620    }
18621
18622    @Override
18623    public int[] getRunningUserIds() {
18624        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18625                != PackageManager.PERMISSION_GRANTED) {
18626            String msg = "Permission Denial: isUserRunning() from pid="
18627                    + Binder.getCallingPid()
18628                    + ", uid=" + Binder.getCallingUid()
18629                    + " requires " + INTERACT_ACROSS_USERS;
18630            Slog.w(TAG, msg);
18631            throw new SecurityException(msg);
18632        }
18633        synchronized (this) {
18634            return mStartedUserArray;
18635        }
18636    }
18637
18638    private void updateStartedUserArrayLocked() {
18639        int num = 0;
18640        for (int i=0; i<mStartedUsers.size();  i++) {
18641            UserStartedState uss = mStartedUsers.valueAt(i);
18642            // This list does not include stopping users.
18643            if (uss.mState != UserStartedState.STATE_STOPPING
18644                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18645                num++;
18646            }
18647        }
18648        mStartedUserArray = new int[num];
18649        num = 0;
18650        for (int i=0; i<mStartedUsers.size();  i++) {
18651            UserStartedState uss = mStartedUsers.valueAt(i);
18652            if (uss.mState != UserStartedState.STATE_STOPPING
18653                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18654                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18655                num++;
18656            }
18657        }
18658    }
18659
18660    @Override
18661    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18662        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18663                != PackageManager.PERMISSION_GRANTED) {
18664            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18665                    + Binder.getCallingPid()
18666                    + ", uid=" + Binder.getCallingUid()
18667                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18668            Slog.w(TAG, msg);
18669            throw new SecurityException(msg);
18670        }
18671
18672        mUserSwitchObservers.register(observer);
18673    }
18674
18675    @Override
18676    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18677        mUserSwitchObservers.unregister(observer);
18678    }
18679
18680    private boolean userExists(int userId) {
18681        if (userId == 0) {
18682            return true;
18683        }
18684        UserManagerService ums = getUserManagerLocked();
18685        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18686    }
18687
18688    int[] getUsersLocked() {
18689        UserManagerService ums = getUserManagerLocked();
18690        return ums != null ? ums.getUserIds() : new int[] { 0 };
18691    }
18692
18693    UserManagerService getUserManagerLocked() {
18694        if (mUserManager == null) {
18695            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
18696            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
18697        }
18698        return mUserManager;
18699    }
18700
18701    private int applyUserId(int uid, int userId) {
18702        return UserHandle.getUid(userId, uid);
18703    }
18704
18705    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18706        if (info == null) return null;
18707        ApplicationInfo newInfo = new ApplicationInfo(info);
18708        newInfo.uid = applyUserId(info.uid, userId);
18709        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18710                + info.packageName;
18711        return newInfo;
18712    }
18713
18714    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18715        if (aInfo == null
18716                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18717            return aInfo;
18718        }
18719
18720        ActivityInfo info = new ActivityInfo(aInfo);
18721        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18722        return info;
18723    }
18724
18725    private final class LocalService extends ActivityManagerInternal {
18726        @Override
18727        public void goingToSleep() {
18728            ActivityManagerService.this.goingToSleep();
18729        }
18730
18731        @Override
18732        public void wakingUp() {
18733            ActivityManagerService.this.wakingUp();
18734        }
18735
18736        @Override
18737        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18738                String processName, String abiOverride, int uid, Runnable crashHandler) {
18739            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18740                    processName, abiOverride, uid, crashHandler);
18741        }
18742    }
18743
18744    /**
18745     * An implementation of IAppTask, that allows an app to manage its own tasks via
18746     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18747     * only the process that calls getAppTasks() can call the AppTask methods.
18748     */
18749    class AppTaskImpl extends IAppTask.Stub {
18750        private int mTaskId;
18751        private int mCallingUid;
18752
18753        public AppTaskImpl(int taskId, int callingUid) {
18754            mTaskId = taskId;
18755            mCallingUid = callingUid;
18756        }
18757
18758        private void checkCaller() {
18759            if (mCallingUid != Binder.getCallingUid()) {
18760                throw new SecurityException("Caller " + mCallingUid
18761                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18762            }
18763        }
18764
18765        @Override
18766        public void finishAndRemoveTask() {
18767            checkCaller();
18768
18769            synchronized (ActivityManagerService.this) {
18770                long origId = Binder.clearCallingIdentity();
18771                try {
18772                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18773                    if (tr == null) {
18774                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18775                    }
18776                    // Only kill the process if we are not a new document
18777                    int flags = tr.getBaseIntent().getFlags();
18778                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
18779                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
18780                    removeTaskByIdLocked(mTaskId,
18781                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
18782                } finally {
18783                    Binder.restoreCallingIdentity(origId);
18784                }
18785            }
18786        }
18787
18788        @Override
18789        public ActivityManager.RecentTaskInfo getTaskInfo() {
18790            checkCaller();
18791
18792            synchronized (ActivityManagerService.this) {
18793                long origId = Binder.clearCallingIdentity();
18794                try {
18795                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18796                    if (tr == null) {
18797                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18798                    }
18799                    return createRecentTaskInfoFromTaskRecord(tr);
18800                } finally {
18801                    Binder.restoreCallingIdentity(origId);
18802                }
18803            }
18804        }
18805
18806        @Override
18807        public void moveToFront() {
18808            checkCaller();
18809
18810            final TaskRecord tr;
18811            synchronized (ActivityManagerService.this) {
18812                tr = recentTaskForIdLocked(mTaskId);
18813                if (tr == null) {
18814                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18815                }
18816                if (tr.getRootActivity() != null) {
18817                    long origId = Binder.clearCallingIdentity();
18818                    try {
18819                        moveTaskToFrontLocked(tr.taskId, 0, null);
18820                        return;
18821                    } finally {
18822                        Binder.restoreCallingIdentity(origId);
18823                    }
18824                }
18825            }
18826
18827            startActivityFromRecentsInner(tr.taskId, null);
18828        }
18829
18830        @Override
18831        public int startActivity(IBinder whoThread, String callingPackage,
18832                Intent intent, String resolvedType, Bundle options) {
18833            checkCaller();
18834
18835            int callingUser = UserHandle.getCallingUserId();
18836            TaskRecord tr;
18837            IApplicationThread appThread;
18838            synchronized (ActivityManagerService.this) {
18839                tr = recentTaskForIdLocked(mTaskId);
18840                if (tr == null) {
18841                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18842                }
18843                appThread = ApplicationThreadNative.asInterface(whoThread);
18844                if (appThread == null) {
18845                    throw new IllegalArgumentException("Bad app thread " + appThread);
18846                }
18847            }
18848            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
18849                    resolvedType, null, null, null, null, 0, 0, null, null,
18850                    null, options, callingUser, null, tr);
18851        }
18852
18853        @Override
18854        public void setExcludeFromRecents(boolean exclude) {
18855            checkCaller();
18856
18857            synchronized (ActivityManagerService.this) {
18858                long origId = Binder.clearCallingIdentity();
18859                try {
18860                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18861                    if (tr == null) {
18862                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18863                    }
18864                    Intent intent = tr.getBaseIntent();
18865                    if (exclude) {
18866                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18867                    } else {
18868                        intent.setFlags(intent.getFlags()
18869                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18870                    }
18871                } finally {
18872                    Binder.restoreCallingIdentity(origId);
18873                }
18874            }
18875        }
18876    }
18877}
18878