ActivityManagerService.java revision 023b6812abbca465773acd6141ff672d525a83ee
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 mCallFinishBooting = false;
892    boolean mBootAnimationComplete = false;
893    boolean mWaitingUpdate = false;
894    boolean mDidUpdate = false;
895    boolean mOnBattery = false;
896    boolean mLaunchWarningShown = false;
897
898    Context mContext;
899
900    int mFactoryTest;
901
902    boolean mCheckedForSetup;
903
904    /**
905     * The time at which we will allow normal application switches again,
906     * after a call to {@link #stopAppSwitches()}.
907     */
908    long mAppSwitchesAllowedTime;
909
910    /**
911     * This is set to true after the first switch after mAppSwitchesAllowedTime
912     * is set; any switches after that will clear the time.
913     */
914    boolean mDidAppSwitch;
915
916    /**
917     * Last time (in realtime) at which we checked for power usage.
918     */
919    long mLastPowerCheckRealtime;
920
921    /**
922     * Last time (in uptime) at which we checked for power usage.
923     */
924    long mLastPowerCheckUptime;
925
926    /**
927     * Set while we are wanting to sleep, to prevent any
928     * activities from being started/resumed.
929     */
930    private boolean mSleeping = false;
931
932    /**
933     * Set while we are running a voice interaction.  This overrides
934     * sleeping while it is active.
935     */
936    private boolean mRunningVoice = false;
937
938    /**
939     * State of external calls telling us if the device is asleep.
940     */
941    private boolean mWentToSleep = false;
942
943    /**
944     * State of external call telling us if the lock screen is shown.
945     */
946    private boolean mLockScreenShown = false;
947
948    /**
949     * Set if we are shutting down the system, similar to sleeping.
950     */
951    boolean mShuttingDown = false;
952
953    /**
954     * Current sequence id for oom_adj computation traversal.
955     */
956    int mAdjSeq = 0;
957
958    /**
959     * Current sequence id for process LRU updating.
960     */
961    int mLruSeq = 0;
962
963    /**
964     * Keep track of the non-cached/empty process we last found, to help
965     * determine how to distribute cached/empty processes next time.
966     */
967    int mNumNonCachedProcs = 0;
968
969    /**
970     * Keep track of the number of cached hidden procs, to balance oom adj
971     * distribution between those and empty procs.
972     */
973    int mNumCachedHiddenProcs = 0;
974
975    /**
976     * Keep track of the number of service processes we last found, to
977     * determine on the next iteration which should be B services.
978     */
979    int mNumServiceProcs = 0;
980    int mNewNumAServiceProcs = 0;
981    int mNewNumServiceProcs = 0;
982
983    /**
984     * Allow the current computed overall memory level of the system to go down?
985     * This is set to false when we are killing processes for reasons other than
986     * memory management, so that the now smaller process list will not be taken as
987     * an indication that memory is tighter.
988     */
989    boolean mAllowLowerMemLevel = false;
990
991    /**
992     * The last computed memory level, for holding when we are in a state that
993     * processes are going away for other reasons.
994     */
995    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
996
997    /**
998     * The last total number of process we have, to determine if changes actually look
999     * like a shrinking number of process due to lower RAM.
1000     */
1001    int mLastNumProcesses;
1002
1003    /**
1004     * The uptime of the last time we performed idle maintenance.
1005     */
1006    long mLastIdleTime = SystemClock.uptimeMillis();
1007
1008    /**
1009     * Total time spent with RAM that has been added in the past since the last idle time.
1010     */
1011    long mLowRamTimeSinceLastIdle = 0;
1012
1013    /**
1014     * If RAM is currently low, when that horrible situation started.
1015     */
1016    long mLowRamStartTime = 0;
1017
1018    /**
1019     * For reporting to battery stats the current top application.
1020     */
1021    private String mCurResumedPackage = null;
1022    private int mCurResumedUid = -1;
1023
1024    /**
1025     * For reporting to battery stats the apps currently running foreground
1026     * service.  The ProcessMap is package/uid tuples; each of these contain
1027     * an array of the currently foreground processes.
1028     */
1029    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1030            = new ProcessMap<ArrayList<ProcessRecord>>();
1031
1032    /**
1033     * This is set if we had to do a delayed dexopt of an app before launching
1034     * it, to increase the ANR timeouts in that case.
1035     */
1036    boolean mDidDexOpt;
1037
1038    /**
1039     * Set if the systemServer made a call to enterSafeMode.
1040     */
1041    boolean mSafeMode;
1042
1043    String mDebugApp = null;
1044    boolean mWaitForDebugger = false;
1045    boolean mDebugTransient = false;
1046    String mOrigDebugApp = null;
1047    boolean mOrigWaitForDebugger = false;
1048    boolean mAlwaysFinishActivities = false;
1049    IActivityController mController = null;
1050    String mProfileApp = null;
1051    ProcessRecord mProfileProc = null;
1052    String mProfileFile;
1053    ParcelFileDescriptor mProfileFd;
1054    int mSamplingInterval = 0;
1055    boolean mAutoStopProfiler = false;
1056    int mProfileType = 0;
1057    String mOpenGlTraceApp = null;
1058
1059    static class ProcessChangeItem {
1060        static final int CHANGE_ACTIVITIES = 1<<0;
1061        static final int CHANGE_PROCESS_STATE = 1<<1;
1062        int changes;
1063        int uid;
1064        int pid;
1065        int processState;
1066        boolean foregroundActivities;
1067    }
1068
1069    final RemoteCallbackList<IProcessObserver> mProcessObservers
1070            = new RemoteCallbackList<IProcessObserver>();
1071    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1072
1073    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1074            = new ArrayList<ProcessChangeItem>();
1075    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1076            = new ArrayList<ProcessChangeItem>();
1077
1078    /**
1079     * Runtime CPU use collection thread.  This object's lock is used to
1080     * perform synchronization with the thread (notifying it to run).
1081     */
1082    final Thread mProcessCpuThread;
1083
1084    /**
1085     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1086     * Must acquire this object's lock when accessing it.
1087     * NOTE: this lock will be held while doing long operations (trawling
1088     * through all processes in /proc), so it should never be acquired by
1089     * any critical paths such as when holding the main activity manager lock.
1090     */
1091    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1092            MONITOR_THREAD_CPU_USAGE);
1093    final AtomicLong mLastCpuTime = new AtomicLong(0);
1094    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1095
1096    long mLastWriteTime = 0;
1097
1098    /**
1099     * Used to retain an update lock when the foreground activity is in
1100     * immersive mode.
1101     */
1102    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1103
1104    /**
1105     * Set to true after the system has finished booting.
1106     */
1107    boolean mBooted = false;
1108
1109    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1110    int mProcessLimitOverride = -1;
1111
1112    WindowManagerService mWindowManager;
1113
1114    final ActivityThread mSystemThread;
1115
1116    // Holds the current foreground user's id
1117    int mCurrentUserId = 0;
1118    // Holds the target user's id during a user switch
1119    int mTargetUserId = UserHandle.USER_NULL;
1120    // If there are multiple profiles for the current user, their ids are here
1121    // Currently only the primary user can have managed profiles
1122    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1123
1124    /**
1125     * Mapping from each known user ID to the profile group ID it is associated with.
1126     */
1127    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1128
1129    private UserManagerService mUserManager;
1130
1131    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1132        final ProcessRecord mApp;
1133        final int mPid;
1134        final IApplicationThread mAppThread;
1135
1136        AppDeathRecipient(ProcessRecord app, int pid,
1137                IApplicationThread thread) {
1138            if (localLOGV) Slog.v(
1139                TAG, "New death recipient " + this
1140                + " for thread " + thread.asBinder());
1141            mApp = app;
1142            mPid = pid;
1143            mAppThread = thread;
1144        }
1145
1146        @Override
1147        public void binderDied() {
1148            if (localLOGV) Slog.v(
1149                TAG, "Death received in " + this
1150                + " for thread " + mAppThread.asBinder());
1151            synchronized(ActivityManagerService.this) {
1152                appDiedLocked(mApp, mPid, mAppThread);
1153            }
1154        }
1155    }
1156
1157    static final int SHOW_ERROR_MSG = 1;
1158    static final int SHOW_NOT_RESPONDING_MSG = 2;
1159    static final int SHOW_FACTORY_ERROR_MSG = 3;
1160    static final int UPDATE_CONFIGURATION_MSG = 4;
1161    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1162    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1163    static final int SERVICE_TIMEOUT_MSG = 12;
1164    static final int UPDATE_TIME_ZONE = 13;
1165    static final int SHOW_UID_ERROR_MSG = 14;
1166    static final int IM_FEELING_LUCKY_MSG = 15;
1167    static final int PROC_START_TIMEOUT_MSG = 20;
1168    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1169    static final int KILL_APPLICATION_MSG = 22;
1170    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1171    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1172    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1173    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1174    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1175    static final int CLEAR_DNS_CACHE_MSG = 28;
1176    static final int UPDATE_HTTP_PROXY_MSG = 29;
1177    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1178    static final int DISPATCH_PROCESSES_CHANGED = 31;
1179    static final int DISPATCH_PROCESS_DIED = 32;
1180    static final int REPORT_MEM_USAGE_MSG = 33;
1181    static final int REPORT_USER_SWITCH_MSG = 34;
1182    static final int CONTINUE_USER_SWITCH_MSG = 35;
1183    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1184    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1185    static final int PERSIST_URI_GRANTS_MSG = 38;
1186    static final int REQUEST_ALL_PSS_MSG = 39;
1187    static final int START_PROFILES_MSG = 40;
1188    static final int UPDATE_TIME = 41;
1189    static final int SYSTEM_USER_START_MSG = 42;
1190    static final int SYSTEM_USER_CURRENT_MSG = 43;
1191    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1192    static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45;
1193    static final int START_USER_SWITCH_MSG = 46;
1194
1195    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1196    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1197    static final int FIRST_COMPAT_MODE_MSG = 300;
1198    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1199
1200    AlertDialog mUidAlert;
1201    CompatModeDialog mCompatModeDialog;
1202    long mLastMemUsageReportTime = 0;
1203
1204    private LockToAppRequestDialog mLockToAppRequest;
1205
1206    /**
1207     * Flag whether the current user is a "monkey", i.e. whether
1208     * the UI is driven by a UI automation tool.
1209     */
1210    private boolean mUserIsMonkey;
1211
1212    /** Flag whether the device has a Recents UI */
1213    boolean mHasRecents;
1214
1215    /** The dimensions of the thumbnails in the Recents UI. */
1216    int mThumbnailWidth;
1217    int mThumbnailHeight;
1218
1219    final ServiceThread mHandlerThread;
1220    final MainHandler mHandler;
1221
1222    final class MainHandler extends Handler {
1223        public MainHandler(Looper looper) {
1224            super(looper, null, true);
1225        }
1226
1227        @Override
1228        public void handleMessage(Message msg) {
1229            switch (msg.what) {
1230            case SHOW_ERROR_MSG: {
1231                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1232                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1233                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1234                synchronized (ActivityManagerService.this) {
1235                    ProcessRecord proc = (ProcessRecord)data.get("app");
1236                    AppErrorResult res = (AppErrorResult) data.get("result");
1237                    if (proc != null && proc.crashDialog != null) {
1238                        Slog.e(TAG, "App already has crash dialog: " + proc);
1239                        if (res != null) {
1240                            res.set(0);
1241                        }
1242                        return;
1243                    }
1244                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1245                            >= Process.FIRST_APPLICATION_UID
1246                            && proc.pid != MY_PID);
1247                    for (int userId : mCurrentProfileIds) {
1248                        isBackground &= (proc.userId != userId);
1249                    }
1250                    if (isBackground && !showBackground) {
1251                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1252                        if (res != null) {
1253                            res.set(0);
1254                        }
1255                        return;
1256                    }
1257                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1258                        Dialog d = new AppErrorDialog(mContext,
1259                                ActivityManagerService.this, res, proc);
1260                        d.show();
1261                        proc.crashDialog = d;
1262                    } else {
1263                        // The device is asleep, so just pretend that the user
1264                        // saw a crash dialog and hit "force quit".
1265                        if (res != null) {
1266                            res.set(0);
1267                        }
1268                    }
1269                }
1270
1271                ensureBootCompleted();
1272            } break;
1273            case SHOW_NOT_RESPONDING_MSG: {
1274                synchronized (ActivityManagerService.this) {
1275                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1276                    ProcessRecord proc = (ProcessRecord)data.get("app");
1277                    if (proc != null && proc.anrDialog != null) {
1278                        Slog.e(TAG, "App already has anr dialog: " + proc);
1279                        return;
1280                    }
1281
1282                    Intent intent = new Intent("android.intent.action.ANR");
1283                    if (!mProcessesReady) {
1284                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1285                                | Intent.FLAG_RECEIVER_FOREGROUND);
1286                    }
1287                    broadcastIntentLocked(null, null, intent,
1288                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1289                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1290
1291                    if (mShowDialogs) {
1292                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1293                                mContext, proc, (ActivityRecord)data.get("activity"),
1294                                msg.arg1 != 0);
1295                        d.show();
1296                        proc.anrDialog = d;
1297                    } else {
1298                        // Just kill the app if there is no dialog to be shown.
1299                        killAppAtUsersRequest(proc, null);
1300                    }
1301                }
1302
1303                ensureBootCompleted();
1304            } break;
1305            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1306                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1307                synchronized (ActivityManagerService.this) {
1308                    ProcessRecord proc = (ProcessRecord) data.get("app");
1309                    if (proc == null) {
1310                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1311                        break;
1312                    }
1313                    if (proc.crashDialog != null) {
1314                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1315                        return;
1316                    }
1317                    AppErrorResult res = (AppErrorResult) data.get("result");
1318                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1319                        Dialog d = new StrictModeViolationDialog(mContext,
1320                                ActivityManagerService.this, res, proc);
1321                        d.show();
1322                        proc.crashDialog = d;
1323                    } else {
1324                        // The device is asleep, so just pretend that the user
1325                        // saw a crash dialog and hit "force quit".
1326                        res.set(0);
1327                    }
1328                }
1329                ensureBootCompleted();
1330            } break;
1331            case SHOW_FACTORY_ERROR_MSG: {
1332                Dialog d = new FactoryErrorDialog(
1333                    mContext, msg.getData().getCharSequence("msg"));
1334                d.show();
1335                ensureBootCompleted();
1336            } break;
1337            case UPDATE_CONFIGURATION_MSG: {
1338                final ContentResolver resolver = mContext.getContentResolver();
1339                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1340            } break;
1341            case GC_BACKGROUND_PROCESSES_MSG: {
1342                synchronized (ActivityManagerService.this) {
1343                    performAppGcsIfAppropriateLocked();
1344                }
1345            } break;
1346            case WAIT_FOR_DEBUGGER_MSG: {
1347                synchronized (ActivityManagerService.this) {
1348                    ProcessRecord app = (ProcessRecord)msg.obj;
1349                    if (msg.arg1 != 0) {
1350                        if (!app.waitedForDebugger) {
1351                            Dialog d = new AppWaitingForDebuggerDialog(
1352                                    ActivityManagerService.this,
1353                                    mContext, app);
1354                            app.waitDialog = d;
1355                            app.waitedForDebugger = true;
1356                            d.show();
1357                        }
1358                    } else {
1359                        if (app.waitDialog != null) {
1360                            app.waitDialog.dismiss();
1361                            app.waitDialog = null;
1362                        }
1363                    }
1364                }
1365            } break;
1366            case SERVICE_TIMEOUT_MSG: {
1367                if (mDidDexOpt) {
1368                    mDidDexOpt = false;
1369                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1370                    nmsg.obj = msg.obj;
1371                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1372                    return;
1373                }
1374                mServices.serviceTimeout((ProcessRecord)msg.obj);
1375            } break;
1376            case UPDATE_TIME_ZONE: {
1377                synchronized (ActivityManagerService.this) {
1378                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1379                        ProcessRecord r = mLruProcesses.get(i);
1380                        if (r.thread != null) {
1381                            try {
1382                                r.thread.updateTimeZone();
1383                            } catch (RemoteException ex) {
1384                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1385                            }
1386                        }
1387                    }
1388                }
1389            } break;
1390            case CLEAR_DNS_CACHE_MSG: {
1391                synchronized (ActivityManagerService.this) {
1392                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1393                        ProcessRecord r = mLruProcesses.get(i);
1394                        if (r.thread != null) {
1395                            try {
1396                                r.thread.clearDnsCache();
1397                            } catch (RemoteException ex) {
1398                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1399                            }
1400                        }
1401                    }
1402                }
1403            } break;
1404            case UPDATE_HTTP_PROXY_MSG: {
1405                ProxyInfo proxy = (ProxyInfo)msg.obj;
1406                String host = "";
1407                String port = "";
1408                String exclList = "";
1409                Uri pacFileUrl = Uri.EMPTY;
1410                if (proxy != null) {
1411                    host = proxy.getHost();
1412                    port = Integer.toString(proxy.getPort());
1413                    exclList = proxy.getExclusionListAsString();
1414                    pacFileUrl = proxy.getPacFileUrl();
1415                }
1416                synchronized (ActivityManagerService.this) {
1417                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1418                        ProcessRecord r = mLruProcesses.get(i);
1419                        if (r.thread != null) {
1420                            try {
1421                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1422                            } catch (RemoteException ex) {
1423                                Slog.w(TAG, "Failed to update http proxy for: " +
1424                                        r.info.processName);
1425                            }
1426                        }
1427                    }
1428                }
1429            } break;
1430            case SHOW_UID_ERROR_MSG: {
1431                String title = "System UIDs Inconsistent";
1432                String text = "UIDs on the system are inconsistent, you need to wipe your"
1433                        + " data partition or your device will be unstable.";
1434                Log.e(TAG, title + ": " + text);
1435                if (mShowDialogs) {
1436                    // XXX This is a temporary dialog, no need to localize.
1437                    AlertDialog d = new BaseErrorDialog(mContext);
1438                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1439                    d.setCancelable(false);
1440                    d.setTitle(title);
1441                    d.setMessage(text);
1442                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1443                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1444                    mUidAlert = d;
1445                    d.show();
1446                }
1447            } break;
1448            case IM_FEELING_LUCKY_MSG: {
1449                if (mUidAlert != null) {
1450                    mUidAlert.dismiss();
1451                    mUidAlert = null;
1452                }
1453            } break;
1454            case PROC_START_TIMEOUT_MSG: {
1455                if (mDidDexOpt) {
1456                    mDidDexOpt = false;
1457                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1458                    nmsg.obj = msg.obj;
1459                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1460                    return;
1461                }
1462                ProcessRecord app = (ProcessRecord)msg.obj;
1463                synchronized (ActivityManagerService.this) {
1464                    processStartTimedOutLocked(app);
1465                }
1466            } break;
1467            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1468                synchronized (ActivityManagerService.this) {
1469                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1470                }
1471            } break;
1472            case KILL_APPLICATION_MSG: {
1473                synchronized (ActivityManagerService.this) {
1474                    int appid = msg.arg1;
1475                    boolean restart = (msg.arg2 == 1);
1476                    Bundle bundle = (Bundle)msg.obj;
1477                    String pkg = bundle.getString("pkg");
1478                    String reason = bundle.getString("reason");
1479                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1480                            false, UserHandle.USER_ALL, reason);
1481                }
1482            } break;
1483            case FINALIZE_PENDING_INTENT_MSG: {
1484                ((PendingIntentRecord)msg.obj).completeFinalize();
1485            } break;
1486            case POST_HEAVY_NOTIFICATION_MSG: {
1487                INotificationManager inm = NotificationManager.getService();
1488                if (inm == null) {
1489                    return;
1490                }
1491
1492                ActivityRecord root = (ActivityRecord)msg.obj;
1493                ProcessRecord process = root.app;
1494                if (process == null) {
1495                    return;
1496                }
1497
1498                try {
1499                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1500                    String text = mContext.getString(R.string.heavy_weight_notification,
1501                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1502                    Notification notification = new Notification();
1503                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1504                    notification.when = 0;
1505                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1506                    notification.tickerText = text;
1507                    notification.defaults = 0; // please be quiet
1508                    notification.sound = null;
1509                    notification.vibrate = null;
1510                    notification.color = mContext.getResources().getColor(
1511                            com.android.internal.R.color.system_notification_accent_color);
1512                    notification.setLatestEventInfo(context, text,
1513                            mContext.getText(R.string.heavy_weight_notification_detail),
1514                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1515                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1516                                    new UserHandle(root.userId)));
1517
1518                    try {
1519                        int[] outId = new int[1];
1520                        inm.enqueueNotificationWithTag("android", "android", null,
1521                                R.string.heavy_weight_notification,
1522                                notification, outId, root.userId);
1523                    } catch (RuntimeException e) {
1524                        Slog.w(ActivityManagerService.TAG,
1525                                "Error showing notification for heavy-weight app", e);
1526                    } catch (RemoteException e) {
1527                    }
1528                } catch (NameNotFoundException e) {
1529                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1530                }
1531            } break;
1532            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1533                INotificationManager inm = NotificationManager.getService();
1534                if (inm == null) {
1535                    return;
1536                }
1537                try {
1538                    inm.cancelNotificationWithTag("android", null,
1539                            R.string.heavy_weight_notification,  msg.arg1);
1540                } catch (RuntimeException e) {
1541                    Slog.w(ActivityManagerService.TAG,
1542                            "Error canceling notification for service", e);
1543                } catch (RemoteException e) {
1544                }
1545            } break;
1546            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1547                synchronized (ActivityManagerService.this) {
1548                    checkExcessivePowerUsageLocked(true);
1549                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1550                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1551                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1552                }
1553            } break;
1554            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1555                synchronized (ActivityManagerService.this) {
1556                    ActivityRecord ar = (ActivityRecord)msg.obj;
1557                    if (mCompatModeDialog != null) {
1558                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1559                                ar.info.applicationInfo.packageName)) {
1560                            return;
1561                        }
1562                        mCompatModeDialog.dismiss();
1563                        mCompatModeDialog = null;
1564                    }
1565                    if (ar != null && false) {
1566                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1567                                ar.packageName)) {
1568                            int mode = mCompatModePackages.computeCompatModeLocked(
1569                                    ar.info.applicationInfo);
1570                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1571                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1572                                mCompatModeDialog = new CompatModeDialog(
1573                                        ActivityManagerService.this, mContext,
1574                                        ar.info.applicationInfo);
1575                                mCompatModeDialog.show();
1576                            }
1577                        }
1578                    }
1579                }
1580                break;
1581            }
1582            case DISPATCH_PROCESSES_CHANGED: {
1583                dispatchProcessesChanged();
1584                break;
1585            }
1586            case DISPATCH_PROCESS_DIED: {
1587                final int pid = msg.arg1;
1588                final int uid = msg.arg2;
1589                dispatchProcessDied(pid, uid);
1590                break;
1591            }
1592            case REPORT_MEM_USAGE_MSG: {
1593                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1594                Thread thread = new Thread() {
1595                    @Override public void run() {
1596                        final SparseArray<ProcessMemInfo> infoMap
1597                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1598                        for (int i=0, N=memInfos.size(); i<N; i++) {
1599                            ProcessMemInfo mi = memInfos.get(i);
1600                            infoMap.put(mi.pid, mi);
1601                        }
1602                        updateCpuStatsNow();
1603                        synchronized (mProcessCpuTracker) {
1604                            final int N = mProcessCpuTracker.countStats();
1605                            for (int i=0; i<N; i++) {
1606                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1607                                if (st.vsize > 0) {
1608                                    long pss = Debug.getPss(st.pid, null);
1609                                    if (pss > 0) {
1610                                        if (infoMap.indexOfKey(st.pid) < 0) {
1611                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1612                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1613                                            mi.pss = pss;
1614                                            memInfos.add(mi);
1615                                        }
1616                                    }
1617                                }
1618                            }
1619                        }
1620
1621                        long totalPss = 0;
1622                        for (int i=0, N=memInfos.size(); i<N; i++) {
1623                            ProcessMemInfo mi = memInfos.get(i);
1624                            if (mi.pss == 0) {
1625                                mi.pss = Debug.getPss(mi.pid, null);
1626                            }
1627                            totalPss += mi.pss;
1628                        }
1629                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1630                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1631                                if (lhs.oomAdj != rhs.oomAdj) {
1632                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1633                                }
1634                                if (lhs.pss != rhs.pss) {
1635                                    return lhs.pss < rhs.pss ? 1 : -1;
1636                                }
1637                                return 0;
1638                            }
1639                        });
1640
1641                        StringBuilder tag = new StringBuilder(128);
1642                        StringBuilder stack = new StringBuilder(128);
1643                        tag.append("Low on memory -- ");
1644                        appendMemBucket(tag, totalPss, "total", false);
1645                        appendMemBucket(stack, totalPss, "total", true);
1646
1647                        StringBuilder logBuilder = new StringBuilder(1024);
1648                        logBuilder.append("Low on memory:\n");
1649
1650                        boolean firstLine = true;
1651                        int lastOomAdj = Integer.MIN_VALUE;
1652                        for (int i=0, N=memInfos.size(); i<N; i++) {
1653                            ProcessMemInfo mi = memInfos.get(i);
1654
1655                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1656                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1657                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1658                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1659                                if (lastOomAdj != mi.oomAdj) {
1660                                    lastOomAdj = mi.oomAdj;
1661                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1662                                        tag.append(" / ");
1663                                    }
1664                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1665                                        if (firstLine) {
1666                                            stack.append(":");
1667                                            firstLine = false;
1668                                        }
1669                                        stack.append("\n\t at ");
1670                                    } else {
1671                                        stack.append("$");
1672                                    }
1673                                } else {
1674                                    tag.append(" ");
1675                                    stack.append("$");
1676                                }
1677                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1678                                    appendMemBucket(tag, mi.pss, mi.name, false);
1679                                }
1680                                appendMemBucket(stack, mi.pss, mi.name, true);
1681                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1682                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1683                                    stack.append("(");
1684                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1685                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1686                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1687                                            stack.append(":");
1688                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1689                                        }
1690                                    }
1691                                    stack.append(")");
1692                                }
1693                            }
1694
1695                            logBuilder.append("  ");
1696                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1697                            logBuilder.append(' ');
1698                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1699                            logBuilder.append(' ');
1700                            ProcessList.appendRamKb(logBuilder, mi.pss);
1701                            logBuilder.append(" kB: ");
1702                            logBuilder.append(mi.name);
1703                            logBuilder.append(" (");
1704                            logBuilder.append(mi.pid);
1705                            logBuilder.append(") ");
1706                            logBuilder.append(mi.adjType);
1707                            logBuilder.append('\n');
1708                            if (mi.adjReason != null) {
1709                                logBuilder.append("                      ");
1710                                logBuilder.append(mi.adjReason);
1711                                logBuilder.append('\n');
1712                            }
1713                        }
1714
1715                        logBuilder.append("           ");
1716                        ProcessList.appendRamKb(logBuilder, totalPss);
1717                        logBuilder.append(" kB: TOTAL\n");
1718
1719                        long[] infos = new long[Debug.MEMINFO_COUNT];
1720                        Debug.getMemInfo(infos);
1721                        logBuilder.append("  MemInfo: ");
1722                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1723                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1724                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1725                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1726                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1727                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1728                            logBuilder.append("  ZRAM: ");
1729                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1730                            logBuilder.append(" kB RAM, ");
1731                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1732                            logBuilder.append(" kB swap total, ");
1733                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1734                            logBuilder.append(" kB swap free\n");
1735                        }
1736                        Slog.i(TAG, logBuilder.toString());
1737
1738                        StringBuilder dropBuilder = new StringBuilder(1024);
1739                        /*
1740                        StringWriter oomSw = new StringWriter();
1741                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1742                        StringWriter catSw = new StringWriter();
1743                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1744                        String[] emptyArgs = new String[] { };
1745                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1746                        oomPw.flush();
1747                        String oomString = oomSw.toString();
1748                        */
1749                        dropBuilder.append(stack);
1750                        dropBuilder.append('\n');
1751                        dropBuilder.append('\n');
1752                        dropBuilder.append(logBuilder);
1753                        dropBuilder.append('\n');
1754                        /*
1755                        dropBuilder.append(oomString);
1756                        dropBuilder.append('\n');
1757                        */
1758                        StringWriter catSw = new StringWriter();
1759                        synchronized (ActivityManagerService.this) {
1760                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1761                            String[] emptyArgs = new String[] { };
1762                            catPw.println();
1763                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1764                            catPw.println();
1765                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1766                                    false, false, null);
1767                            catPw.println();
1768                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1769                            catPw.flush();
1770                        }
1771                        dropBuilder.append(catSw.toString());
1772                        addErrorToDropBox("lowmem", null, "system_server", null,
1773                                null, tag.toString(), dropBuilder.toString(), null, null);
1774                        //Slog.i(TAG, "Sent to dropbox:");
1775                        //Slog.i(TAG, dropBuilder.toString());
1776                        synchronized (ActivityManagerService.this) {
1777                            long now = SystemClock.uptimeMillis();
1778                            if (mLastMemUsageReportTime < now) {
1779                                mLastMemUsageReportTime = now;
1780                            }
1781                        }
1782                    }
1783                };
1784                thread.start();
1785                break;
1786            }
1787            case START_USER_SWITCH_MSG: {
1788                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1789                break;
1790            }
1791            case REPORT_USER_SWITCH_MSG: {
1792                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1793                break;
1794            }
1795            case CONTINUE_USER_SWITCH_MSG: {
1796                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1797                break;
1798            }
1799            case USER_SWITCH_TIMEOUT_MSG: {
1800                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1801                break;
1802            }
1803            case IMMERSIVE_MODE_LOCK_MSG: {
1804                final boolean nextState = (msg.arg1 != 0);
1805                if (mUpdateLock.isHeld() != nextState) {
1806                    if (DEBUG_IMMERSIVE) {
1807                        final ActivityRecord r = (ActivityRecord) msg.obj;
1808                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1809                    }
1810                    if (nextState) {
1811                        mUpdateLock.acquire();
1812                    } else {
1813                        mUpdateLock.release();
1814                    }
1815                }
1816                break;
1817            }
1818            case PERSIST_URI_GRANTS_MSG: {
1819                writeGrantedUriPermissions();
1820                break;
1821            }
1822            case REQUEST_ALL_PSS_MSG: {
1823                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1824                break;
1825            }
1826            case START_PROFILES_MSG: {
1827                synchronized (ActivityManagerService.this) {
1828                    startProfilesLocked();
1829                }
1830                break;
1831            }
1832            case UPDATE_TIME: {
1833                synchronized (ActivityManagerService.this) {
1834                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1835                        ProcessRecord r = mLruProcesses.get(i);
1836                        if (r.thread != null) {
1837                            try {
1838                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1839                            } catch (RemoteException ex) {
1840                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1841                            }
1842                        }
1843                    }
1844                }
1845                break;
1846            }
1847            case SYSTEM_USER_START_MSG: {
1848                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1849                        Integer.toString(msg.arg1), msg.arg1);
1850                mSystemServiceManager.startUser(msg.arg1);
1851                break;
1852            }
1853            case SYSTEM_USER_CURRENT_MSG: {
1854                mBatteryStatsService.noteEvent(
1855                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1856                        Integer.toString(msg.arg2), msg.arg2);
1857                mBatteryStatsService.noteEvent(
1858                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1859                        Integer.toString(msg.arg1), msg.arg1);
1860                mSystemServiceManager.switchUser(msg.arg1);
1861                mLockToAppRequest.clearPrompt();
1862                break;
1863            }
1864            case ENTER_ANIMATION_COMPLETE_MSG: {
1865                synchronized (ActivityManagerService.this) {
1866                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1867                    if (r != null && r.app != null && r.app.thread != null) {
1868                        try {
1869                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1870                        } catch (RemoteException e) {
1871                        }
1872                    }
1873                }
1874                break;
1875            }
1876            case ENABLE_SCREEN_AFTER_BOOT_MSG: {
1877                enableScreenAfterBoot();
1878                break;
1879            }
1880            }
1881        }
1882    };
1883
1884    static final int COLLECT_PSS_BG_MSG = 1;
1885
1886    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1887        @Override
1888        public void handleMessage(Message msg) {
1889            switch (msg.what) {
1890            case COLLECT_PSS_BG_MSG: {
1891                long start = SystemClock.uptimeMillis();
1892                MemInfoReader memInfo = null;
1893                synchronized (ActivityManagerService.this) {
1894                    if (mFullPssPending) {
1895                        mFullPssPending = false;
1896                        memInfo = new MemInfoReader();
1897                    }
1898                }
1899                if (memInfo != null) {
1900                    updateCpuStatsNow();
1901                    long nativeTotalPss = 0;
1902                    synchronized (mProcessCpuTracker) {
1903                        final int N = mProcessCpuTracker.countStats();
1904                        for (int j=0; j<N; j++) {
1905                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1906                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1907                                // This is definitely an application process; skip it.
1908                                continue;
1909                            }
1910                            synchronized (mPidsSelfLocked) {
1911                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1912                                    // This is one of our own processes; skip it.
1913                                    continue;
1914                                }
1915                            }
1916                            nativeTotalPss += Debug.getPss(st.pid, null);
1917                        }
1918                    }
1919                    memInfo.readMemInfo();
1920                    synchronized (ActivityManagerService.this) {
1921                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1922                                + (SystemClock.uptimeMillis()-start) + "ms");
1923                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1924                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1925                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1926                                        +memInfo.getSlabSizeKb(),
1927                                nativeTotalPss);
1928                    }
1929                }
1930
1931                int i=0, num=0;
1932                long[] tmp = new long[1];
1933                do {
1934                    ProcessRecord proc;
1935                    int procState;
1936                    int pid;
1937                    synchronized (ActivityManagerService.this) {
1938                        if (i >= mPendingPssProcesses.size()) {
1939                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1940                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1941                            mPendingPssProcesses.clear();
1942                            return;
1943                        }
1944                        proc = mPendingPssProcesses.get(i);
1945                        procState = proc.pssProcState;
1946                        if (proc.thread != null && procState == proc.setProcState) {
1947                            pid = proc.pid;
1948                        } else {
1949                            proc = null;
1950                            pid = 0;
1951                        }
1952                        i++;
1953                    }
1954                    if (proc != null) {
1955                        long pss = Debug.getPss(pid, tmp);
1956                        synchronized (ActivityManagerService.this) {
1957                            if (proc.thread != null && proc.setProcState == procState
1958                                    && proc.pid == pid) {
1959                                num++;
1960                                proc.lastPssTime = SystemClock.uptimeMillis();
1961                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1962                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1963                                        + ": " + pss + " lastPss=" + proc.lastPss
1964                                        + " state=" + ProcessList.makeProcStateString(procState));
1965                                if (proc.initialIdlePss == 0) {
1966                                    proc.initialIdlePss = pss;
1967                                }
1968                                proc.lastPss = pss;
1969                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1970                                    proc.lastCachedPss = pss;
1971                                }
1972                            }
1973                        }
1974                    }
1975                } while (true);
1976            }
1977            }
1978        }
1979    };
1980
1981    /**
1982     * Monitor for package changes and update our internal state.
1983     */
1984    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1985        @Override
1986        public void onPackageRemoved(String packageName, int uid) {
1987            // Remove all tasks with activities in the specified package from the list of recent tasks
1988            synchronized (ActivityManagerService.this) {
1989                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1990                    TaskRecord tr = mRecentTasks.get(i);
1991                    ComponentName cn = tr.intent.getComponent();
1992                    if (cn != null && cn.getPackageName().equals(packageName)) {
1993                        // If the package name matches, remove the task and kill the process
1994                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1995                    }
1996                }
1997            }
1998        }
1999
2000        @Override
2001        public boolean onPackageChanged(String packageName, int uid, String[] components) {
2002            onPackageModified(packageName);
2003            return true;
2004        }
2005
2006        @Override
2007        public void onPackageModified(String packageName) {
2008            final PackageManager pm = mContext.getPackageManager();
2009            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
2010                    new ArrayList<Pair<Intent, Integer>>();
2011            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
2012            // Copy the list of recent tasks so that we don't hold onto the lock on
2013            // ActivityManagerService for long periods while checking if components exist.
2014            synchronized (ActivityManagerService.this) {
2015                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2016                    TaskRecord tr = mRecentTasks.get(i);
2017                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
2018                }
2019            }
2020            // Check the recent tasks and filter out all tasks with components that no longer exist.
2021            Intent tmpI = new Intent();
2022            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
2023                Pair<Intent, Integer> p = recentTaskIntents.get(i);
2024                ComponentName cn = p.first.getComponent();
2025                if (cn != null && cn.getPackageName().equals(packageName)) {
2026                    try {
2027                        // Add the task to the list to remove if the component no longer exists
2028                        tmpI.setComponent(cn);
2029                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
2030                            tasksToRemove.add(p.second);
2031                        }
2032                    } catch (Exception e) {}
2033                }
2034            }
2035            // Prune all the tasks with removed components from the list of recent tasks
2036            synchronized (ActivityManagerService.this) {
2037                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
2038                    // Remove the task but don't kill the process (since other components in that
2039                    // package may still be running and in the background)
2040                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
2041                }
2042            }
2043        }
2044
2045        @Override
2046        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2047            // Force stop the specified packages
2048            if (packages != null) {
2049                for (String pkg : packages) {
2050                    synchronized (ActivityManagerService.this) {
2051                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2052                                "finished booting")) {
2053                            return true;
2054                        }
2055                    }
2056                }
2057            }
2058            return false;
2059        }
2060    };
2061
2062    public void setSystemProcess() {
2063        try {
2064            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2065            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2066            ServiceManager.addService("meminfo", new MemBinder(this));
2067            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2068            ServiceManager.addService("dbinfo", new DbBinder(this));
2069            if (MONITOR_CPU_USAGE) {
2070                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2071            }
2072            ServiceManager.addService("permission", new PermissionController(this));
2073
2074            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2075                    "android", STOCK_PM_FLAGS);
2076            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2077
2078            synchronized (this) {
2079                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2080                app.persistent = true;
2081                app.pid = MY_PID;
2082                app.maxAdj = ProcessList.SYSTEM_ADJ;
2083                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2084                mProcessNames.put(app.processName, app.uid, app);
2085                synchronized (mPidsSelfLocked) {
2086                    mPidsSelfLocked.put(app.pid, app);
2087                }
2088                updateLruProcessLocked(app, false, null);
2089                updateOomAdjLocked();
2090            }
2091        } catch (PackageManager.NameNotFoundException e) {
2092            throw new RuntimeException(
2093                    "Unable to find android system package", e);
2094        }
2095    }
2096
2097    public void setWindowManager(WindowManagerService wm) {
2098        mWindowManager = wm;
2099        mStackSupervisor.setWindowManager(wm);
2100    }
2101
2102    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2103        mUsageStatsService = usageStatsManager;
2104    }
2105
2106    public void startObservingNativeCrashes() {
2107        final NativeCrashListener ncl = new NativeCrashListener(this);
2108        ncl.start();
2109    }
2110
2111    public IAppOpsService getAppOpsService() {
2112        return mAppOpsService;
2113    }
2114
2115    static class MemBinder extends Binder {
2116        ActivityManagerService mActivityManagerService;
2117        MemBinder(ActivityManagerService activityManagerService) {
2118            mActivityManagerService = activityManagerService;
2119        }
2120
2121        @Override
2122        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2123            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2124                    != PackageManager.PERMISSION_GRANTED) {
2125                pw.println("Permission Denial: can't dump meminfo from from pid="
2126                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2127                        + " without permission " + android.Manifest.permission.DUMP);
2128                return;
2129            }
2130
2131            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2132        }
2133    }
2134
2135    static class GraphicsBinder extends Binder {
2136        ActivityManagerService mActivityManagerService;
2137        GraphicsBinder(ActivityManagerService activityManagerService) {
2138            mActivityManagerService = activityManagerService;
2139        }
2140
2141        @Override
2142        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2143            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2144                    != PackageManager.PERMISSION_GRANTED) {
2145                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2146                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2147                        + " without permission " + android.Manifest.permission.DUMP);
2148                return;
2149            }
2150
2151            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2152        }
2153    }
2154
2155    static class DbBinder extends Binder {
2156        ActivityManagerService mActivityManagerService;
2157        DbBinder(ActivityManagerService activityManagerService) {
2158            mActivityManagerService = activityManagerService;
2159        }
2160
2161        @Override
2162        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2163            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2164                    != PackageManager.PERMISSION_GRANTED) {
2165                pw.println("Permission Denial: can't dump dbinfo from from pid="
2166                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2167                        + " without permission " + android.Manifest.permission.DUMP);
2168                return;
2169            }
2170
2171            mActivityManagerService.dumpDbInfo(fd, pw, args);
2172        }
2173    }
2174
2175    static class CpuBinder extends Binder {
2176        ActivityManagerService mActivityManagerService;
2177        CpuBinder(ActivityManagerService activityManagerService) {
2178            mActivityManagerService = activityManagerService;
2179        }
2180
2181        @Override
2182        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2183            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2184                    != PackageManager.PERMISSION_GRANTED) {
2185                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2186                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2187                        + " without permission " + android.Manifest.permission.DUMP);
2188                return;
2189            }
2190
2191            synchronized (mActivityManagerService.mProcessCpuTracker) {
2192                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2193                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2194                        SystemClock.uptimeMillis()));
2195            }
2196        }
2197    }
2198
2199    public static final class Lifecycle extends SystemService {
2200        private final ActivityManagerService mService;
2201
2202        public Lifecycle(Context context) {
2203            super(context);
2204            mService = new ActivityManagerService(context);
2205        }
2206
2207        @Override
2208        public void onStart() {
2209            mService.start();
2210        }
2211
2212        public ActivityManagerService getService() {
2213            return mService;
2214        }
2215    }
2216
2217    // Note: This method is invoked on the main thread but may need to attach various
2218    // handlers to other threads.  So take care to be explicit about the looper.
2219    public ActivityManagerService(Context systemContext) {
2220        mContext = systemContext;
2221        mFactoryTest = FactoryTest.getMode();
2222        mSystemThread = ActivityThread.currentActivityThread();
2223
2224        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2225
2226        mHandlerThread = new ServiceThread(TAG,
2227                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2228        mHandlerThread.start();
2229        mHandler = new MainHandler(mHandlerThread.getLooper());
2230
2231        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2232                "foreground", BROADCAST_FG_TIMEOUT, false);
2233        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2234                "background", BROADCAST_BG_TIMEOUT, true);
2235        mBroadcastQueues[0] = mFgBroadcastQueue;
2236        mBroadcastQueues[1] = mBgBroadcastQueue;
2237
2238        mServices = new ActiveServices(this);
2239        mProviderMap = new ProviderMap(this);
2240
2241        // TODO: Move creation of battery stats service outside of activity manager service.
2242        File dataDir = Environment.getDataDirectory();
2243        File systemDir = new File(dataDir, "system");
2244        systemDir.mkdirs();
2245        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2246        mBatteryStatsService.getActiveStatistics().readLocked();
2247        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2248        mOnBattery = DEBUG_POWER ? true
2249                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2250        mBatteryStatsService.getActiveStatistics().setCallback(this);
2251
2252        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2253
2254        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2255
2256        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2257
2258        // User 0 is the first and only user that runs at boot.
2259        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2260        mUserLru.add(Integer.valueOf(0));
2261        updateStartedUserArrayLocked();
2262
2263        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2264            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2265
2266        mConfiguration.setToDefaults();
2267        mConfiguration.setLocale(Locale.getDefault());
2268
2269        mConfigurationSeq = mConfiguration.seq = 1;
2270        mProcessCpuTracker.init();
2271
2272        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2273        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2274        mStackSupervisor = new ActivityStackSupervisor(this);
2275        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2276
2277        mProcessCpuThread = new Thread("CpuTracker") {
2278            @Override
2279            public void run() {
2280                while (true) {
2281                    try {
2282                        try {
2283                            synchronized(this) {
2284                                final long now = SystemClock.uptimeMillis();
2285                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2286                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2287                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2288                                //        + ", write delay=" + nextWriteDelay);
2289                                if (nextWriteDelay < nextCpuDelay) {
2290                                    nextCpuDelay = nextWriteDelay;
2291                                }
2292                                if (nextCpuDelay > 0) {
2293                                    mProcessCpuMutexFree.set(true);
2294                                    this.wait(nextCpuDelay);
2295                                }
2296                            }
2297                        } catch (InterruptedException e) {
2298                        }
2299                        updateCpuStatsNow();
2300                    } catch (Exception e) {
2301                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2302                    }
2303                }
2304            }
2305        };
2306
2307        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2308
2309        Watchdog.getInstance().addMonitor(this);
2310        Watchdog.getInstance().addThread(mHandler);
2311    }
2312
2313    public void setSystemServiceManager(SystemServiceManager mgr) {
2314        mSystemServiceManager = mgr;
2315    }
2316
2317    private void start() {
2318        Process.removeAllProcessGroups();
2319        mProcessCpuThread.start();
2320
2321        mBatteryStatsService.publish(mContext);
2322        mAppOpsService.publish(mContext);
2323        Slog.d("AppOps", "AppOpsService published");
2324        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2325    }
2326
2327    public void initPowerManagement() {
2328        mStackSupervisor.initPowerManagement();
2329        mBatteryStatsService.initPowerManagement();
2330    }
2331
2332    @Override
2333    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2334            throws RemoteException {
2335        if (code == SYSPROPS_TRANSACTION) {
2336            // We need to tell all apps about the system property change.
2337            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2338            synchronized(this) {
2339                final int NP = mProcessNames.getMap().size();
2340                for (int ip=0; ip<NP; ip++) {
2341                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2342                    final int NA = apps.size();
2343                    for (int ia=0; ia<NA; ia++) {
2344                        ProcessRecord app = apps.valueAt(ia);
2345                        if (app.thread != null) {
2346                            procs.add(app.thread.asBinder());
2347                        }
2348                    }
2349                }
2350            }
2351
2352            int N = procs.size();
2353            for (int i=0; i<N; i++) {
2354                Parcel data2 = Parcel.obtain();
2355                try {
2356                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2357                } catch (RemoteException e) {
2358                }
2359                data2.recycle();
2360            }
2361        }
2362        try {
2363            return super.onTransact(code, data, reply, flags);
2364        } catch (RuntimeException e) {
2365            // The activity manager only throws security exceptions, so let's
2366            // log all others.
2367            if (!(e instanceof SecurityException)) {
2368                Slog.wtf(TAG, "Activity Manager Crash", e);
2369            }
2370            throw e;
2371        }
2372    }
2373
2374    void updateCpuStats() {
2375        final long now = SystemClock.uptimeMillis();
2376        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2377            return;
2378        }
2379        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2380            synchronized (mProcessCpuThread) {
2381                mProcessCpuThread.notify();
2382            }
2383        }
2384    }
2385
2386    void updateCpuStatsNow() {
2387        synchronized (mProcessCpuTracker) {
2388            mProcessCpuMutexFree.set(false);
2389            final long now = SystemClock.uptimeMillis();
2390            boolean haveNewCpuStats = false;
2391
2392            if (MONITOR_CPU_USAGE &&
2393                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2394                mLastCpuTime.set(now);
2395                haveNewCpuStats = true;
2396                mProcessCpuTracker.update();
2397                //Slog.i(TAG, mProcessCpu.printCurrentState());
2398                //Slog.i(TAG, "Total CPU usage: "
2399                //        + mProcessCpu.getTotalCpuPercent() + "%");
2400
2401                // Slog the cpu usage if the property is set.
2402                if ("true".equals(SystemProperties.get("events.cpu"))) {
2403                    int user = mProcessCpuTracker.getLastUserTime();
2404                    int system = mProcessCpuTracker.getLastSystemTime();
2405                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2406                    int irq = mProcessCpuTracker.getLastIrqTime();
2407                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2408                    int idle = mProcessCpuTracker.getLastIdleTime();
2409
2410                    int total = user + system + iowait + irq + softIrq + idle;
2411                    if (total == 0) total = 1;
2412
2413                    EventLog.writeEvent(EventLogTags.CPU,
2414                            ((user+system+iowait+irq+softIrq) * 100) / total,
2415                            (user * 100) / total,
2416                            (system * 100) / total,
2417                            (iowait * 100) / total,
2418                            (irq * 100) / total,
2419                            (softIrq * 100) / total);
2420                }
2421            }
2422
2423            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2424            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2425            synchronized(bstats) {
2426                synchronized(mPidsSelfLocked) {
2427                    if (haveNewCpuStats) {
2428                        if (mOnBattery) {
2429                            int perc = bstats.startAddingCpuLocked();
2430                            int totalUTime = 0;
2431                            int totalSTime = 0;
2432                            final int N = mProcessCpuTracker.countStats();
2433                            for (int i=0; i<N; i++) {
2434                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2435                                if (!st.working) {
2436                                    continue;
2437                                }
2438                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2439                                int otherUTime = (st.rel_utime*perc)/100;
2440                                int otherSTime = (st.rel_stime*perc)/100;
2441                                totalUTime += otherUTime;
2442                                totalSTime += otherSTime;
2443                                if (pr != null) {
2444                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2445                                    if (ps == null || !ps.isActive()) {
2446                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2447                                                pr.info.uid, pr.processName);
2448                                    }
2449                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2450                                            st.rel_stime-otherSTime);
2451                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2452                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2453                                } else {
2454                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2455                                    if (ps == null || !ps.isActive()) {
2456                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2457                                                bstats.mapUid(st.uid), st.name);
2458                                    }
2459                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2460                                            st.rel_stime-otherSTime);
2461                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2462                                }
2463                            }
2464                            bstats.finishAddingCpuLocked(perc, totalUTime,
2465                                    totalSTime, cpuSpeedTimes);
2466                        }
2467                    }
2468                }
2469
2470                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2471                    mLastWriteTime = now;
2472                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2473                }
2474            }
2475        }
2476    }
2477
2478    @Override
2479    public void batteryNeedsCpuUpdate() {
2480        updateCpuStatsNow();
2481    }
2482
2483    @Override
2484    public void batteryPowerChanged(boolean onBattery) {
2485        // When plugging in, update the CPU stats first before changing
2486        // the plug state.
2487        updateCpuStatsNow();
2488        synchronized (this) {
2489            synchronized(mPidsSelfLocked) {
2490                mOnBattery = DEBUG_POWER ? true : onBattery;
2491            }
2492        }
2493    }
2494
2495    /**
2496     * Initialize the application bind args. These are passed to each
2497     * process when the bindApplication() IPC is sent to the process. They're
2498     * lazily setup to make sure the services are running when they're asked for.
2499     */
2500    private HashMap<String, IBinder> getCommonServicesLocked() {
2501        if (mAppBindArgs == null) {
2502            mAppBindArgs = new HashMap<String, IBinder>();
2503
2504            // Setup the application init args
2505            mAppBindArgs.put("package", ServiceManager.getService("package"));
2506            mAppBindArgs.put("window", ServiceManager.getService("window"));
2507            mAppBindArgs.put(Context.ALARM_SERVICE,
2508                    ServiceManager.getService(Context.ALARM_SERVICE));
2509        }
2510        return mAppBindArgs;
2511    }
2512
2513    final void setFocusedActivityLocked(ActivityRecord r) {
2514        if (mFocusedActivity != r) {
2515            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2516            mFocusedActivity = r;
2517            if (r.task != null && r.task.voiceInteractor != null) {
2518                startRunningVoiceLocked();
2519            } else {
2520                finishRunningVoiceLocked();
2521            }
2522            mStackSupervisor.setFocusedStack(r);
2523            if (r != null) {
2524                mWindowManager.setFocusedApp(r.appToken, true);
2525            }
2526            applyUpdateLockStateLocked(r);
2527        }
2528    }
2529
2530    final void clearFocusedActivity(ActivityRecord r) {
2531        if (mFocusedActivity == r) {
2532            mFocusedActivity = null;
2533        }
2534    }
2535
2536    @Override
2537    public void setFocusedStack(int stackId) {
2538        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2539        synchronized (ActivityManagerService.this) {
2540            ActivityStack stack = mStackSupervisor.getStack(stackId);
2541            if (stack != null) {
2542                ActivityRecord r = stack.topRunningActivityLocked(null);
2543                if (r != null) {
2544                    setFocusedActivityLocked(r);
2545                }
2546            }
2547        }
2548    }
2549
2550    @Override
2551    public void notifyActivityDrawn(IBinder token) {
2552        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2553        synchronized (this) {
2554            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2555            if (r != null) {
2556                r.task.stack.notifyActivityDrawnLocked(r);
2557            }
2558        }
2559    }
2560
2561    final void applyUpdateLockStateLocked(ActivityRecord r) {
2562        // Modifications to the UpdateLock state are done on our handler, outside
2563        // the activity manager's locks.  The new state is determined based on the
2564        // state *now* of the relevant activity record.  The object is passed to
2565        // the handler solely for logging detail, not to be consulted/modified.
2566        final boolean nextState = r != null && r.immersive;
2567        mHandler.sendMessage(
2568                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2569    }
2570
2571    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2572        Message msg = Message.obtain();
2573        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2574        msg.obj = r.task.askedCompatMode ? null : r;
2575        mHandler.sendMessage(msg);
2576    }
2577
2578    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2579            String what, Object obj, ProcessRecord srcApp) {
2580        app.lastActivityTime = now;
2581
2582        if (app.activities.size() > 0) {
2583            // Don't want to touch dependent processes that are hosting activities.
2584            return index;
2585        }
2586
2587        int lrui = mLruProcesses.lastIndexOf(app);
2588        if (lrui < 0) {
2589            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2590                    + what + " " + obj + " from " + srcApp);
2591            return index;
2592        }
2593
2594        if (lrui >= index) {
2595            // Don't want to cause this to move dependent processes *back* in the
2596            // list as if they were less frequently used.
2597            return index;
2598        }
2599
2600        if (lrui >= mLruProcessActivityStart) {
2601            // Don't want to touch dependent processes that are hosting activities.
2602            return index;
2603        }
2604
2605        mLruProcesses.remove(lrui);
2606        if (index > 0) {
2607            index--;
2608        }
2609        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2610                + " in LRU list: " + app);
2611        mLruProcesses.add(index, app);
2612        return index;
2613    }
2614
2615    final void removeLruProcessLocked(ProcessRecord app) {
2616        int lrui = mLruProcesses.lastIndexOf(app);
2617        if (lrui >= 0) {
2618            if (lrui <= mLruProcessActivityStart) {
2619                mLruProcessActivityStart--;
2620            }
2621            if (lrui <= mLruProcessServiceStart) {
2622                mLruProcessServiceStart--;
2623            }
2624            mLruProcesses.remove(lrui);
2625        }
2626    }
2627
2628    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2629            ProcessRecord client) {
2630        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2631                || app.treatLikeActivity;
2632        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2633        if (!activityChange && hasActivity) {
2634            // The process has activities, so we are only allowing activity-based adjustments
2635            // to move it.  It should be kept in the front of the list with other
2636            // processes that have activities, and we don't want those to change their
2637            // order except due to activity operations.
2638            return;
2639        }
2640
2641        mLruSeq++;
2642        final long now = SystemClock.uptimeMillis();
2643        app.lastActivityTime = now;
2644
2645        // First a quick reject: if the app is already at the position we will
2646        // put it, then there is nothing to do.
2647        if (hasActivity) {
2648            final int N = mLruProcesses.size();
2649            if (N > 0 && mLruProcesses.get(N-1) == app) {
2650                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2651                return;
2652            }
2653        } else {
2654            if (mLruProcessServiceStart > 0
2655                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2656                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2657                return;
2658            }
2659        }
2660
2661        int lrui = mLruProcesses.lastIndexOf(app);
2662
2663        if (app.persistent && lrui >= 0) {
2664            // We don't care about the position of persistent processes, as long as
2665            // they are in the list.
2666            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2667            return;
2668        }
2669
2670        /* In progress: compute new position first, so we can avoid doing work
2671           if the process is not actually going to move.  Not yet working.
2672        int addIndex;
2673        int nextIndex;
2674        boolean inActivity = false, inService = false;
2675        if (hasActivity) {
2676            // Process has activities, put it at the very tipsy-top.
2677            addIndex = mLruProcesses.size();
2678            nextIndex = mLruProcessServiceStart;
2679            inActivity = true;
2680        } else if (hasService) {
2681            // Process has services, put it at the top of the service list.
2682            addIndex = mLruProcessActivityStart;
2683            nextIndex = mLruProcessServiceStart;
2684            inActivity = true;
2685            inService = true;
2686        } else  {
2687            // Process not otherwise of interest, it goes to the top of the non-service area.
2688            addIndex = mLruProcessServiceStart;
2689            if (client != null) {
2690                int clientIndex = mLruProcesses.lastIndexOf(client);
2691                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2692                        + app);
2693                if (clientIndex >= 0 && addIndex > clientIndex) {
2694                    addIndex = clientIndex;
2695                }
2696            }
2697            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2698        }
2699
2700        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2701                + mLruProcessActivityStart + "): " + app);
2702        */
2703
2704        if (lrui >= 0) {
2705            if (lrui < mLruProcessActivityStart) {
2706                mLruProcessActivityStart--;
2707            }
2708            if (lrui < mLruProcessServiceStart) {
2709                mLruProcessServiceStart--;
2710            }
2711            /*
2712            if (addIndex > lrui) {
2713                addIndex--;
2714            }
2715            if (nextIndex > lrui) {
2716                nextIndex--;
2717            }
2718            */
2719            mLruProcesses.remove(lrui);
2720        }
2721
2722        /*
2723        mLruProcesses.add(addIndex, app);
2724        if (inActivity) {
2725            mLruProcessActivityStart++;
2726        }
2727        if (inService) {
2728            mLruProcessActivityStart++;
2729        }
2730        */
2731
2732        int nextIndex;
2733        if (hasActivity) {
2734            final int N = mLruProcesses.size();
2735            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2736                // Process doesn't have activities, but has clients with
2737                // activities...  move it up, but one below the top (the top
2738                // should always have a real activity).
2739                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2740                mLruProcesses.add(N-1, app);
2741                // To keep it from spamming the LRU list (by making a bunch of clients),
2742                // we will push down any other entries owned by the app.
2743                final int uid = app.info.uid;
2744                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2745                    ProcessRecord subProc = mLruProcesses.get(i);
2746                    if (subProc.info.uid == uid) {
2747                        // We want to push this one down the list.  If the process after
2748                        // it is for the same uid, however, don't do so, because we don't
2749                        // want them internally to be re-ordered.
2750                        if (mLruProcesses.get(i-1).info.uid != uid) {
2751                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2752                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2753                            ProcessRecord tmp = mLruProcesses.get(i);
2754                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2755                            mLruProcesses.set(i-1, tmp);
2756                            i--;
2757                        }
2758                    } else {
2759                        // A gap, we can stop here.
2760                        break;
2761                    }
2762                }
2763            } else {
2764                // Process has activities, put it at the very tipsy-top.
2765                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2766                mLruProcesses.add(app);
2767            }
2768            nextIndex = mLruProcessServiceStart;
2769        } else if (hasService) {
2770            // Process has services, put it at the top of the service list.
2771            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2772            mLruProcesses.add(mLruProcessActivityStart, app);
2773            nextIndex = mLruProcessServiceStart;
2774            mLruProcessActivityStart++;
2775        } else  {
2776            // Process not otherwise of interest, it goes to the top of the non-service area.
2777            int index = mLruProcessServiceStart;
2778            if (client != null) {
2779                // If there is a client, don't allow the process to be moved up higher
2780                // in the list than that client.
2781                int clientIndex = mLruProcesses.lastIndexOf(client);
2782                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2783                        + " when updating " + app);
2784                if (clientIndex <= lrui) {
2785                    // Don't allow the client index restriction to push it down farther in the
2786                    // list than it already is.
2787                    clientIndex = lrui;
2788                }
2789                if (clientIndex >= 0 && index > clientIndex) {
2790                    index = clientIndex;
2791                }
2792            }
2793            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2794            mLruProcesses.add(index, app);
2795            nextIndex = index-1;
2796            mLruProcessActivityStart++;
2797            mLruProcessServiceStart++;
2798        }
2799
2800        // If the app is currently using a content provider or service,
2801        // bump those processes as well.
2802        for (int j=app.connections.size()-1; j>=0; j--) {
2803            ConnectionRecord cr = app.connections.valueAt(j);
2804            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2805                    && cr.binding.service.app != null
2806                    && cr.binding.service.app.lruSeq != mLruSeq
2807                    && !cr.binding.service.app.persistent) {
2808                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2809                        "service connection", cr, app);
2810            }
2811        }
2812        for (int j=app.conProviders.size()-1; j>=0; j--) {
2813            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2814            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2815                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2816                        "provider reference", cpr, app);
2817            }
2818        }
2819    }
2820
2821    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2822        if (uid == Process.SYSTEM_UID) {
2823            // The system gets to run in any process.  If there are multiple
2824            // processes with the same uid, just pick the first (this
2825            // should never happen).
2826            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2827            if (procs == null) return null;
2828            final int N = procs.size();
2829            for (int i = 0; i < N; i++) {
2830                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2831            }
2832        }
2833        ProcessRecord proc = mProcessNames.get(processName, uid);
2834        if (false && proc != null && !keepIfLarge
2835                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2836                && proc.lastCachedPss >= 4000) {
2837            // Turn this condition on to cause killing to happen regularly, for testing.
2838            if (proc.baseProcessTracker != null) {
2839                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2840            }
2841            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2842        } else if (proc != null && !keepIfLarge
2843                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2844                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2845            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2846            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2847                if (proc.baseProcessTracker != null) {
2848                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2849                }
2850                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2851            }
2852        }
2853        return proc;
2854    }
2855
2856    void ensurePackageDexOpt(String packageName) {
2857        IPackageManager pm = AppGlobals.getPackageManager();
2858        try {
2859            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2860                mDidDexOpt = true;
2861            }
2862        } catch (RemoteException e) {
2863        }
2864    }
2865
2866    boolean isNextTransitionForward() {
2867        int transit = mWindowManager.getPendingAppTransition();
2868        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2869                || transit == AppTransition.TRANSIT_TASK_OPEN
2870                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2871    }
2872
2873    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2874            String processName, String abiOverride, int uid, Runnable crashHandler) {
2875        synchronized(this) {
2876            ApplicationInfo info = new ApplicationInfo();
2877            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2878            // For isolated processes, the former contains the parent's uid and the latter the
2879            // actual uid of the isolated process.
2880            // In the special case introduced by this method (which is, starting an isolated
2881            // process directly from the SystemServer without an actual parent app process) the
2882            // closest thing to a parent's uid is SYSTEM_UID.
2883            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2884            // the |isolated| logic in the ProcessRecord constructor.
2885            info.uid = Process.SYSTEM_UID;
2886            info.processName = processName;
2887            info.className = entryPoint;
2888            info.packageName = "android";
2889            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2890                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2891                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2892                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2893                    crashHandler);
2894            return proc != null ? proc.pid : 0;
2895        }
2896    }
2897
2898    final ProcessRecord startProcessLocked(String processName,
2899            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2900            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2901            boolean isolated, boolean keepIfLarge) {
2902        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2903                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2904                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2905                null /* crashHandler */);
2906    }
2907
2908    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2909            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2910            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2911            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2912        long startTime = SystemClock.elapsedRealtime();
2913        ProcessRecord app;
2914        if (!isolated) {
2915            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2916            checkTime(startTime, "startProcess: after getProcessRecord");
2917        } else {
2918            // If this is an isolated process, it can't re-use an existing process.
2919            app = null;
2920        }
2921        // We don't have to do anything more if:
2922        // (1) There is an existing application record; and
2923        // (2) The caller doesn't think it is dead, OR there is no thread
2924        //     object attached to it so we know it couldn't have crashed; and
2925        // (3) There is a pid assigned to it, so it is either starting or
2926        //     already running.
2927        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2928                + " app=" + app + " knownToBeDead=" + knownToBeDead
2929                + " thread=" + (app != null ? app.thread : null)
2930                + " pid=" + (app != null ? app.pid : -1));
2931        if (app != null && app.pid > 0) {
2932            if (!knownToBeDead || app.thread == null) {
2933                // We already have the app running, or are waiting for it to
2934                // come up (we have a pid but not yet its thread), so keep it.
2935                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2936                // If this is a new package in the process, add the package to the list
2937                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2938                checkTime(startTime, "startProcess: done, added package to proc");
2939                return app;
2940            }
2941
2942            // An application record is attached to a previous process,
2943            // clean it up now.
2944            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2945            checkTime(startTime, "startProcess: bad proc running, killing");
2946            Process.killProcessGroup(app.info.uid, app.pid);
2947            handleAppDiedLocked(app, true, true);
2948            checkTime(startTime, "startProcess: done killing old proc");
2949        }
2950
2951        String hostingNameStr = hostingName != null
2952                ? hostingName.flattenToShortString() : null;
2953
2954        if (!isolated) {
2955            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2956                // If we are in the background, then check to see if this process
2957                // is bad.  If so, we will just silently fail.
2958                if (mBadProcesses.get(info.processName, info.uid) != null) {
2959                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2960                            + "/" + info.processName);
2961                    return null;
2962                }
2963            } else {
2964                // When the user is explicitly starting a process, then clear its
2965                // crash count so that we won't make it bad until they see at
2966                // least one crash dialog again, and make the process good again
2967                // if it had been bad.
2968                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2969                        + "/" + info.processName);
2970                mProcessCrashTimes.remove(info.processName, info.uid);
2971                if (mBadProcesses.get(info.processName, info.uid) != null) {
2972                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2973                            UserHandle.getUserId(info.uid), info.uid,
2974                            info.processName);
2975                    mBadProcesses.remove(info.processName, info.uid);
2976                    if (app != null) {
2977                        app.bad = false;
2978                    }
2979                }
2980            }
2981        }
2982
2983        if (app == null) {
2984            checkTime(startTime, "startProcess: creating new process record");
2985            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2986            app.crashHandler = crashHandler;
2987            if (app == null) {
2988                Slog.w(TAG, "Failed making new process record for "
2989                        + processName + "/" + info.uid + " isolated=" + isolated);
2990                return null;
2991            }
2992            mProcessNames.put(processName, app.uid, app);
2993            if (isolated) {
2994                mIsolatedProcesses.put(app.uid, app);
2995            }
2996            checkTime(startTime, "startProcess: done creating new process record");
2997        } else {
2998            // If this is a new package in the process, add the package to the list
2999            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3000            checkTime(startTime, "startProcess: added package to existing proc");
3001        }
3002
3003        // If the system is not ready yet, then hold off on starting this
3004        // process until it is.
3005        if (!mProcessesReady
3006                && !isAllowedWhileBooting(info)
3007                && !allowWhileBooting) {
3008            if (!mProcessesOnHold.contains(app)) {
3009                mProcessesOnHold.add(app);
3010            }
3011            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
3012            checkTime(startTime, "startProcess: returning with proc on hold");
3013            return app;
3014        }
3015
3016        checkTime(startTime, "startProcess: stepping in to startProcess");
3017        startProcessLocked(
3018                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3019        checkTime(startTime, "startProcess: done starting proc!");
3020        return (app.pid != 0) ? app : null;
3021    }
3022
3023    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3024        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3025    }
3026
3027    private final void startProcessLocked(ProcessRecord app,
3028            String hostingType, String hostingNameStr) {
3029        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3030                null /* entryPoint */, null /* entryPointArgs */);
3031    }
3032
3033    private final void startProcessLocked(ProcessRecord app, String hostingType,
3034            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3035        long startTime = SystemClock.elapsedRealtime();
3036        if (app.pid > 0 && app.pid != MY_PID) {
3037            checkTime(startTime, "startProcess: removing from pids map");
3038            synchronized (mPidsSelfLocked) {
3039                mPidsSelfLocked.remove(app.pid);
3040                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3041            }
3042            checkTime(startTime, "startProcess: done removing from pids map");
3043            app.setPid(0);
3044        }
3045
3046        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3047                "startProcessLocked removing on hold: " + app);
3048        mProcessesOnHold.remove(app);
3049
3050        checkTime(startTime, "startProcess: starting to update cpu stats");
3051        updateCpuStats();
3052        checkTime(startTime, "startProcess: done updating cpu stats");
3053
3054        try {
3055            int uid = app.uid;
3056
3057            int[] gids = null;
3058            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3059            if (!app.isolated) {
3060                int[] permGids = null;
3061                try {
3062                    checkTime(startTime, "startProcess: getting gids from package manager");
3063                    final PackageManager pm = mContext.getPackageManager();
3064                    permGids = pm.getPackageGids(app.info.packageName);
3065
3066                    if (Environment.isExternalStorageEmulated()) {
3067                        checkTime(startTime, "startProcess: checking external storage perm");
3068                        if (pm.checkPermission(
3069                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3070                                app.info.packageName) == PERMISSION_GRANTED) {
3071                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3072                        } else {
3073                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3074                        }
3075                    }
3076                } catch (PackageManager.NameNotFoundException e) {
3077                    Slog.w(TAG, "Unable to retrieve gids", e);
3078                }
3079
3080                /*
3081                 * Add shared application and profile GIDs so applications can share some
3082                 * resources like shared libraries and access user-wide resources
3083                 */
3084                if (permGids == null) {
3085                    gids = new int[2];
3086                } else {
3087                    gids = new int[permGids.length + 2];
3088                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3089                }
3090                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3091                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3092            }
3093            checkTime(startTime, "startProcess: building args");
3094            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3095                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3096                        && mTopComponent != null
3097                        && app.processName.equals(mTopComponent.getPackageName())) {
3098                    uid = 0;
3099                }
3100                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3101                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3102                    uid = 0;
3103                }
3104            }
3105            int debugFlags = 0;
3106            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3107                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3108                // Also turn on CheckJNI for debuggable apps. It's quite
3109                // awkward to turn on otherwise.
3110                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3111            }
3112            // Run the app in safe mode if its manifest requests so or the
3113            // system is booted in safe mode.
3114            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3115                mSafeMode == true) {
3116                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3117            }
3118            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3119                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3120            }
3121            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3122                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3123            }
3124            if ("1".equals(SystemProperties.get("debug.assert"))) {
3125                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3126            }
3127
3128            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3129            if (requiredAbi == null) {
3130                requiredAbi = Build.SUPPORTED_ABIS[0];
3131            }
3132
3133            String instructionSet = null;
3134            if (app.info.primaryCpuAbi != null) {
3135                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3136            }
3137
3138            // Start the process.  It will either succeed and return a result containing
3139            // the PID of the new process, or else throw a RuntimeException.
3140            boolean isActivityProcess = (entryPoint == null);
3141            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3142            checkTime(startTime, "startProcess: asking zygote to start proc");
3143            Process.ProcessStartResult startResult = Process.start(entryPoint,
3144                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3145                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3146                    entryPointArgs);
3147            checkTime(startTime, "startProcess: returned from zygote!");
3148
3149            if (app.isolated) {
3150                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3151            }
3152            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3153            checkTime(startTime, "startProcess: done updating battery stats");
3154
3155            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3156                    UserHandle.getUserId(uid), startResult.pid, uid,
3157                    app.processName, hostingType,
3158                    hostingNameStr != null ? hostingNameStr : "");
3159
3160            if (app.persistent) {
3161                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3162            }
3163
3164            checkTime(startTime, "startProcess: building log message");
3165            StringBuilder buf = mStringBuilder;
3166            buf.setLength(0);
3167            buf.append("Start proc ");
3168            buf.append(app.processName);
3169            if (!isActivityProcess) {
3170                buf.append(" [");
3171                buf.append(entryPoint);
3172                buf.append("]");
3173            }
3174            buf.append(" for ");
3175            buf.append(hostingType);
3176            if (hostingNameStr != null) {
3177                buf.append(" ");
3178                buf.append(hostingNameStr);
3179            }
3180            buf.append(": pid=");
3181            buf.append(startResult.pid);
3182            buf.append(" uid=");
3183            buf.append(uid);
3184            buf.append(" gids={");
3185            if (gids != null) {
3186                for (int gi=0; gi<gids.length; gi++) {
3187                    if (gi != 0) buf.append(", ");
3188                    buf.append(gids[gi]);
3189
3190                }
3191            }
3192            buf.append("}");
3193            if (requiredAbi != null) {
3194                buf.append(" abi=");
3195                buf.append(requiredAbi);
3196            }
3197            Slog.i(TAG, buf.toString());
3198            app.setPid(startResult.pid);
3199            app.usingWrapper = startResult.usingWrapper;
3200            app.removed = false;
3201            app.killedByAm = false;
3202            checkTime(startTime, "startProcess: starting to update pids map");
3203            synchronized (mPidsSelfLocked) {
3204                this.mPidsSelfLocked.put(startResult.pid, app);
3205                if (isActivityProcess) {
3206                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3207                    msg.obj = app;
3208                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3209                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3210                }
3211            }
3212            checkTime(startTime, "startProcess: done updating pids map");
3213        } catch (RuntimeException e) {
3214            // XXX do better error recovery.
3215            app.setPid(0);
3216            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3217            if (app.isolated) {
3218                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3219            }
3220            Slog.e(TAG, "Failure starting process " + app.processName, e);
3221        }
3222    }
3223
3224    void updateUsageStats(ActivityRecord component, boolean resumed) {
3225        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3226        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3227        if (resumed) {
3228            if (mUsageStatsService != null) {
3229                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3230                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3231            }
3232            synchronized (stats) {
3233                stats.noteActivityResumedLocked(component.app.uid);
3234            }
3235        } else {
3236            if (mUsageStatsService != null) {
3237                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3238                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3239            }
3240            synchronized (stats) {
3241                stats.noteActivityPausedLocked(component.app.uid);
3242            }
3243        }
3244    }
3245
3246    Intent getHomeIntent() {
3247        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3248        intent.setComponent(mTopComponent);
3249        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3250            intent.addCategory(Intent.CATEGORY_HOME);
3251        }
3252        return intent;
3253    }
3254
3255    boolean startHomeActivityLocked(int userId) {
3256        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3257                && mTopAction == null) {
3258            // We are running in factory test mode, but unable to find
3259            // the factory test app, so just sit around displaying the
3260            // error message and don't try to start anything.
3261            return false;
3262        }
3263        Intent intent = getHomeIntent();
3264        ActivityInfo aInfo =
3265            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3266        if (aInfo != null) {
3267            intent.setComponent(new ComponentName(
3268                    aInfo.applicationInfo.packageName, aInfo.name));
3269            // Don't do this if the home app is currently being
3270            // instrumented.
3271            aInfo = new ActivityInfo(aInfo);
3272            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3273            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3274                    aInfo.applicationInfo.uid, true);
3275            if (app == null || app.instrumentationClass == null) {
3276                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3277                mStackSupervisor.startHomeActivity(intent, aInfo);
3278            }
3279        }
3280
3281        return true;
3282    }
3283
3284    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3285        ActivityInfo ai = null;
3286        ComponentName comp = intent.getComponent();
3287        try {
3288            if (comp != null) {
3289                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3290            } else {
3291                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3292                        intent,
3293                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3294                            flags, userId);
3295
3296                if (info != null) {
3297                    ai = info.activityInfo;
3298                }
3299            }
3300        } catch (RemoteException e) {
3301            // ignore
3302        }
3303
3304        return ai;
3305    }
3306
3307    /**
3308     * Starts the "new version setup screen" if appropriate.
3309     */
3310    void startSetupActivityLocked() {
3311        // Only do this once per boot.
3312        if (mCheckedForSetup) {
3313            return;
3314        }
3315
3316        // We will show this screen if the current one is a different
3317        // version than the last one shown, and we are not running in
3318        // low-level factory test mode.
3319        final ContentResolver resolver = mContext.getContentResolver();
3320        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3321                Settings.Global.getInt(resolver,
3322                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3323            mCheckedForSetup = true;
3324
3325            // See if we should be showing the platform update setup UI.
3326            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3327            List<ResolveInfo> ris = mContext.getPackageManager()
3328                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3329
3330            // We don't allow third party apps to replace this.
3331            ResolveInfo ri = null;
3332            for (int i=0; ris != null && i<ris.size(); i++) {
3333                if ((ris.get(i).activityInfo.applicationInfo.flags
3334                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3335                    ri = ris.get(i);
3336                    break;
3337                }
3338            }
3339
3340            if (ri != null) {
3341                String vers = ri.activityInfo.metaData != null
3342                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3343                        : null;
3344                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3345                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3346                            Intent.METADATA_SETUP_VERSION);
3347                }
3348                String lastVers = Settings.Secure.getString(
3349                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3350                if (vers != null && !vers.equals(lastVers)) {
3351                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3352                    intent.setComponent(new ComponentName(
3353                            ri.activityInfo.packageName, ri.activityInfo.name));
3354                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3355                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null,
3356                            null);
3357                }
3358            }
3359        }
3360    }
3361
3362    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3363        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3364    }
3365
3366    void enforceNotIsolatedCaller(String caller) {
3367        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3368            throw new SecurityException("Isolated process not allowed to call " + caller);
3369        }
3370    }
3371
3372    @Override
3373    public int getFrontActivityScreenCompatMode() {
3374        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3375        synchronized (this) {
3376            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3377        }
3378    }
3379
3380    @Override
3381    public void setFrontActivityScreenCompatMode(int mode) {
3382        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3383                "setFrontActivityScreenCompatMode");
3384        synchronized (this) {
3385            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3386        }
3387    }
3388
3389    @Override
3390    public int getPackageScreenCompatMode(String packageName) {
3391        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3392        synchronized (this) {
3393            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3394        }
3395    }
3396
3397    @Override
3398    public void setPackageScreenCompatMode(String packageName, int mode) {
3399        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3400                "setPackageScreenCompatMode");
3401        synchronized (this) {
3402            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3403        }
3404    }
3405
3406    @Override
3407    public boolean getPackageAskScreenCompat(String packageName) {
3408        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3409        synchronized (this) {
3410            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3411        }
3412    }
3413
3414    @Override
3415    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3416        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3417                "setPackageAskScreenCompat");
3418        synchronized (this) {
3419            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3420        }
3421    }
3422
3423    private void dispatchProcessesChanged() {
3424        int N;
3425        synchronized (this) {
3426            N = mPendingProcessChanges.size();
3427            if (mActiveProcessChanges.length < N) {
3428                mActiveProcessChanges = new ProcessChangeItem[N];
3429            }
3430            mPendingProcessChanges.toArray(mActiveProcessChanges);
3431            mAvailProcessChanges.addAll(mPendingProcessChanges);
3432            mPendingProcessChanges.clear();
3433            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3434        }
3435
3436        int i = mProcessObservers.beginBroadcast();
3437        while (i > 0) {
3438            i--;
3439            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3440            if (observer != null) {
3441                try {
3442                    for (int j=0; j<N; j++) {
3443                        ProcessChangeItem item = mActiveProcessChanges[j];
3444                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3445                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3446                                    + item.pid + " uid=" + item.uid + ": "
3447                                    + item.foregroundActivities);
3448                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3449                                    item.foregroundActivities);
3450                        }
3451                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3452                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3453                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3454                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3455                        }
3456                    }
3457                } catch (RemoteException e) {
3458                }
3459            }
3460        }
3461        mProcessObservers.finishBroadcast();
3462    }
3463
3464    private void dispatchProcessDied(int pid, int uid) {
3465        int i = mProcessObservers.beginBroadcast();
3466        while (i > 0) {
3467            i--;
3468            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3469            if (observer != null) {
3470                try {
3471                    observer.onProcessDied(pid, uid);
3472                } catch (RemoteException e) {
3473                }
3474            }
3475        }
3476        mProcessObservers.finishBroadcast();
3477    }
3478
3479    @Override
3480    public final int startActivity(IApplicationThread caller, String callingPackage,
3481            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3482            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3483        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3484            resultWho, requestCode, startFlags, profilerInfo, options,
3485            UserHandle.getCallingUserId());
3486    }
3487
3488    @Override
3489    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3490            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3491            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3492        enforceNotIsolatedCaller("startActivity");
3493        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3494                false, ALLOW_FULL_ONLY, "startActivity", null);
3495        // TODO: Switch to user app stacks here.
3496        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3497                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3498                profilerInfo, null, null, options, userId, null, null);
3499    }
3500
3501    @Override
3502    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3503            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3504            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3505
3506        // This is very dangerous -- it allows you to perform a start activity (including
3507        // permission grants) as any app that may launch one of your own activities.  So
3508        // we will only allow this to be done from activities that are part of the core framework,
3509        // and then only when they are running as the system.
3510        final ActivityRecord sourceRecord;
3511        final int targetUid;
3512        final String targetPackage;
3513        synchronized (this) {
3514            if (resultTo == null) {
3515                throw new SecurityException("Must be called from an activity");
3516            }
3517            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3518            if (sourceRecord == null) {
3519                throw new SecurityException("Called with bad activity token: " + resultTo);
3520            }
3521            if (!sourceRecord.info.packageName.equals("android")) {
3522                throw new SecurityException(
3523                        "Must be called from an activity that is declared in the android package");
3524            }
3525            if (sourceRecord.app == null) {
3526                throw new SecurityException("Called without a process attached to activity");
3527            }
3528            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3529                // This is still okay, as long as this activity is running under the
3530                // uid of the original calling activity.
3531                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3532                    throw new SecurityException(
3533                            "Calling activity in uid " + sourceRecord.app.uid
3534                                    + " must be system uid or original calling uid "
3535                                    + sourceRecord.launchedFromUid);
3536                }
3537            }
3538            targetUid = sourceRecord.launchedFromUid;
3539            targetPackage = sourceRecord.launchedFromPackage;
3540        }
3541
3542        // TODO: Switch to user app stacks here.
3543        try {
3544            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3545                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3546                    null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null);
3547            return ret;
3548        } catch (SecurityException e) {
3549            // XXX need to figure out how to propagate to original app.
3550            // A SecurityException here is generally actually a fault of the original
3551            // calling activity (such as a fairly granting permissions), so propagate it
3552            // back to them.
3553            /*
3554            StringBuilder msg = new StringBuilder();
3555            msg.append("While launching");
3556            msg.append(intent.toString());
3557            msg.append(": ");
3558            msg.append(e.getMessage());
3559            */
3560            throw e;
3561        }
3562    }
3563
3564    @Override
3565    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3566            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3567            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3568        enforceNotIsolatedCaller("startActivityAndWait");
3569        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3570                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3571        WaitResult res = new WaitResult();
3572        // TODO: Switch to user app stacks here.
3573        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3574                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3575                options, userId, null, null);
3576        return res;
3577    }
3578
3579    @Override
3580    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3581            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3582            int startFlags, Configuration config, Bundle options, int userId) {
3583        enforceNotIsolatedCaller("startActivityWithConfig");
3584        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3585                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3586        // TODO: Switch to user app stacks here.
3587        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3588                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3589                null, null, config, options, userId, null, null);
3590        return ret;
3591    }
3592
3593    @Override
3594    public int startActivityIntentSender(IApplicationThread caller,
3595            IntentSender intent, Intent fillInIntent, String resolvedType,
3596            IBinder resultTo, String resultWho, int requestCode,
3597            int flagsMask, int flagsValues, Bundle options) {
3598        enforceNotIsolatedCaller("startActivityIntentSender");
3599        // Refuse possible leaked file descriptors
3600        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3601            throw new IllegalArgumentException("File descriptors passed in Intent");
3602        }
3603
3604        IIntentSender sender = intent.getTarget();
3605        if (!(sender instanceof PendingIntentRecord)) {
3606            throw new IllegalArgumentException("Bad PendingIntent object");
3607        }
3608
3609        PendingIntentRecord pir = (PendingIntentRecord)sender;
3610
3611        synchronized (this) {
3612            // If this is coming from the currently resumed activity, it is
3613            // effectively saying that app switches are allowed at this point.
3614            final ActivityStack stack = getFocusedStack();
3615            if (stack.mResumedActivity != null &&
3616                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3617                mAppSwitchesAllowedTime = 0;
3618            }
3619        }
3620        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3621                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3622        return ret;
3623    }
3624
3625    @Override
3626    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3627            Intent intent, String resolvedType, IVoiceInteractionSession session,
3628            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3629            Bundle options, int userId) {
3630        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3631                != PackageManager.PERMISSION_GRANTED) {
3632            String msg = "Permission Denial: startVoiceActivity() from pid="
3633                    + Binder.getCallingPid()
3634                    + ", uid=" + Binder.getCallingUid()
3635                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3636            Slog.w(TAG, msg);
3637            throw new SecurityException(msg);
3638        }
3639        if (session == null || interactor == null) {
3640            throw new NullPointerException("null session or interactor");
3641        }
3642        userId = handleIncomingUser(callingPid, callingUid, userId,
3643                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3644        // TODO: Switch to user app stacks here.
3645        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3646                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3647                null, options, userId, null, null);
3648    }
3649
3650    @Override
3651    public boolean startNextMatchingActivity(IBinder callingActivity,
3652            Intent intent, Bundle options) {
3653        // Refuse possible leaked file descriptors
3654        if (intent != null && intent.hasFileDescriptors() == true) {
3655            throw new IllegalArgumentException("File descriptors passed in Intent");
3656        }
3657
3658        synchronized (this) {
3659            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3660            if (r == null) {
3661                ActivityOptions.abort(options);
3662                return false;
3663            }
3664            if (r.app == null || r.app.thread == null) {
3665                // The caller is not running...  d'oh!
3666                ActivityOptions.abort(options);
3667                return false;
3668            }
3669            intent = new Intent(intent);
3670            // The caller is not allowed to change the data.
3671            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3672            // And we are resetting to find the next component...
3673            intent.setComponent(null);
3674
3675            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3676
3677            ActivityInfo aInfo = null;
3678            try {
3679                List<ResolveInfo> resolves =
3680                    AppGlobals.getPackageManager().queryIntentActivities(
3681                            intent, r.resolvedType,
3682                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3683                            UserHandle.getCallingUserId());
3684
3685                // Look for the original activity in the list...
3686                final int N = resolves != null ? resolves.size() : 0;
3687                for (int i=0; i<N; i++) {
3688                    ResolveInfo rInfo = resolves.get(i);
3689                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3690                            && rInfo.activityInfo.name.equals(r.info.name)) {
3691                        // We found the current one...  the next matching is
3692                        // after it.
3693                        i++;
3694                        if (i<N) {
3695                            aInfo = resolves.get(i).activityInfo;
3696                        }
3697                        if (debug) {
3698                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3699                                    + "/" + r.info.name);
3700                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3701                                    + "/" + aInfo.name);
3702                        }
3703                        break;
3704                    }
3705                }
3706            } catch (RemoteException e) {
3707            }
3708
3709            if (aInfo == null) {
3710                // Nobody who is next!
3711                ActivityOptions.abort(options);
3712                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3713                return false;
3714            }
3715
3716            intent.setComponent(new ComponentName(
3717                    aInfo.applicationInfo.packageName, aInfo.name));
3718            intent.setFlags(intent.getFlags()&~(
3719                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3720                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3721                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3722                    Intent.FLAG_ACTIVITY_NEW_TASK));
3723
3724            // Okay now we need to start the new activity, replacing the
3725            // currently running activity.  This is a little tricky because
3726            // we want to start the new one as if the current one is finished,
3727            // but not finish the current one first so that there is no flicker.
3728            // And thus...
3729            final boolean wasFinishing = r.finishing;
3730            r.finishing = true;
3731
3732            // Propagate reply information over to the new activity.
3733            final ActivityRecord resultTo = r.resultTo;
3734            final String resultWho = r.resultWho;
3735            final int requestCode = r.requestCode;
3736            r.resultTo = null;
3737            if (resultTo != null) {
3738                resultTo.removeResultsLocked(r, resultWho, requestCode);
3739            }
3740
3741            final long origId = Binder.clearCallingIdentity();
3742            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3743                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3744                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3745                    options, false, null, null, null);
3746            Binder.restoreCallingIdentity(origId);
3747
3748            r.finishing = wasFinishing;
3749            if (res != ActivityManager.START_SUCCESS) {
3750                return false;
3751            }
3752            return true;
3753        }
3754    }
3755
3756    @Override
3757    public final int startActivityFromRecents(int taskId, Bundle options) {
3758        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3759            String msg = "Permission Denial: startActivityFromRecents called without " +
3760                    START_TASKS_FROM_RECENTS;
3761            Slog.w(TAG, msg);
3762            throw new SecurityException(msg);
3763        }
3764        return startActivityFromRecentsInner(taskId, options);
3765    }
3766
3767    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3768        final TaskRecord task;
3769        final int callingUid;
3770        final String callingPackage;
3771        final Intent intent;
3772        final int userId;
3773        synchronized (this) {
3774            task = recentTaskForIdLocked(taskId);
3775            if (task == null) {
3776                throw new IllegalArgumentException("Task " + taskId + " not found.");
3777            }
3778            callingUid = task.mCallingUid;
3779            callingPackage = task.mCallingPackage;
3780            intent = task.intent;
3781            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3782            userId = task.userId;
3783        }
3784        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3785                options, userId, null, task);
3786    }
3787
3788    final int startActivityInPackage(int uid, String callingPackage,
3789            Intent intent, String resolvedType, IBinder resultTo,
3790            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3791            IActivityContainer container, TaskRecord inTask) {
3792
3793        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3794                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3795
3796        // TODO: Switch to user app stacks here.
3797        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3798                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3799                null, null, null, options, userId, container, inTask);
3800        return ret;
3801    }
3802
3803    @Override
3804    public final int startActivities(IApplicationThread caller, String callingPackage,
3805            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3806            int userId) {
3807        enforceNotIsolatedCaller("startActivities");
3808        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3809                false, ALLOW_FULL_ONLY, "startActivity", null);
3810        // TODO: Switch to user app stacks here.
3811        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3812                resolvedTypes, resultTo, options, userId);
3813        return ret;
3814    }
3815
3816    final int startActivitiesInPackage(int uid, String callingPackage,
3817            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3818            Bundle options, int userId) {
3819
3820        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3821                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3822        // TODO: Switch to user app stacks here.
3823        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3824                resultTo, options, userId);
3825        return ret;
3826    }
3827
3828    //explicitly remove thd old information in mRecentTasks when removing existing user.
3829    private void removeRecentTasksForUserLocked(int userId) {
3830        if(userId <= 0) {
3831            Slog.i(TAG, "Can't remove recent task on user " + userId);
3832            return;
3833        }
3834
3835        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3836            TaskRecord tr = mRecentTasks.get(i);
3837            if (tr.userId == userId) {
3838                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3839                        + " when finishing user" + userId);
3840                mRecentTasks.remove(i);
3841                tr.removedFromRecents(mTaskPersister);
3842            }
3843        }
3844
3845        // Remove tasks from persistent storage.
3846        mTaskPersister.wakeup(null, true);
3847    }
3848
3849    /**
3850     * Update the recent tasks lists: make sure tasks should still be here (their
3851     * applications / activities still exist), update their availability, fixup ordering
3852     * of affiliations.
3853     */
3854    void cleanupRecentTasksLocked(int userId) {
3855        if (mRecentTasks == null) {
3856            // Happens when called from the packagemanager broadcast before boot.
3857            return;
3858        }
3859
3860        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3861        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3862        final IPackageManager pm = AppGlobals.getPackageManager();
3863        final ActivityInfo dummyAct = new ActivityInfo();
3864        final ApplicationInfo dummyApp = new ApplicationInfo();
3865
3866        int N = mRecentTasks.size();
3867
3868        int[] users = userId == UserHandle.USER_ALL
3869                ? getUsersLocked() : new int[] { userId };
3870        for (int user : users) {
3871            for (int i = 0; i < N; i++) {
3872                TaskRecord task = mRecentTasks.get(i);
3873                if (task.userId != user) {
3874                    // Only look at tasks for the user ID of interest.
3875                    continue;
3876                }
3877                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3878                    // This situation is broken, and we should just get rid of it now.
3879                    mRecentTasks.remove(i);
3880                    task.removedFromRecents(mTaskPersister);
3881                    i--;
3882                    N--;
3883                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3884                    continue;
3885                }
3886                // Check whether this activity is currently available.
3887                if (task.realActivity != null) {
3888                    ActivityInfo ai = availActCache.get(task.realActivity);
3889                    if (ai == null) {
3890                        try {
3891                            ai = pm.getActivityInfo(task.realActivity,
3892                                    PackageManager.GET_UNINSTALLED_PACKAGES
3893                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3894                        } catch (RemoteException e) {
3895                            // Will never happen.
3896                            continue;
3897                        }
3898                        if (ai == null) {
3899                            ai = dummyAct;
3900                        }
3901                        availActCache.put(task.realActivity, ai);
3902                    }
3903                    if (ai == dummyAct) {
3904                        // This could be either because the activity no longer exists, or the
3905                        // app is temporarily gone.  For the former we want to remove the recents
3906                        // entry; for the latter we want to mark it as unavailable.
3907                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3908                        if (app == null) {
3909                            try {
3910                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3911                                        PackageManager.GET_UNINSTALLED_PACKAGES
3912                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3913                            } catch (RemoteException e) {
3914                                // Will never happen.
3915                                continue;
3916                            }
3917                            if (app == null) {
3918                                app = dummyApp;
3919                            }
3920                            availAppCache.put(task.realActivity.getPackageName(), app);
3921                        }
3922                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3923                            // Doesn't exist any more!  Good-bye.
3924                            mRecentTasks.remove(i);
3925                            task.removedFromRecents(mTaskPersister);
3926                            i--;
3927                            N--;
3928                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3929                            continue;
3930                        } else {
3931                            // Otherwise just not available for now.
3932                            if (task.isAvailable) {
3933                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3934                                        + task);
3935                            }
3936                            task.isAvailable = false;
3937                        }
3938                    } else {
3939                        if (!ai.enabled || !ai.applicationInfo.enabled
3940                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3941                            if (task.isAvailable) {
3942                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3943                                        + task + " (enabled=" + ai.enabled + "/"
3944                                        + ai.applicationInfo.enabled +  " flags="
3945                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3946                            }
3947                            task.isAvailable = false;
3948                        } else {
3949                            if (!task.isAvailable) {
3950                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3951                                        + task);
3952                            }
3953                            task.isAvailable = true;
3954                        }
3955                    }
3956                }
3957            }
3958        }
3959
3960        // Verify the affiliate chain for each task.
3961        for (int i = 0; i < N; ) {
3962            TaskRecord task = mRecentTasks.remove(i);
3963            if (mTmpRecents.contains(task)) {
3964                continue;
3965            }
3966            int affiliatedTaskId = task.mAffiliatedTaskId;
3967            while (true) {
3968                TaskRecord next = task.mNextAffiliate;
3969                if (next == null) {
3970                    break;
3971                }
3972                if (next.mAffiliatedTaskId != affiliatedTaskId) {
3973                    Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
3974                            next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
3975                    task.setNextAffiliate(null);
3976                    if (next.mPrevAffiliate == task) {
3977                        next.setPrevAffiliate(null);
3978                    }
3979                    break;
3980                }
3981                if (next.mPrevAffiliate != task) {
3982                    Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
3983                            next.mPrevAffiliate + " task=" + task);
3984                    next.setPrevAffiliate(null);
3985                    task.setNextAffiliate(null);
3986                    break;
3987                }
3988                if (!mRecentTasks.contains(next)) {
3989                    Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
3990                    task.setNextAffiliate(null);
3991                    // We know that next.mPrevAffiliate is always task, from above, so clear
3992                    // its previous affiliate.
3993                    next.setPrevAffiliate(null);
3994                    break;
3995                }
3996                task = next;
3997            }
3998            // task is now the end of the list
3999            do {
4000                mRecentTasks.remove(task);
4001                mRecentTasks.add(i++, task);
4002                mTmpRecents.add(task);
4003                task.inRecents = true;
4004            } while ((task = task.mPrevAffiliate) != null);
4005        }
4006        mTmpRecents.clear();
4007        // mRecentTasks is now in sorted, affiliated order.
4008    }
4009
4010    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
4011        int N = mRecentTasks.size();
4012        TaskRecord top = task;
4013        int topIndex = taskIndex;
4014        while (top.mNextAffiliate != null && topIndex > 0) {
4015            top = top.mNextAffiliate;
4016            topIndex--;
4017        }
4018        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
4019                + topIndex + " from intial " + taskIndex);
4020        // Find the end of the chain, doing a sanity check along the way.
4021        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
4022        int endIndex = topIndex;
4023        TaskRecord prev = top;
4024        while (endIndex < N) {
4025            TaskRecord cur = mRecentTasks.get(endIndex);
4026            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
4027                    + endIndex + " " + cur);
4028            if (cur == top) {
4029                // Verify start of the chain.
4030                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
4031                    Slog.wtf(TAG, "Bad chain @" + endIndex
4032                            + ": first task has next affiliate: " + prev);
4033                    sane = false;
4034                    break;
4035                }
4036            } else {
4037                // Verify middle of the chain's next points back to the one before.
4038                if (cur.mNextAffiliate != prev
4039                        || cur.mNextAffiliateTaskId != prev.taskId) {
4040                    Slog.wtf(TAG, "Bad chain @" + endIndex
4041                            + ": middle task " + cur + " @" + endIndex
4042                            + " has bad next affiliate "
4043                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4044                            + ", expected " + prev);
4045                    sane = false;
4046                    break;
4047                }
4048            }
4049            if (cur.mPrevAffiliateTaskId == -1) {
4050                // Chain ends here.
4051                if (cur.mPrevAffiliate != null) {
4052                    Slog.wtf(TAG, "Bad chain @" + endIndex
4053                            + ": last task " + cur + " has previous affiliate "
4054                            + cur.mPrevAffiliate);
4055                    sane = false;
4056                }
4057                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4058                break;
4059            } else {
4060                // Verify middle of the chain's prev points to a valid item.
4061                if (cur.mPrevAffiliate == null) {
4062                    Slog.wtf(TAG, "Bad chain @" + endIndex
4063                            + ": task " + cur + " has previous affiliate "
4064                            + cur.mPrevAffiliate + " but should be id "
4065                            + cur.mPrevAffiliate);
4066                    sane = false;
4067                    break;
4068                }
4069            }
4070            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4071                Slog.wtf(TAG, "Bad chain @" + endIndex
4072                        + ": task " + cur + " has affiliated id "
4073                        + cur.mAffiliatedTaskId + " but should be "
4074                        + task.mAffiliatedTaskId);
4075                sane = false;
4076                break;
4077            }
4078            prev = cur;
4079            endIndex++;
4080            if (endIndex >= N) {
4081                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4082                        + ": last task " + prev);
4083                sane = false;
4084                break;
4085            }
4086        }
4087        if (sane) {
4088            if (endIndex < taskIndex) {
4089                Slog.wtf(TAG, "Bad chain @" + endIndex
4090                        + ": did not extend to task " + task + " @" + taskIndex);
4091                sane = false;
4092            }
4093        }
4094        if (sane) {
4095            // All looks good, we can just move all of the affiliated tasks
4096            // to the top.
4097            for (int i=topIndex; i<=endIndex; i++) {
4098                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4099                        + " from " + i + " to " + (i-topIndex));
4100                TaskRecord cur = mRecentTasks.remove(i);
4101                mRecentTasks.add(i-topIndex, cur);
4102            }
4103            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4104                    + " to " + endIndex);
4105            return true;
4106        }
4107
4108        // Whoops, couldn't do it.
4109        return false;
4110    }
4111
4112    final void addRecentTaskLocked(TaskRecord task) {
4113        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4114                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4115
4116        int N = mRecentTasks.size();
4117        // Quick case: check if the top-most recent task is the same.
4118        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4119            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4120            return;
4121        }
4122        // Another quick case: check if this is part of a set of affiliated
4123        // tasks that are at the top.
4124        if (isAffiliated && N > 0 && task.inRecents
4125                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4126            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4127                    + " at top when adding " + task);
4128            return;
4129        }
4130        // Another quick case: never add voice sessions.
4131        if (task.voiceSession != null) {
4132            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4133            return;
4134        }
4135
4136        boolean needAffiliationFix = false;
4137
4138        // Slightly less quick case: the task is already in recents, so all we need
4139        // to do is move it.
4140        if (task.inRecents) {
4141            int taskIndex = mRecentTasks.indexOf(task);
4142            if (taskIndex >= 0) {
4143                if (!isAffiliated) {
4144                    // Simple case: this is not an affiliated task, so we just move it to the front.
4145                    mRecentTasks.remove(taskIndex);
4146                    mRecentTasks.add(0, task);
4147                    notifyTaskPersisterLocked(task, false);
4148                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4149                            + " from " + taskIndex);
4150                    return;
4151                } else {
4152                    // More complicated: need to keep all affiliated tasks together.
4153                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4154                        // All went well.
4155                        return;
4156                    }
4157
4158                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4159                    // everything and then go through our general path of adding a new task.
4160                    needAffiliationFix = true;
4161                }
4162            } else {
4163                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4164                needAffiliationFix = true;
4165            }
4166        }
4167
4168        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4169        trimRecentsForTask(task, true);
4170
4171        N = mRecentTasks.size();
4172        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4173            final TaskRecord tr = mRecentTasks.remove(N - 1);
4174            tr.removedFromRecents(mTaskPersister);
4175            N--;
4176        }
4177        task.inRecents = true;
4178        if (!isAffiliated || needAffiliationFix) {
4179            // If this is a simple non-affiliated task, or we had some failure trying to
4180            // handle it as part of an affilated task, then just place it at the top.
4181            mRecentTasks.add(0, task);
4182        } else if (isAffiliated) {
4183            // If this is a new affiliated task, then move all of the affiliated tasks
4184            // to the front and insert this new one.
4185            TaskRecord other = task.mNextAffiliate;
4186            if (other == null) {
4187                other = task.mPrevAffiliate;
4188            }
4189            if (other != null) {
4190                int otherIndex = mRecentTasks.indexOf(other);
4191                if (otherIndex >= 0) {
4192                    // Insert new task at appropriate location.
4193                    int taskIndex;
4194                    if (other == task.mNextAffiliate) {
4195                        // We found the index of our next affiliation, which is who is
4196                        // before us in the list, so add after that point.
4197                        taskIndex = otherIndex+1;
4198                    } else {
4199                        // We found the index of our previous affiliation, which is who is
4200                        // after us in the list, so add at their position.
4201                        taskIndex = otherIndex;
4202                    }
4203                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4204                            + taskIndex + ": " + task);
4205                    mRecentTasks.add(taskIndex, task);
4206
4207                    // Now move everything to the front.
4208                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4209                        // All went well.
4210                        return;
4211                    }
4212
4213                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4214                    // everything and then go through our general path of adding a new task.
4215                    needAffiliationFix = true;
4216                } else {
4217                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4218                            + other);
4219                    needAffiliationFix = true;
4220                }
4221            } else {
4222                if (DEBUG_RECENTS) Slog.d(TAG,
4223                        "addRecent: adding affiliated task without next/prev:" + task);
4224                needAffiliationFix = true;
4225            }
4226        }
4227        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4228
4229        if (needAffiliationFix) {
4230            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4231            cleanupRecentTasksLocked(task.userId);
4232        }
4233    }
4234
4235    /**
4236     * If needed, remove oldest existing entries in recents that are for the same kind
4237     * of task as the given one.
4238     */
4239    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4240        int N = mRecentTasks.size();
4241        final Intent intent = task.intent;
4242        final boolean document = intent != null && intent.isDocument();
4243
4244        int maxRecents = task.maxRecents - 1;
4245        for (int i=0; i<N; i++) {
4246            final TaskRecord tr = mRecentTasks.get(i);
4247            if (task != tr) {
4248                if (task.userId != tr.userId) {
4249                    continue;
4250                }
4251                if (i > MAX_RECENT_BITMAPS) {
4252                    tr.freeLastThumbnail();
4253                }
4254                final Intent trIntent = tr.intent;
4255                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4256                    (intent == null || !intent.filterEquals(trIntent))) {
4257                    continue;
4258                }
4259                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4260                if (document && trIsDocument) {
4261                    // These are the same document activity (not necessarily the same doc).
4262                    if (maxRecents > 0) {
4263                        --maxRecents;
4264                        continue;
4265                    }
4266                    // Hit the maximum number of documents for this task. Fall through
4267                    // and remove this document from recents.
4268                } else if (document || trIsDocument) {
4269                    // Only one of these is a document. Not the droid we're looking for.
4270                    continue;
4271                }
4272            }
4273
4274            if (!doTrim) {
4275                // If the caller is not actually asking for a trim, just tell them we reached
4276                // a point where the trim would happen.
4277                return i;
4278            }
4279
4280            // Either task and tr are the same or, their affinities match or their intents match
4281            // and neither of them is a document, or they are documents using the same activity
4282            // and their maxRecents has been reached.
4283            tr.disposeThumbnail();
4284            mRecentTasks.remove(i);
4285            if (task != tr) {
4286                tr.removedFromRecents(mTaskPersister);
4287            }
4288            i--;
4289            N--;
4290            if (task.intent == null) {
4291                // If the new recent task we are adding is not fully
4292                // specified, then replace it with the existing recent task.
4293                task = tr;
4294            }
4295            notifyTaskPersisterLocked(tr, false);
4296        }
4297
4298        return -1;
4299    }
4300
4301    @Override
4302    public void reportActivityFullyDrawn(IBinder token) {
4303        synchronized (this) {
4304            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4305            if (r == null) {
4306                return;
4307            }
4308            r.reportFullyDrawnLocked();
4309        }
4310    }
4311
4312    @Override
4313    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4314        synchronized (this) {
4315            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4316            if (r == null) {
4317                return;
4318            }
4319            final long origId = Binder.clearCallingIdentity();
4320            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4321            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4322                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4323            if (config != null) {
4324                r.frozenBeforeDestroy = true;
4325                if (!updateConfigurationLocked(config, r, false, false)) {
4326                    mStackSupervisor.resumeTopActivitiesLocked();
4327                }
4328            }
4329            Binder.restoreCallingIdentity(origId);
4330        }
4331    }
4332
4333    @Override
4334    public int getRequestedOrientation(IBinder token) {
4335        synchronized (this) {
4336            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4337            if (r == null) {
4338                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4339            }
4340            return mWindowManager.getAppOrientation(r.appToken);
4341        }
4342    }
4343
4344    /**
4345     * This is the internal entry point for handling Activity.finish().
4346     *
4347     * @param token The Binder token referencing the Activity we want to finish.
4348     * @param resultCode Result code, if any, from this Activity.
4349     * @param resultData Result data (Intent), if any, from this Activity.
4350     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4351     *            the root Activity in the task.
4352     *
4353     * @return Returns true if the activity successfully finished, or false if it is still running.
4354     */
4355    @Override
4356    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4357            boolean finishTask) {
4358        // Refuse possible leaked file descriptors
4359        if (resultData != null && resultData.hasFileDescriptors() == true) {
4360            throw new IllegalArgumentException("File descriptors passed in Intent");
4361        }
4362
4363        synchronized(this) {
4364            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4365            if (r == null) {
4366                return true;
4367            }
4368            // Keep track of the root activity of the task before we finish it
4369            TaskRecord tr = r.task;
4370            ActivityRecord rootR = tr.getRootActivity();
4371            // Do not allow task to finish in Lock Task mode.
4372            if (tr == mStackSupervisor.mLockTaskModeTask) {
4373                if (rootR == r) {
4374                    mStackSupervisor.showLockTaskToast();
4375                    return false;
4376                }
4377            }
4378            if (mController != null) {
4379                // Find the first activity that is not finishing.
4380                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4381                if (next != null) {
4382                    // ask watcher if this is allowed
4383                    boolean resumeOK = true;
4384                    try {
4385                        resumeOK = mController.activityResuming(next.packageName);
4386                    } catch (RemoteException e) {
4387                        mController = null;
4388                        Watchdog.getInstance().setActivityController(null);
4389                    }
4390
4391                    if (!resumeOK) {
4392                        return false;
4393                    }
4394                }
4395            }
4396            final long origId = Binder.clearCallingIdentity();
4397            try {
4398                boolean res;
4399                if (finishTask && r == rootR) {
4400                    // If requested, remove the task that is associated to this activity only if it
4401                    // was the root activity in the task.  The result code and data is ignored because
4402                    // we don't support returning them across task boundaries.
4403                    res = removeTaskByIdLocked(tr.taskId, 0);
4404                } else {
4405                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4406                            resultData, "app-request", true);
4407                }
4408                return res;
4409            } finally {
4410                Binder.restoreCallingIdentity(origId);
4411            }
4412        }
4413    }
4414
4415    @Override
4416    public final void finishHeavyWeightApp() {
4417        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4418                != PackageManager.PERMISSION_GRANTED) {
4419            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4420                    + Binder.getCallingPid()
4421                    + ", uid=" + Binder.getCallingUid()
4422                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4423            Slog.w(TAG, msg);
4424            throw new SecurityException(msg);
4425        }
4426
4427        synchronized(this) {
4428            if (mHeavyWeightProcess == null) {
4429                return;
4430            }
4431
4432            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4433                    mHeavyWeightProcess.activities);
4434            for (int i=0; i<activities.size(); i++) {
4435                ActivityRecord r = activities.get(i);
4436                if (!r.finishing) {
4437                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4438                            null, "finish-heavy", true);
4439                }
4440            }
4441
4442            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4443                    mHeavyWeightProcess.userId, 0));
4444            mHeavyWeightProcess = null;
4445        }
4446    }
4447
4448    @Override
4449    public void crashApplication(int uid, int initialPid, String packageName,
4450            String message) {
4451        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4452                != PackageManager.PERMISSION_GRANTED) {
4453            String msg = "Permission Denial: crashApplication() from pid="
4454                    + Binder.getCallingPid()
4455                    + ", uid=" + Binder.getCallingUid()
4456                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4457            Slog.w(TAG, msg);
4458            throw new SecurityException(msg);
4459        }
4460
4461        synchronized(this) {
4462            ProcessRecord proc = null;
4463
4464            // Figure out which process to kill.  We don't trust that initialPid
4465            // still has any relation to current pids, so must scan through the
4466            // list.
4467            synchronized (mPidsSelfLocked) {
4468                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4469                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4470                    if (p.uid != uid) {
4471                        continue;
4472                    }
4473                    if (p.pid == initialPid) {
4474                        proc = p;
4475                        break;
4476                    }
4477                    if (p.pkgList.containsKey(packageName)) {
4478                        proc = p;
4479                    }
4480                }
4481            }
4482
4483            if (proc == null) {
4484                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4485                        + " initialPid=" + initialPid
4486                        + " packageName=" + packageName);
4487                return;
4488            }
4489
4490            if (proc.thread != null) {
4491                if (proc.pid == Process.myPid()) {
4492                    Log.w(TAG, "crashApplication: trying to crash self!");
4493                    return;
4494                }
4495                long ident = Binder.clearCallingIdentity();
4496                try {
4497                    proc.thread.scheduleCrash(message);
4498                } catch (RemoteException e) {
4499                }
4500                Binder.restoreCallingIdentity(ident);
4501            }
4502        }
4503    }
4504
4505    @Override
4506    public final void finishSubActivity(IBinder token, String resultWho,
4507            int requestCode) {
4508        synchronized(this) {
4509            final long origId = Binder.clearCallingIdentity();
4510            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4511            if (r != null) {
4512                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4513            }
4514            Binder.restoreCallingIdentity(origId);
4515        }
4516    }
4517
4518    @Override
4519    public boolean finishActivityAffinity(IBinder token) {
4520        synchronized(this) {
4521            final long origId = Binder.clearCallingIdentity();
4522            try {
4523                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4524
4525                ActivityRecord rootR = r.task.getRootActivity();
4526                // Do not allow task to finish in Lock Task mode.
4527                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4528                    if (rootR == r) {
4529                        mStackSupervisor.showLockTaskToast();
4530                        return false;
4531                    }
4532                }
4533                boolean res = false;
4534                if (r != null) {
4535                    res = r.task.stack.finishActivityAffinityLocked(r);
4536                }
4537                return res;
4538            } finally {
4539                Binder.restoreCallingIdentity(origId);
4540            }
4541        }
4542    }
4543
4544    @Override
4545    public void finishVoiceTask(IVoiceInteractionSession session) {
4546        synchronized(this) {
4547            final long origId = Binder.clearCallingIdentity();
4548            try {
4549                mStackSupervisor.finishVoiceTask(session);
4550            } finally {
4551                Binder.restoreCallingIdentity(origId);
4552            }
4553        }
4554
4555    }
4556
4557    @Override
4558    public boolean releaseActivityInstance(IBinder token) {
4559        synchronized(this) {
4560            final long origId = Binder.clearCallingIdentity();
4561            try {
4562                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4563                if (r.task == null || r.task.stack == null) {
4564                    return false;
4565                }
4566                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4567            } finally {
4568                Binder.restoreCallingIdentity(origId);
4569            }
4570        }
4571    }
4572
4573    @Override
4574    public void releaseSomeActivities(IApplicationThread appInt) {
4575        synchronized(this) {
4576            final long origId = Binder.clearCallingIdentity();
4577            try {
4578                ProcessRecord app = getRecordForAppLocked(appInt);
4579                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4580            } finally {
4581                Binder.restoreCallingIdentity(origId);
4582            }
4583        }
4584    }
4585
4586    @Override
4587    public boolean willActivityBeVisible(IBinder token) {
4588        synchronized(this) {
4589            ActivityStack stack = ActivityRecord.getStackLocked(token);
4590            if (stack != null) {
4591                return stack.willActivityBeVisibleLocked(token);
4592            }
4593            return false;
4594        }
4595    }
4596
4597    @Override
4598    public void overridePendingTransition(IBinder token, String packageName,
4599            int enterAnim, int exitAnim) {
4600        synchronized(this) {
4601            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4602            if (self == null) {
4603                return;
4604            }
4605
4606            final long origId = Binder.clearCallingIdentity();
4607
4608            if (self.state == ActivityState.RESUMED
4609                    || self.state == ActivityState.PAUSING) {
4610                mWindowManager.overridePendingAppTransition(packageName,
4611                        enterAnim, exitAnim, null);
4612            }
4613
4614            Binder.restoreCallingIdentity(origId);
4615        }
4616    }
4617
4618    /**
4619     * Main function for removing an existing process from the activity manager
4620     * as a result of that process going away.  Clears out all connections
4621     * to the process.
4622     */
4623    private final void handleAppDiedLocked(ProcessRecord app,
4624            boolean restarting, boolean allowRestart) {
4625        int pid = app.pid;
4626        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4627        if (!restarting) {
4628            removeLruProcessLocked(app);
4629            if (pid > 0) {
4630                ProcessList.remove(pid);
4631            }
4632        }
4633
4634        if (mProfileProc == app) {
4635            clearProfilerLocked();
4636        }
4637
4638        // Remove this application's activities from active lists.
4639        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4640
4641        app.activities.clear();
4642
4643        if (app.instrumentationClass != null) {
4644            Slog.w(TAG, "Crash of app " + app.processName
4645                  + " running instrumentation " + app.instrumentationClass);
4646            Bundle info = new Bundle();
4647            info.putString("shortMsg", "Process crashed.");
4648            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4649        }
4650
4651        if (!restarting) {
4652            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4653                // If there was nothing to resume, and we are not already
4654                // restarting this process, but there is a visible activity that
4655                // is hosted by the process...  then make sure all visible
4656                // activities are running, taking care of restarting this
4657                // process.
4658                if (hasVisibleActivities) {
4659                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4660                }
4661            }
4662        }
4663    }
4664
4665    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4666        IBinder threadBinder = thread.asBinder();
4667        // Find the application record.
4668        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4669            ProcessRecord rec = mLruProcesses.get(i);
4670            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4671                return i;
4672            }
4673        }
4674        return -1;
4675    }
4676
4677    final ProcessRecord getRecordForAppLocked(
4678            IApplicationThread thread) {
4679        if (thread == null) {
4680            return null;
4681        }
4682
4683        int appIndex = getLRURecordIndexForAppLocked(thread);
4684        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4685    }
4686
4687    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4688        // If there are no longer any background processes running,
4689        // and the app that died was not running instrumentation,
4690        // then tell everyone we are now low on memory.
4691        boolean haveBg = false;
4692        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4693            ProcessRecord rec = mLruProcesses.get(i);
4694            if (rec.thread != null
4695                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4696                haveBg = true;
4697                break;
4698            }
4699        }
4700
4701        if (!haveBg) {
4702            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4703            if (doReport) {
4704                long now = SystemClock.uptimeMillis();
4705                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4706                    doReport = false;
4707                } else {
4708                    mLastMemUsageReportTime = now;
4709                }
4710            }
4711            final ArrayList<ProcessMemInfo> memInfos
4712                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4713            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4714            long now = SystemClock.uptimeMillis();
4715            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4716                ProcessRecord rec = mLruProcesses.get(i);
4717                if (rec == dyingProc || rec.thread == null) {
4718                    continue;
4719                }
4720                if (doReport) {
4721                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4722                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4723                }
4724                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4725                    // The low memory report is overriding any current
4726                    // state for a GC request.  Make sure to do
4727                    // heavy/important/visible/foreground processes first.
4728                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4729                        rec.lastRequestedGc = 0;
4730                    } else {
4731                        rec.lastRequestedGc = rec.lastLowMemory;
4732                    }
4733                    rec.reportLowMemory = true;
4734                    rec.lastLowMemory = now;
4735                    mProcessesToGc.remove(rec);
4736                    addProcessToGcListLocked(rec);
4737                }
4738            }
4739            if (doReport) {
4740                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4741                mHandler.sendMessage(msg);
4742            }
4743            scheduleAppGcsLocked();
4744        }
4745    }
4746
4747    final void appDiedLocked(ProcessRecord app) {
4748       appDiedLocked(app, app.pid, app.thread);
4749    }
4750
4751    final void appDiedLocked(ProcessRecord app, int pid,
4752            IApplicationThread thread) {
4753
4754        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4755        synchronized (stats) {
4756            stats.noteProcessDiedLocked(app.info.uid, pid);
4757        }
4758
4759        Process.killProcessGroup(app.info.uid, pid);
4760
4761        // Clean up already done if the process has been re-started.
4762        if (app.pid == pid && app.thread != null &&
4763                app.thread.asBinder() == thread.asBinder()) {
4764            boolean doLowMem = app.instrumentationClass == null;
4765            boolean doOomAdj = doLowMem;
4766            if (!app.killedByAm) {
4767                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4768                        + ") has died.");
4769                mAllowLowerMemLevel = true;
4770            } else {
4771                // Note that we always want to do oom adj to update our state with the
4772                // new number of procs.
4773                mAllowLowerMemLevel = false;
4774                doLowMem = false;
4775            }
4776            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4777            if (DEBUG_CLEANUP) Slog.v(
4778                TAG, "Dying app: " + app + ", pid: " + pid
4779                + ", thread: " + thread.asBinder());
4780            handleAppDiedLocked(app, false, true);
4781
4782            if (doOomAdj) {
4783                updateOomAdjLocked();
4784            }
4785            if (doLowMem) {
4786                doLowMemReportIfNeededLocked(app);
4787            }
4788        } else if (app.pid != pid) {
4789            // A new process has already been started.
4790            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4791                    + ") has died and restarted (pid " + app.pid + ").");
4792            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4793        } else if (DEBUG_PROCESSES) {
4794            Slog.d(TAG, "Received spurious death notification for thread "
4795                    + thread.asBinder());
4796        }
4797    }
4798
4799    /**
4800     * If a stack trace dump file is configured, dump process stack traces.
4801     * @param clearTraces causes the dump file to be erased prior to the new
4802     *    traces being written, if true; when false, the new traces will be
4803     *    appended to any existing file content.
4804     * @param firstPids of dalvik VM processes to dump stack traces for first
4805     * @param lastPids of dalvik VM processes to dump stack traces for last
4806     * @param nativeProcs optional list of native process names to dump stack crawls
4807     * @return file containing stack traces, or null if no dump file is configured
4808     */
4809    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4810            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4811        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4812        if (tracesPath == null || tracesPath.length() == 0) {
4813            return null;
4814        }
4815
4816        File tracesFile = new File(tracesPath);
4817        try {
4818            File tracesDir = tracesFile.getParentFile();
4819            if (!tracesDir.exists()) {
4820                tracesFile.mkdirs();
4821                if (!SELinux.restorecon(tracesDir)) {
4822                    return null;
4823                }
4824            }
4825            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4826
4827            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4828            tracesFile.createNewFile();
4829            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4830        } catch (IOException e) {
4831            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4832            return null;
4833        }
4834
4835        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4836        return tracesFile;
4837    }
4838
4839    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4840            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4841        // Use a FileObserver to detect when traces finish writing.
4842        // The order of traces is considered important to maintain for legibility.
4843        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4844            @Override
4845            public synchronized void onEvent(int event, String path) { notify(); }
4846        };
4847
4848        try {
4849            observer.startWatching();
4850
4851            // First collect all of the stacks of the most important pids.
4852            if (firstPids != null) {
4853                try {
4854                    int num = firstPids.size();
4855                    for (int i = 0; i < num; i++) {
4856                        synchronized (observer) {
4857                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4858                            observer.wait(200);  // Wait for write-close, give up after 200msec
4859                        }
4860                    }
4861                } catch (InterruptedException e) {
4862                    Log.wtf(TAG, e);
4863                }
4864            }
4865
4866            // Next collect the stacks of the native pids
4867            if (nativeProcs != null) {
4868                int[] pids = Process.getPidsForCommands(nativeProcs);
4869                if (pids != null) {
4870                    for (int pid : pids) {
4871                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4872                    }
4873                }
4874            }
4875
4876            // Lastly, measure CPU usage.
4877            if (processCpuTracker != null) {
4878                processCpuTracker.init();
4879                System.gc();
4880                processCpuTracker.update();
4881                try {
4882                    synchronized (processCpuTracker) {
4883                        processCpuTracker.wait(500); // measure over 1/2 second.
4884                    }
4885                } catch (InterruptedException e) {
4886                }
4887                processCpuTracker.update();
4888
4889                // We'll take the stack crawls of just the top apps using CPU.
4890                final int N = processCpuTracker.countWorkingStats();
4891                int numProcs = 0;
4892                for (int i=0; i<N && numProcs<5; i++) {
4893                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4894                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4895                        numProcs++;
4896                        try {
4897                            synchronized (observer) {
4898                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4899                                observer.wait(200);  // Wait for write-close, give up after 200msec
4900                            }
4901                        } catch (InterruptedException e) {
4902                            Log.wtf(TAG, e);
4903                        }
4904
4905                    }
4906                }
4907            }
4908        } finally {
4909            observer.stopWatching();
4910        }
4911    }
4912
4913    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4914        if (true || IS_USER_BUILD) {
4915            return;
4916        }
4917        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4918        if (tracesPath == null || tracesPath.length() == 0) {
4919            return;
4920        }
4921
4922        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4923        StrictMode.allowThreadDiskWrites();
4924        try {
4925            final File tracesFile = new File(tracesPath);
4926            final File tracesDir = tracesFile.getParentFile();
4927            final File tracesTmp = new File(tracesDir, "__tmp__");
4928            try {
4929                if (!tracesDir.exists()) {
4930                    tracesFile.mkdirs();
4931                    if (!SELinux.restorecon(tracesDir.getPath())) {
4932                        return;
4933                    }
4934                }
4935                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4936
4937                if (tracesFile.exists()) {
4938                    tracesTmp.delete();
4939                    tracesFile.renameTo(tracesTmp);
4940                }
4941                StringBuilder sb = new StringBuilder();
4942                Time tobj = new Time();
4943                tobj.set(System.currentTimeMillis());
4944                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4945                sb.append(": ");
4946                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4947                sb.append(" since ");
4948                sb.append(msg);
4949                FileOutputStream fos = new FileOutputStream(tracesFile);
4950                fos.write(sb.toString().getBytes());
4951                if (app == null) {
4952                    fos.write("\n*** No application process!".getBytes());
4953                }
4954                fos.close();
4955                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4956            } catch (IOException e) {
4957                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4958                return;
4959            }
4960
4961            if (app != null) {
4962                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4963                firstPids.add(app.pid);
4964                dumpStackTraces(tracesPath, firstPids, null, null, null);
4965            }
4966
4967            File lastTracesFile = null;
4968            File curTracesFile = null;
4969            for (int i=9; i>=0; i--) {
4970                String name = String.format(Locale.US, "slow%02d.txt", i);
4971                curTracesFile = new File(tracesDir, name);
4972                if (curTracesFile.exists()) {
4973                    if (lastTracesFile != null) {
4974                        curTracesFile.renameTo(lastTracesFile);
4975                    } else {
4976                        curTracesFile.delete();
4977                    }
4978                }
4979                lastTracesFile = curTracesFile;
4980            }
4981            tracesFile.renameTo(curTracesFile);
4982            if (tracesTmp.exists()) {
4983                tracesTmp.renameTo(tracesFile);
4984            }
4985        } finally {
4986            StrictMode.setThreadPolicy(oldPolicy);
4987        }
4988    }
4989
4990    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4991            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4992        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4993        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4994
4995        if (mController != null) {
4996            try {
4997                // 0 == continue, -1 = kill process immediately
4998                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4999                if (res < 0 && app.pid != MY_PID) {
5000                    app.kill("anr", true);
5001                }
5002            } catch (RemoteException e) {
5003                mController = null;
5004                Watchdog.getInstance().setActivityController(null);
5005            }
5006        }
5007
5008        long anrTime = SystemClock.uptimeMillis();
5009        if (MONITOR_CPU_USAGE) {
5010            updateCpuStatsNow();
5011        }
5012
5013        synchronized (this) {
5014            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5015            if (mShuttingDown) {
5016                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5017                return;
5018            } else if (app.notResponding) {
5019                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5020                return;
5021            } else if (app.crashing) {
5022                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5023                return;
5024            }
5025
5026            // In case we come through here for the same app before completing
5027            // this one, mark as anring now so we will bail out.
5028            app.notResponding = true;
5029
5030            // Log the ANR to the event log.
5031            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5032                    app.processName, app.info.flags, annotation);
5033
5034            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5035            firstPids.add(app.pid);
5036
5037            int parentPid = app.pid;
5038            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5039            if (parentPid != app.pid) firstPids.add(parentPid);
5040
5041            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5042
5043            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5044                ProcessRecord r = mLruProcesses.get(i);
5045                if (r != null && r.thread != null) {
5046                    int pid = r.pid;
5047                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5048                        if (r.persistent) {
5049                            firstPids.add(pid);
5050                        } else {
5051                            lastPids.put(pid, Boolean.TRUE);
5052                        }
5053                    }
5054                }
5055            }
5056        }
5057
5058        // Log the ANR to the main log.
5059        StringBuilder info = new StringBuilder();
5060        info.setLength(0);
5061        info.append("ANR in ").append(app.processName);
5062        if (activity != null && activity.shortComponentName != null) {
5063            info.append(" (").append(activity.shortComponentName).append(")");
5064        }
5065        info.append("\n");
5066        info.append("PID: ").append(app.pid).append("\n");
5067        if (annotation != null) {
5068            info.append("Reason: ").append(annotation).append("\n");
5069        }
5070        if (parent != null && parent != activity) {
5071            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5072        }
5073
5074        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5075
5076        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5077                NATIVE_STACKS_OF_INTEREST);
5078
5079        String cpuInfo = null;
5080        if (MONITOR_CPU_USAGE) {
5081            updateCpuStatsNow();
5082            synchronized (mProcessCpuTracker) {
5083                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5084            }
5085            info.append(processCpuTracker.printCurrentLoad());
5086            info.append(cpuInfo);
5087        }
5088
5089        info.append(processCpuTracker.printCurrentState(anrTime));
5090
5091        Slog.e(TAG, info.toString());
5092        if (tracesFile == null) {
5093            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5094            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5095        }
5096
5097        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5098                cpuInfo, tracesFile, null);
5099
5100        if (mController != null) {
5101            try {
5102                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5103                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5104                if (res != 0) {
5105                    if (res < 0 && app.pid != MY_PID) {
5106                        app.kill("anr", true);
5107                    } else {
5108                        synchronized (this) {
5109                            mServices.scheduleServiceTimeoutLocked(app);
5110                        }
5111                    }
5112                    return;
5113                }
5114            } catch (RemoteException e) {
5115                mController = null;
5116                Watchdog.getInstance().setActivityController(null);
5117            }
5118        }
5119
5120        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5121        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5122                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5123
5124        synchronized (this) {
5125            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5126                app.kill("bg anr", true);
5127                return;
5128            }
5129
5130            // Set the app's notResponding state, and look up the errorReportReceiver
5131            makeAppNotRespondingLocked(app,
5132                    activity != null ? activity.shortComponentName : null,
5133                    annotation != null ? "ANR " + annotation : "ANR",
5134                    info.toString());
5135
5136            // Bring up the infamous App Not Responding dialog
5137            Message msg = Message.obtain();
5138            HashMap<String, Object> map = new HashMap<String, Object>();
5139            msg.what = SHOW_NOT_RESPONDING_MSG;
5140            msg.obj = map;
5141            msg.arg1 = aboveSystem ? 1 : 0;
5142            map.put("app", app);
5143            if (activity != null) {
5144                map.put("activity", activity);
5145            }
5146
5147            mHandler.sendMessage(msg);
5148        }
5149    }
5150
5151    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5152        if (!mLaunchWarningShown) {
5153            mLaunchWarningShown = true;
5154            mHandler.post(new Runnable() {
5155                @Override
5156                public void run() {
5157                    synchronized (ActivityManagerService.this) {
5158                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5159                        d.show();
5160                        mHandler.postDelayed(new Runnable() {
5161                            @Override
5162                            public void run() {
5163                                synchronized (ActivityManagerService.this) {
5164                                    d.dismiss();
5165                                    mLaunchWarningShown = false;
5166                                }
5167                            }
5168                        }, 4000);
5169                    }
5170                }
5171            });
5172        }
5173    }
5174
5175    @Override
5176    public boolean clearApplicationUserData(final String packageName,
5177            final IPackageDataObserver observer, int userId) {
5178        enforceNotIsolatedCaller("clearApplicationUserData");
5179        int uid = Binder.getCallingUid();
5180        int pid = Binder.getCallingPid();
5181        userId = handleIncomingUser(pid, uid,
5182                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5183        long callingId = Binder.clearCallingIdentity();
5184        try {
5185            IPackageManager pm = AppGlobals.getPackageManager();
5186            int pkgUid = -1;
5187            synchronized(this) {
5188                try {
5189                    pkgUid = pm.getPackageUid(packageName, userId);
5190                } catch (RemoteException e) {
5191                }
5192                if (pkgUid == -1) {
5193                    Slog.w(TAG, "Invalid packageName: " + packageName);
5194                    if (observer != null) {
5195                        try {
5196                            observer.onRemoveCompleted(packageName, false);
5197                        } catch (RemoteException e) {
5198                            Slog.i(TAG, "Observer no longer exists.");
5199                        }
5200                    }
5201                    return false;
5202                }
5203                if (uid == pkgUid || checkComponentPermission(
5204                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5205                        pid, uid, -1, true)
5206                        == PackageManager.PERMISSION_GRANTED) {
5207                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5208                } else {
5209                    throw new SecurityException("PID " + pid + " does not have permission "
5210                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5211                                    + " of package " + packageName);
5212                }
5213
5214                // Remove all tasks match the cleared application package and user
5215                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5216                    final TaskRecord tr = mRecentTasks.get(i);
5217                    final String taskPackageName =
5218                            tr.getBaseIntent().getComponent().getPackageName();
5219                    if (tr.userId != userId) continue;
5220                    if (!taskPackageName.equals(packageName)) continue;
5221                    removeTaskByIdLocked(tr.taskId, 0);
5222                }
5223            }
5224
5225            try {
5226                // Clear application user data
5227                pm.clearApplicationUserData(packageName, observer, userId);
5228
5229                synchronized(this) {
5230                    // Remove all permissions granted from/to this package
5231                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5232                }
5233
5234                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5235                        Uri.fromParts("package", packageName, null));
5236                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5237                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5238                        null, null, 0, null, null, null, false, false, userId);
5239            } catch (RemoteException e) {
5240            }
5241        } finally {
5242            Binder.restoreCallingIdentity(callingId);
5243        }
5244        return true;
5245    }
5246
5247    @Override
5248    public void killBackgroundProcesses(final String packageName, int userId) {
5249        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5250                != PackageManager.PERMISSION_GRANTED &&
5251                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5252                        != PackageManager.PERMISSION_GRANTED) {
5253            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5254                    + Binder.getCallingPid()
5255                    + ", uid=" + Binder.getCallingUid()
5256                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5257            Slog.w(TAG, msg);
5258            throw new SecurityException(msg);
5259        }
5260
5261        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5262                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5263        long callingId = Binder.clearCallingIdentity();
5264        try {
5265            IPackageManager pm = AppGlobals.getPackageManager();
5266            synchronized(this) {
5267                int appId = -1;
5268                try {
5269                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5270                } catch (RemoteException e) {
5271                }
5272                if (appId == -1) {
5273                    Slog.w(TAG, "Invalid packageName: " + packageName);
5274                    return;
5275                }
5276                killPackageProcessesLocked(packageName, appId, userId,
5277                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5278            }
5279        } finally {
5280            Binder.restoreCallingIdentity(callingId);
5281        }
5282    }
5283
5284    @Override
5285    public void killAllBackgroundProcesses() {
5286        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5287                != PackageManager.PERMISSION_GRANTED) {
5288            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5289                    + Binder.getCallingPid()
5290                    + ", uid=" + Binder.getCallingUid()
5291                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5292            Slog.w(TAG, msg);
5293            throw new SecurityException(msg);
5294        }
5295
5296        long callingId = Binder.clearCallingIdentity();
5297        try {
5298            synchronized(this) {
5299                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5300                final int NP = mProcessNames.getMap().size();
5301                for (int ip=0; ip<NP; ip++) {
5302                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5303                    final int NA = apps.size();
5304                    for (int ia=0; ia<NA; ia++) {
5305                        ProcessRecord app = apps.valueAt(ia);
5306                        if (app.persistent) {
5307                            // we don't kill persistent processes
5308                            continue;
5309                        }
5310                        if (app.removed) {
5311                            procs.add(app);
5312                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5313                            app.removed = true;
5314                            procs.add(app);
5315                        }
5316                    }
5317                }
5318
5319                int N = procs.size();
5320                for (int i=0; i<N; i++) {
5321                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5322                }
5323                mAllowLowerMemLevel = true;
5324                updateOomAdjLocked();
5325                doLowMemReportIfNeededLocked(null);
5326            }
5327        } finally {
5328            Binder.restoreCallingIdentity(callingId);
5329        }
5330    }
5331
5332    @Override
5333    public void forceStopPackage(final String packageName, int userId) {
5334        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5335                != PackageManager.PERMISSION_GRANTED) {
5336            String msg = "Permission Denial: forceStopPackage() from pid="
5337                    + Binder.getCallingPid()
5338                    + ", uid=" + Binder.getCallingUid()
5339                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5340            Slog.w(TAG, msg);
5341            throw new SecurityException(msg);
5342        }
5343        final int callingPid = Binder.getCallingPid();
5344        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5345                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5346        long callingId = Binder.clearCallingIdentity();
5347        try {
5348            IPackageManager pm = AppGlobals.getPackageManager();
5349            synchronized(this) {
5350                int[] users = userId == UserHandle.USER_ALL
5351                        ? getUsersLocked() : new int[] { userId };
5352                for (int user : users) {
5353                    int pkgUid = -1;
5354                    try {
5355                        pkgUid = pm.getPackageUid(packageName, user);
5356                    } catch (RemoteException e) {
5357                    }
5358                    if (pkgUid == -1) {
5359                        Slog.w(TAG, "Invalid packageName: " + packageName);
5360                        continue;
5361                    }
5362                    try {
5363                        pm.setPackageStoppedState(packageName, true, user);
5364                    } catch (RemoteException e) {
5365                    } catch (IllegalArgumentException e) {
5366                        Slog.w(TAG, "Failed trying to unstop package "
5367                                + packageName + ": " + e);
5368                    }
5369                    if (isUserRunningLocked(user, false)) {
5370                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5371                    }
5372                }
5373            }
5374        } finally {
5375            Binder.restoreCallingIdentity(callingId);
5376        }
5377    }
5378
5379    @Override
5380    public void addPackageDependency(String packageName) {
5381        synchronized (this) {
5382            int callingPid = Binder.getCallingPid();
5383            if (callingPid == Process.myPid()) {
5384                //  Yeah, um, no.
5385                Slog.w(TAG, "Can't addPackageDependency on system process");
5386                return;
5387            }
5388            ProcessRecord proc;
5389            synchronized (mPidsSelfLocked) {
5390                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5391            }
5392            if (proc != null) {
5393                if (proc.pkgDeps == null) {
5394                    proc.pkgDeps = new ArraySet<String>(1);
5395                }
5396                proc.pkgDeps.add(packageName);
5397            }
5398        }
5399    }
5400
5401    /*
5402     * The pkg name and app id have to be specified.
5403     */
5404    @Override
5405    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5406        if (pkg == null) {
5407            return;
5408        }
5409        // Make sure the uid is valid.
5410        if (appid < 0) {
5411            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5412            return;
5413        }
5414        int callerUid = Binder.getCallingUid();
5415        // Only the system server can kill an application
5416        if (callerUid == Process.SYSTEM_UID) {
5417            // Post an aysnc message to kill the application
5418            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5419            msg.arg1 = appid;
5420            msg.arg2 = 0;
5421            Bundle bundle = new Bundle();
5422            bundle.putString("pkg", pkg);
5423            bundle.putString("reason", reason);
5424            msg.obj = bundle;
5425            mHandler.sendMessage(msg);
5426        } else {
5427            throw new SecurityException(callerUid + " cannot kill pkg: " +
5428                    pkg);
5429        }
5430    }
5431
5432    @Override
5433    public void closeSystemDialogs(String reason) {
5434        enforceNotIsolatedCaller("closeSystemDialogs");
5435
5436        final int pid = Binder.getCallingPid();
5437        final int uid = Binder.getCallingUid();
5438        final long origId = Binder.clearCallingIdentity();
5439        try {
5440            synchronized (this) {
5441                // Only allow this from foreground processes, so that background
5442                // applications can't abuse it to prevent system UI from being shown.
5443                if (uid >= Process.FIRST_APPLICATION_UID) {
5444                    ProcessRecord proc;
5445                    synchronized (mPidsSelfLocked) {
5446                        proc = mPidsSelfLocked.get(pid);
5447                    }
5448                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5449                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5450                                + " from background process " + proc);
5451                        return;
5452                    }
5453                }
5454                closeSystemDialogsLocked(reason);
5455            }
5456        } finally {
5457            Binder.restoreCallingIdentity(origId);
5458        }
5459    }
5460
5461    void closeSystemDialogsLocked(String reason) {
5462        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5463        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5464                | Intent.FLAG_RECEIVER_FOREGROUND);
5465        if (reason != null) {
5466            intent.putExtra("reason", reason);
5467        }
5468        mWindowManager.closeSystemDialogs(reason);
5469
5470        mStackSupervisor.closeSystemDialogsLocked();
5471
5472        broadcastIntentLocked(null, null, intent, null,
5473                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5474                Process.SYSTEM_UID, UserHandle.USER_ALL);
5475    }
5476
5477    @Override
5478    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5479        enforceNotIsolatedCaller("getProcessMemoryInfo");
5480        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5481        for (int i=pids.length-1; i>=0; i--) {
5482            ProcessRecord proc;
5483            int oomAdj;
5484            synchronized (this) {
5485                synchronized (mPidsSelfLocked) {
5486                    proc = mPidsSelfLocked.get(pids[i]);
5487                    oomAdj = proc != null ? proc.setAdj : 0;
5488                }
5489            }
5490            infos[i] = new Debug.MemoryInfo();
5491            Debug.getMemoryInfo(pids[i], infos[i]);
5492            if (proc != null) {
5493                synchronized (this) {
5494                    if (proc.thread != null && proc.setAdj == oomAdj) {
5495                        // Record this for posterity if the process has been stable.
5496                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5497                                infos[i].getTotalUss(), false, proc.pkgList);
5498                    }
5499                }
5500            }
5501        }
5502        return infos;
5503    }
5504
5505    @Override
5506    public long[] getProcessPss(int[] pids) {
5507        enforceNotIsolatedCaller("getProcessPss");
5508        long[] pss = new long[pids.length];
5509        for (int i=pids.length-1; i>=0; i--) {
5510            ProcessRecord proc;
5511            int oomAdj;
5512            synchronized (this) {
5513                synchronized (mPidsSelfLocked) {
5514                    proc = mPidsSelfLocked.get(pids[i]);
5515                    oomAdj = proc != null ? proc.setAdj : 0;
5516                }
5517            }
5518            long[] tmpUss = new long[1];
5519            pss[i] = Debug.getPss(pids[i], tmpUss);
5520            if (proc != null) {
5521                synchronized (this) {
5522                    if (proc.thread != null && proc.setAdj == oomAdj) {
5523                        // Record this for posterity if the process has been stable.
5524                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5525                    }
5526                }
5527            }
5528        }
5529        return pss;
5530    }
5531
5532    @Override
5533    public void killApplicationProcess(String processName, int uid) {
5534        if (processName == null) {
5535            return;
5536        }
5537
5538        int callerUid = Binder.getCallingUid();
5539        // Only the system server can kill an application
5540        if (callerUid == Process.SYSTEM_UID) {
5541            synchronized (this) {
5542                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5543                if (app != null && app.thread != null) {
5544                    try {
5545                        app.thread.scheduleSuicide();
5546                    } catch (RemoteException e) {
5547                        // If the other end already died, then our work here is done.
5548                    }
5549                } else {
5550                    Slog.w(TAG, "Process/uid not found attempting kill of "
5551                            + processName + " / " + uid);
5552                }
5553            }
5554        } else {
5555            throw new SecurityException(callerUid + " cannot kill app process: " +
5556                    processName);
5557        }
5558    }
5559
5560    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5561        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5562                false, true, false, false, UserHandle.getUserId(uid), reason);
5563        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5564                Uri.fromParts("package", packageName, null));
5565        if (!mProcessesReady) {
5566            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5567                    | Intent.FLAG_RECEIVER_FOREGROUND);
5568        }
5569        intent.putExtra(Intent.EXTRA_UID, uid);
5570        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5571        broadcastIntentLocked(null, null, intent,
5572                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5573                false, false,
5574                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5575    }
5576
5577    private void forceStopUserLocked(int userId, String reason) {
5578        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5579        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5580        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5581                | Intent.FLAG_RECEIVER_FOREGROUND);
5582        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5583        broadcastIntentLocked(null, null, intent,
5584                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5585                false, false,
5586                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5587    }
5588
5589    private final boolean killPackageProcessesLocked(String packageName, int appId,
5590            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5591            boolean doit, boolean evenPersistent, String reason) {
5592        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5593
5594        // Remove all processes this package may have touched: all with the
5595        // same UID (except for the system or root user), and all whose name
5596        // matches the package name.
5597        final int NP = mProcessNames.getMap().size();
5598        for (int ip=0; ip<NP; ip++) {
5599            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5600            final int NA = apps.size();
5601            for (int ia=0; ia<NA; ia++) {
5602                ProcessRecord app = apps.valueAt(ia);
5603                if (app.persistent && !evenPersistent) {
5604                    // we don't kill persistent processes
5605                    continue;
5606                }
5607                if (app.removed) {
5608                    if (doit) {
5609                        procs.add(app);
5610                    }
5611                    continue;
5612                }
5613
5614                // Skip process if it doesn't meet our oom adj requirement.
5615                if (app.setAdj < minOomAdj) {
5616                    continue;
5617                }
5618
5619                // If no package is specified, we call all processes under the
5620                // give user id.
5621                if (packageName == null) {
5622                    if (app.userId != userId) {
5623                        continue;
5624                    }
5625                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5626                        continue;
5627                    }
5628                // Package has been specified, we want to hit all processes
5629                // that match it.  We need to qualify this by the processes
5630                // that are running under the specified app and user ID.
5631                } else {
5632                    final boolean isDep = app.pkgDeps != null
5633                            && app.pkgDeps.contains(packageName);
5634                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5635                        continue;
5636                    }
5637                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5638                        continue;
5639                    }
5640                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5641                        continue;
5642                    }
5643                }
5644
5645                // Process has passed all conditions, kill it!
5646                if (!doit) {
5647                    return true;
5648                }
5649                app.removed = true;
5650                procs.add(app);
5651            }
5652        }
5653
5654        int N = procs.size();
5655        for (int i=0; i<N; i++) {
5656            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5657        }
5658        updateOomAdjLocked();
5659        return N > 0;
5660    }
5661
5662    private final boolean forceStopPackageLocked(String name, int appId,
5663            boolean callerWillRestart, boolean purgeCache, boolean doit,
5664            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5665        int i;
5666        int N;
5667
5668        if (userId == UserHandle.USER_ALL && name == null) {
5669            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5670        }
5671
5672        if (appId < 0 && name != null) {
5673            try {
5674                appId = UserHandle.getAppId(
5675                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5676            } catch (RemoteException e) {
5677            }
5678        }
5679
5680        if (doit) {
5681            if (name != null) {
5682                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5683                        + " user=" + userId + ": " + reason);
5684            } else {
5685                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5686            }
5687
5688            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5689            for (int ip=pmap.size()-1; ip>=0; ip--) {
5690                SparseArray<Long> ba = pmap.valueAt(ip);
5691                for (i=ba.size()-1; i>=0; i--) {
5692                    boolean remove = false;
5693                    final int entUid = ba.keyAt(i);
5694                    if (name != null) {
5695                        if (userId == UserHandle.USER_ALL) {
5696                            if (UserHandle.getAppId(entUid) == appId) {
5697                                remove = true;
5698                            }
5699                        } else {
5700                            if (entUid == UserHandle.getUid(userId, appId)) {
5701                                remove = true;
5702                            }
5703                        }
5704                    } else if (UserHandle.getUserId(entUid) == userId) {
5705                        remove = true;
5706                    }
5707                    if (remove) {
5708                        ba.removeAt(i);
5709                    }
5710                }
5711                if (ba.size() == 0) {
5712                    pmap.removeAt(ip);
5713                }
5714            }
5715        }
5716
5717        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5718                -100, callerWillRestart, true, doit, evenPersistent,
5719                name == null ? ("stop user " + userId) : ("stop " + name));
5720
5721        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5722            if (!doit) {
5723                return true;
5724            }
5725            didSomething = true;
5726        }
5727
5728        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5729            if (!doit) {
5730                return true;
5731            }
5732            didSomething = true;
5733        }
5734
5735        if (name == null) {
5736            // Remove all sticky broadcasts from this user.
5737            mStickyBroadcasts.remove(userId);
5738        }
5739
5740        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5741        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5742                userId, providers)) {
5743            if (!doit) {
5744                return true;
5745            }
5746            didSomething = true;
5747        }
5748        N = providers.size();
5749        for (i=0; i<N; i++) {
5750            removeDyingProviderLocked(null, providers.get(i), true);
5751        }
5752
5753        // Remove transient permissions granted from/to this package/user
5754        removeUriPermissionsForPackageLocked(name, userId, false);
5755
5756        if (name == null || uninstalling) {
5757            // Remove pending intents.  For now we only do this when force
5758            // stopping users, because we have some problems when doing this
5759            // for packages -- app widgets are not currently cleaned up for
5760            // such packages, so they can be left with bad pending intents.
5761            if (mIntentSenderRecords.size() > 0) {
5762                Iterator<WeakReference<PendingIntentRecord>> it
5763                        = mIntentSenderRecords.values().iterator();
5764                while (it.hasNext()) {
5765                    WeakReference<PendingIntentRecord> wpir = it.next();
5766                    if (wpir == null) {
5767                        it.remove();
5768                        continue;
5769                    }
5770                    PendingIntentRecord pir = wpir.get();
5771                    if (pir == null) {
5772                        it.remove();
5773                        continue;
5774                    }
5775                    if (name == null) {
5776                        // Stopping user, remove all objects for the user.
5777                        if (pir.key.userId != userId) {
5778                            // Not the same user, skip it.
5779                            continue;
5780                        }
5781                    } else {
5782                        if (UserHandle.getAppId(pir.uid) != appId) {
5783                            // Different app id, skip it.
5784                            continue;
5785                        }
5786                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5787                            // Different user, skip it.
5788                            continue;
5789                        }
5790                        if (!pir.key.packageName.equals(name)) {
5791                            // Different package, skip it.
5792                            continue;
5793                        }
5794                    }
5795                    if (!doit) {
5796                        return true;
5797                    }
5798                    didSomething = true;
5799                    it.remove();
5800                    pir.canceled = true;
5801                    if (pir.key.activity != null) {
5802                        pir.key.activity.pendingResults.remove(pir.ref);
5803                    }
5804                }
5805            }
5806        }
5807
5808        if (doit) {
5809            if (purgeCache && name != null) {
5810                AttributeCache ac = AttributeCache.instance();
5811                if (ac != null) {
5812                    ac.removePackage(name);
5813                }
5814            }
5815            if (mBooted) {
5816                mStackSupervisor.resumeTopActivitiesLocked();
5817                mStackSupervisor.scheduleIdleLocked();
5818            }
5819        }
5820
5821        return didSomething;
5822    }
5823
5824    private final boolean removeProcessLocked(ProcessRecord app,
5825            boolean callerWillRestart, boolean allowRestart, String reason) {
5826        final String name = app.processName;
5827        final int uid = app.uid;
5828        if (DEBUG_PROCESSES) Slog.d(
5829            TAG, "Force removing proc " + app.toShortString() + " (" + name
5830            + "/" + uid + ")");
5831
5832        mProcessNames.remove(name, uid);
5833        mIsolatedProcesses.remove(app.uid);
5834        if (mHeavyWeightProcess == app) {
5835            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5836                    mHeavyWeightProcess.userId, 0));
5837            mHeavyWeightProcess = null;
5838        }
5839        boolean needRestart = false;
5840        if (app.pid > 0 && app.pid != MY_PID) {
5841            int pid = app.pid;
5842            synchronized (mPidsSelfLocked) {
5843                mPidsSelfLocked.remove(pid);
5844                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5845            }
5846            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5847            if (app.isolated) {
5848                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5849            }
5850            app.kill(reason, true);
5851            handleAppDiedLocked(app, true, allowRestart);
5852            removeLruProcessLocked(app);
5853
5854            if (app.persistent && !app.isolated) {
5855                if (!callerWillRestart) {
5856                    addAppLocked(app.info, false, null /* ABI override */);
5857                } else {
5858                    needRestart = true;
5859                }
5860            }
5861        } else {
5862            mRemovedProcesses.add(app);
5863        }
5864
5865        return needRestart;
5866    }
5867
5868    private final void processStartTimedOutLocked(ProcessRecord app) {
5869        final int pid = app.pid;
5870        boolean gone = false;
5871        synchronized (mPidsSelfLocked) {
5872            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5873            if (knownApp != null && knownApp.thread == null) {
5874                mPidsSelfLocked.remove(pid);
5875                gone = true;
5876            }
5877        }
5878
5879        if (gone) {
5880            Slog.w(TAG, "Process " + app + " failed to attach");
5881            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5882                    pid, app.uid, app.processName);
5883            mProcessNames.remove(app.processName, app.uid);
5884            mIsolatedProcesses.remove(app.uid);
5885            if (mHeavyWeightProcess == app) {
5886                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5887                        mHeavyWeightProcess.userId, 0));
5888                mHeavyWeightProcess = null;
5889            }
5890            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5891            if (app.isolated) {
5892                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5893            }
5894            // Take care of any launching providers waiting for this process.
5895            checkAppInLaunchingProvidersLocked(app, true);
5896            // Take care of any services that are waiting for the process.
5897            mServices.processStartTimedOutLocked(app);
5898            app.kill("start timeout", true);
5899            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5900                Slog.w(TAG, "Unattached app died before backup, skipping");
5901                try {
5902                    IBackupManager bm = IBackupManager.Stub.asInterface(
5903                            ServiceManager.getService(Context.BACKUP_SERVICE));
5904                    bm.agentDisconnected(app.info.packageName);
5905                } catch (RemoteException e) {
5906                    // Can't happen; the backup manager is local
5907                }
5908            }
5909            if (isPendingBroadcastProcessLocked(pid)) {
5910                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5911                skipPendingBroadcastLocked(pid);
5912            }
5913        } else {
5914            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5915        }
5916    }
5917
5918    private final boolean attachApplicationLocked(IApplicationThread thread,
5919            int pid) {
5920
5921        // Find the application record that is being attached...  either via
5922        // the pid if we are running in multiple processes, or just pull the
5923        // next app record if we are emulating process with anonymous threads.
5924        ProcessRecord app;
5925        if (pid != MY_PID && pid >= 0) {
5926            synchronized (mPidsSelfLocked) {
5927                app = mPidsSelfLocked.get(pid);
5928            }
5929        } else {
5930            app = null;
5931        }
5932
5933        if (app == null) {
5934            Slog.w(TAG, "No pending application record for pid " + pid
5935                    + " (IApplicationThread " + thread + "); dropping process");
5936            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5937            if (pid > 0 && pid != MY_PID) {
5938                Process.killProcessQuiet(pid);
5939                //TODO: Process.killProcessGroup(app.info.uid, pid);
5940            } else {
5941                try {
5942                    thread.scheduleExit();
5943                } catch (Exception e) {
5944                    // Ignore exceptions.
5945                }
5946            }
5947            return false;
5948        }
5949
5950        // If this application record is still attached to a previous
5951        // process, clean it up now.
5952        if (app.thread != null) {
5953            handleAppDiedLocked(app, true, true);
5954        }
5955
5956        // Tell the process all about itself.
5957
5958        if (localLOGV) Slog.v(
5959                TAG, "Binding process pid " + pid + " to record " + app);
5960
5961        final String processName = app.processName;
5962        try {
5963            AppDeathRecipient adr = new AppDeathRecipient(
5964                    app, pid, thread);
5965            thread.asBinder().linkToDeath(adr, 0);
5966            app.deathRecipient = adr;
5967        } catch (RemoteException e) {
5968            app.resetPackageList(mProcessStats);
5969            startProcessLocked(app, "link fail", processName);
5970            return false;
5971        }
5972
5973        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5974
5975        app.makeActive(thread, mProcessStats);
5976        app.curAdj = app.setAdj = -100;
5977        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5978        app.forcingToForeground = null;
5979        updateProcessForegroundLocked(app, false, false);
5980        app.hasShownUi = false;
5981        app.debugging = false;
5982        app.cached = false;
5983
5984        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5985
5986        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5987        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5988
5989        if (!normalMode) {
5990            Slog.i(TAG, "Launching preboot mode app: " + app);
5991        }
5992
5993        if (localLOGV) Slog.v(
5994            TAG, "New app record " + app
5995            + " thread=" + thread.asBinder() + " pid=" + pid);
5996        try {
5997            int testMode = IApplicationThread.DEBUG_OFF;
5998            if (mDebugApp != null && mDebugApp.equals(processName)) {
5999                testMode = mWaitForDebugger
6000                    ? IApplicationThread.DEBUG_WAIT
6001                    : IApplicationThread.DEBUG_ON;
6002                app.debugging = true;
6003                if (mDebugTransient) {
6004                    mDebugApp = mOrigDebugApp;
6005                    mWaitForDebugger = mOrigWaitForDebugger;
6006                }
6007            }
6008            String profileFile = app.instrumentationProfileFile;
6009            ParcelFileDescriptor profileFd = null;
6010            int samplingInterval = 0;
6011            boolean profileAutoStop = false;
6012            if (mProfileApp != null && mProfileApp.equals(processName)) {
6013                mProfileProc = app;
6014                profileFile = mProfileFile;
6015                profileFd = mProfileFd;
6016                samplingInterval = mSamplingInterval;
6017                profileAutoStop = mAutoStopProfiler;
6018            }
6019            boolean enableOpenGlTrace = false;
6020            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6021                enableOpenGlTrace = true;
6022                mOpenGlTraceApp = null;
6023            }
6024
6025            // If the app is being launched for restore or full backup, set it up specially
6026            boolean isRestrictedBackupMode = false;
6027            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6028                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6029                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6030                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6031            }
6032
6033            ensurePackageDexOpt(app.instrumentationInfo != null
6034                    ? app.instrumentationInfo.packageName
6035                    : app.info.packageName);
6036            if (app.instrumentationClass != null) {
6037                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6038            }
6039            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6040                    + processName + " with config " + mConfiguration);
6041            ApplicationInfo appInfo = app.instrumentationInfo != null
6042                    ? app.instrumentationInfo : app.info;
6043            app.compat = compatibilityInfoForPackageLocked(appInfo);
6044            if (profileFd != null) {
6045                profileFd = profileFd.dup();
6046            }
6047            ProfilerInfo profilerInfo = profileFile == null ? null
6048                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6049            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6050                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6051                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6052                    isRestrictedBackupMode || !normalMode, app.persistent,
6053                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6054                    mCoreSettingsObserver.getCoreSettingsLocked());
6055            updateLruProcessLocked(app, false, null);
6056            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6057        } catch (Exception e) {
6058            // todo: Yikes!  What should we do?  For now we will try to
6059            // start another process, but that could easily get us in
6060            // an infinite loop of restarting processes...
6061            Slog.w(TAG, "Exception thrown during bind!", e);
6062
6063            app.resetPackageList(mProcessStats);
6064            app.unlinkDeathRecipient();
6065            startProcessLocked(app, "bind fail", processName);
6066            return false;
6067        }
6068
6069        // Remove this record from the list of starting applications.
6070        mPersistentStartingProcesses.remove(app);
6071        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6072                "Attach application locked removing on hold: " + app);
6073        mProcessesOnHold.remove(app);
6074
6075        boolean badApp = false;
6076        boolean didSomething = false;
6077
6078        // See if the top visible activity is waiting to run in this process...
6079        if (normalMode) {
6080            try {
6081                if (mStackSupervisor.attachApplicationLocked(app)) {
6082                    didSomething = true;
6083                }
6084            } catch (Exception e) {
6085                badApp = true;
6086            }
6087        }
6088
6089        // Find any services that should be running in this process...
6090        if (!badApp) {
6091            try {
6092                didSomething |= mServices.attachApplicationLocked(app, processName);
6093            } catch (Exception e) {
6094                badApp = true;
6095            }
6096        }
6097
6098        // Check if a next-broadcast receiver is in this process...
6099        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6100            try {
6101                didSomething |= sendPendingBroadcastsLocked(app);
6102            } catch (Exception e) {
6103                // If the app died trying to launch the receiver we declare it 'bad'
6104                badApp = true;
6105            }
6106        }
6107
6108        // Check whether the next backup agent is in this process...
6109        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6110            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6111            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6112            try {
6113                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6114                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6115                        mBackupTarget.backupMode);
6116            } catch (Exception e) {
6117                Slog.w(TAG, "Exception scheduling backup agent creation: ");
6118                e.printStackTrace();
6119            }
6120        }
6121
6122        if (badApp) {
6123            // todo: Also need to kill application to deal with all
6124            // kinds of exceptions.
6125            handleAppDiedLocked(app, false, true);
6126            return false;
6127        }
6128
6129        if (!didSomething) {
6130            updateOomAdjLocked();
6131        }
6132
6133        return true;
6134    }
6135
6136    @Override
6137    public final void attachApplication(IApplicationThread thread) {
6138        synchronized (this) {
6139            int callingPid = Binder.getCallingPid();
6140            final long origId = Binder.clearCallingIdentity();
6141            attachApplicationLocked(thread, callingPid);
6142            Binder.restoreCallingIdentity(origId);
6143        }
6144    }
6145
6146    @Override
6147    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6148        final long origId = Binder.clearCallingIdentity();
6149        synchronized (this) {
6150            ActivityStack stack = ActivityRecord.getStackLocked(token);
6151            if (stack != null) {
6152                ActivityRecord r =
6153                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6154                if (stopProfiling) {
6155                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6156                        try {
6157                            mProfileFd.close();
6158                        } catch (IOException e) {
6159                        }
6160                        clearProfilerLocked();
6161                    }
6162                }
6163            }
6164        }
6165        Binder.restoreCallingIdentity(origId);
6166    }
6167
6168    void postEnableScreenAfterBootLocked() {
6169        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
6170    }
6171
6172    void enableScreenAfterBoot() {
6173        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6174                SystemClock.uptimeMillis());
6175        mWindowManager.enableScreenAfterBoot();
6176
6177        synchronized (this) {
6178            updateEventDispatchingLocked();
6179        }
6180    }
6181
6182    @Override
6183    public void showBootMessage(final CharSequence msg, final boolean always) {
6184        enforceNotIsolatedCaller("showBootMessage");
6185        mWindowManager.showBootMessage(msg, always);
6186    }
6187
6188    @Override
6189    public void keyguardWaitingForActivityDrawn() {
6190        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6191        final long token = Binder.clearCallingIdentity();
6192        try {
6193            synchronized (this) {
6194                if (DEBUG_LOCKSCREEN) logLockScreen("");
6195                mWindowManager.keyguardWaitingForActivityDrawn();
6196            }
6197        } finally {
6198            Binder.restoreCallingIdentity(token);
6199        }
6200    }
6201
6202    final void finishBooting() {
6203        synchronized (this) {
6204            if (!mBootAnimationComplete) {
6205                mCallFinishBooting = true;
6206                return;
6207            }
6208            mCallFinishBooting = false;
6209        }
6210
6211        // Register receivers to handle package update events
6212        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
6213
6214        // Let system services know.
6215        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6216
6217        synchronized (this) {
6218            // Ensure that any processes we had put on hold are now started
6219            // up.
6220            final int NP = mProcessesOnHold.size();
6221            if (NP > 0) {
6222                ArrayList<ProcessRecord> procs =
6223                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6224                for (int ip=0; ip<NP; ip++) {
6225                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6226                            + procs.get(ip));
6227                    startProcessLocked(procs.get(ip), "on-hold", null);
6228                }
6229            }
6230
6231            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6232                // Start looking for apps that are abusing wake locks.
6233                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6234                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6235                // Tell anyone interested that we are done booting!
6236                SystemProperties.set("sys.boot_completed", "1");
6237                SystemProperties.set("dev.bootcomplete", "1");
6238                for (int i=0; i<mStartedUsers.size(); i++) {
6239                    UserStartedState uss = mStartedUsers.valueAt(i);
6240                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6241                        uss.mState = UserStartedState.STATE_RUNNING;
6242                        final int userId = mStartedUsers.keyAt(i);
6243                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6244                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6245                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6246                        broadcastIntentLocked(null, null, intent, null,
6247                                new IIntentReceiver.Stub() {
6248                                    @Override
6249                                    public void performReceive(Intent intent, int resultCode,
6250                                            String data, Bundle extras, boolean ordered,
6251                                            boolean sticky, int sendingUser) {
6252                                        synchronized (ActivityManagerService.this) {
6253                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6254                                                    true, false);
6255                                        }
6256                                    }
6257                                },
6258                                0, null, null,
6259                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6260                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6261                                userId);
6262                    }
6263                }
6264                scheduleStartProfilesLocked();
6265            }
6266        }
6267    }
6268
6269    @Override
6270    public void bootAnimationComplete() {
6271        final boolean callFinishBooting;
6272        synchronized (this) {
6273            callFinishBooting = mCallFinishBooting;
6274            mBootAnimationComplete = true;
6275        }
6276        if (callFinishBooting) {
6277            finishBooting();
6278        }
6279    }
6280
6281    final void ensureBootCompleted() {
6282        boolean booting;
6283        boolean enableScreen;
6284        synchronized (this) {
6285            booting = mBooting;
6286            mBooting = false;
6287            enableScreen = !mBooted;
6288            mBooted = true;
6289        }
6290
6291        if (booting) {
6292            finishBooting();
6293        }
6294
6295        if (enableScreen) {
6296            enableScreenAfterBoot();
6297        }
6298    }
6299
6300    @Override
6301    public final void activityResumed(IBinder token) {
6302        final long origId = Binder.clearCallingIdentity();
6303        synchronized(this) {
6304            ActivityStack stack = ActivityRecord.getStackLocked(token);
6305            if (stack != null) {
6306                ActivityRecord.activityResumedLocked(token);
6307            }
6308        }
6309        Binder.restoreCallingIdentity(origId);
6310    }
6311
6312    @Override
6313    public final void activityPaused(IBinder token) {
6314        final long origId = Binder.clearCallingIdentity();
6315        synchronized(this) {
6316            ActivityStack stack = ActivityRecord.getStackLocked(token);
6317            if (stack != null) {
6318                stack.activityPausedLocked(token, false);
6319            }
6320        }
6321        Binder.restoreCallingIdentity(origId);
6322    }
6323
6324    @Override
6325    public final void activityStopped(IBinder token, Bundle icicle,
6326            PersistableBundle persistentState, CharSequence description) {
6327        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6328
6329        // Refuse possible leaked file descriptors
6330        if (icicle != null && icicle.hasFileDescriptors()) {
6331            throw new IllegalArgumentException("File descriptors passed in Bundle");
6332        }
6333
6334        final long origId = Binder.clearCallingIdentity();
6335
6336        synchronized (this) {
6337            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6338            if (r != null) {
6339                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6340            }
6341        }
6342
6343        trimApplications();
6344
6345        Binder.restoreCallingIdentity(origId);
6346    }
6347
6348    @Override
6349    public final void activityDestroyed(IBinder token) {
6350        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6351        synchronized (this) {
6352            ActivityStack stack = ActivityRecord.getStackLocked(token);
6353            if (stack != null) {
6354                stack.activityDestroyedLocked(token);
6355            }
6356        }
6357    }
6358
6359    @Override
6360    public final void backgroundResourcesReleased(IBinder token) {
6361        final long origId = Binder.clearCallingIdentity();
6362        try {
6363            synchronized (this) {
6364                ActivityStack stack = ActivityRecord.getStackLocked(token);
6365                if (stack != null) {
6366                    stack.backgroundResourcesReleased(token);
6367                }
6368            }
6369        } finally {
6370            Binder.restoreCallingIdentity(origId);
6371        }
6372    }
6373
6374    @Override
6375    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6376        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6377    }
6378
6379    @Override
6380    public final void notifyEnterAnimationComplete(IBinder token) {
6381        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6382    }
6383
6384    @Override
6385    public String getCallingPackage(IBinder token) {
6386        synchronized (this) {
6387            ActivityRecord r = getCallingRecordLocked(token);
6388            return r != null ? r.info.packageName : null;
6389        }
6390    }
6391
6392    @Override
6393    public ComponentName getCallingActivity(IBinder token) {
6394        synchronized (this) {
6395            ActivityRecord r = getCallingRecordLocked(token);
6396            return r != null ? r.intent.getComponent() : null;
6397        }
6398    }
6399
6400    private ActivityRecord getCallingRecordLocked(IBinder token) {
6401        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6402        if (r == null) {
6403            return null;
6404        }
6405        return r.resultTo;
6406    }
6407
6408    @Override
6409    public ComponentName getActivityClassForToken(IBinder token) {
6410        synchronized(this) {
6411            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6412            if (r == null) {
6413                return null;
6414            }
6415            return r.intent.getComponent();
6416        }
6417    }
6418
6419    @Override
6420    public String getPackageForToken(IBinder token) {
6421        synchronized(this) {
6422            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6423            if (r == null) {
6424                return null;
6425            }
6426            return r.packageName;
6427        }
6428    }
6429
6430    @Override
6431    public IIntentSender getIntentSender(int type,
6432            String packageName, IBinder token, String resultWho,
6433            int requestCode, Intent[] intents, String[] resolvedTypes,
6434            int flags, Bundle options, int userId) {
6435        enforceNotIsolatedCaller("getIntentSender");
6436        // Refuse possible leaked file descriptors
6437        if (intents != null) {
6438            if (intents.length < 1) {
6439                throw new IllegalArgumentException("Intents array length must be >= 1");
6440            }
6441            for (int i=0; i<intents.length; i++) {
6442                Intent intent = intents[i];
6443                if (intent != null) {
6444                    if (intent.hasFileDescriptors()) {
6445                        throw new IllegalArgumentException("File descriptors passed in Intent");
6446                    }
6447                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6448                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6449                        throw new IllegalArgumentException(
6450                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6451                    }
6452                    intents[i] = new Intent(intent);
6453                }
6454            }
6455            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6456                throw new IllegalArgumentException(
6457                        "Intent array length does not match resolvedTypes length");
6458            }
6459        }
6460        if (options != null) {
6461            if (options.hasFileDescriptors()) {
6462                throw new IllegalArgumentException("File descriptors passed in options");
6463            }
6464        }
6465
6466        synchronized(this) {
6467            int callingUid = Binder.getCallingUid();
6468            int origUserId = userId;
6469            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6470                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6471                    ALLOW_NON_FULL, "getIntentSender", null);
6472            if (origUserId == UserHandle.USER_CURRENT) {
6473                // We don't want to evaluate this until the pending intent is
6474                // actually executed.  However, we do want to always do the
6475                // security checking for it above.
6476                userId = UserHandle.USER_CURRENT;
6477            }
6478            try {
6479                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6480                    int uid = AppGlobals.getPackageManager()
6481                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6482                    if (!UserHandle.isSameApp(callingUid, uid)) {
6483                        String msg = "Permission Denial: getIntentSender() from pid="
6484                            + Binder.getCallingPid()
6485                            + ", uid=" + Binder.getCallingUid()
6486                            + ", (need uid=" + uid + ")"
6487                            + " is not allowed to send as package " + packageName;
6488                        Slog.w(TAG, msg);
6489                        throw new SecurityException(msg);
6490                    }
6491                }
6492
6493                return getIntentSenderLocked(type, packageName, callingUid, userId,
6494                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6495
6496            } catch (RemoteException e) {
6497                throw new SecurityException(e);
6498            }
6499        }
6500    }
6501
6502    IIntentSender getIntentSenderLocked(int type, String packageName,
6503            int callingUid, int userId, IBinder token, String resultWho,
6504            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6505            Bundle options) {
6506        if (DEBUG_MU)
6507            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6508        ActivityRecord activity = null;
6509        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6510            activity = ActivityRecord.isInStackLocked(token);
6511            if (activity == null) {
6512                return null;
6513            }
6514            if (activity.finishing) {
6515                return null;
6516            }
6517        }
6518
6519        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6520        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6521        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6522        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6523                |PendingIntent.FLAG_UPDATE_CURRENT);
6524
6525        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6526                type, packageName, activity, resultWho,
6527                requestCode, intents, resolvedTypes, flags, options, userId);
6528        WeakReference<PendingIntentRecord> ref;
6529        ref = mIntentSenderRecords.get(key);
6530        PendingIntentRecord rec = ref != null ? ref.get() : null;
6531        if (rec != null) {
6532            if (!cancelCurrent) {
6533                if (updateCurrent) {
6534                    if (rec.key.requestIntent != null) {
6535                        rec.key.requestIntent.replaceExtras(intents != null ?
6536                                intents[intents.length - 1] : null);
6537                    }
6538                    if (intents != null) {
6539                        intents[intents.length-1] = rec.key.requestIntent;
6540                        rec.key.allIntents = intents;
6541                        rec.key.allResolvedTypes = resolvedTypes;
6542                    } else {
6543                        rec.key.allIntents = null;
6544                        rec.key.allResolvedTypes = null;
6545                    }
6546                }
6547                return rec;
6548            }
6549            rec.canceled = true;
6550            mIntentSenderRecords.remove(key);
6551        }
6552        if (noCreate) {
6553            return rec;
6554        }
6555        rec = new PendingIntentRecord(this, key, callingUid);
6556        mIntentSenderRecords.put(key, rec.ref);
6557        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6558            if (activity.pendingResults == null) {
6559                activity.pendingResults
6560                        = new HashSet<WeakReference<PendingIntentRecord>>();
6561            }
6562            activity.pendingResults.add(rec.ref);
6563        }
6564        return rec;
6565    }
6566
6567    @Override
6568    public void cancelIntentSender(IIntentSender sender) {
6569        if (!(sender instanceof PendingIntentRecord)) {
6570            return;
6571        }
6572        synchronized(this) {
6573            PendingIntentRecord rec = (PendingIntentRecord)sender;
6574            try {
6575                int uid = AppGlobals.getPackageManager()
6576                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6577                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6578                    String msg = "Permission Denial: cancelIntentSender() from pid="
6579                        + Binder.getCallingPid()
6580                        + ", uid=" + Binder.getCallingUid()
6581                        + " is not allowed to cancel packges "
6582                        + rec.key.packageName;
6583                    Slog.w(TAG, msg);
6584                    throw new SecurityException(msg);
6585                }
6586            } catch (RemoteException e) {
6587                throw new SecurityException(e);
6588            }
6589            cancelIntentSenderLocked(rec, true);
6590        }
6591    }
6592
6593    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6594        rec.canceled = true;
6595        mIntentSenderRecords.remove(rec.key);
6596        if (cleanActivity && rec.key.activity != null) {
6597            rec.key.activity.pendingResults.remove(rec.ref);
6598        }
6599    }
6600
6601    @Override
6602    public String getPackageForIntentSender(IIntentSender pendingResult) {
6603        if (!(pendingResult instanceof PendingIntentRecord)) {
6604            return null;
6605        }
6606        try {
6607            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6608            return res.key.packageName;
6609        } catch (ClassCastException e) {
6610        }
6611        return null;
6612    }
6613
6614    @Override
6615    public int getUidForIntentSender(IIntentSender sender) {
6616        if (sender instanceof PendingIntentRecord) {
6617            try {
6618                PendingIntentRecord res = (PendingIntentRecord)sender;
6619                return res.uid;
6620            } catch (ClassCastException e) {
6621            }
6622        }
6623        return -1;
6624    }
6625
6626    @Override
6627    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6628        if (!(pendingResult instanceof PendingIntentRecord)) {
6629            return false;
6630        }
6631        try {
6632            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6633            if (res.key.allIntents == null) {
6634                return false;
6635            }
6636            for (int i=0; i<res.key.allIntents.length; i++) {
6637                Intent intent = res.key.allIntents[i];
6638                if (intent.getPackage() != null && intent.getComponent() != null) {
6639                    return false;
6640                }
6641            }
6642            return true;
6643        } catch (ClassCastException e) {
6644        }
6645        return false;
6646    }
6647
6648    @Override
6649    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6650        if (!(pendingResult instanceof PendingIntentRecord)) {
6651            return false;
6652        }
6653        try {
6654            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6655            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6656                return true;
6657            }
6658            return false;
6659        } catch (ClassCastException e) {
6660        }
6661        return false;
6662    }
6663
6664    @Override
6665    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6666        if (!(pendingResult instanceof PendingIntentRecord)) {
6667            return null;
6668        }
6669        try {
6670            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6671            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6672        } catch (ClassCastException e) {
6673        }
6674        return null;
6675    }
6676
6677    @Override
6678    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6679        if (!(pendingResult instanceof PendingIntentRecord)) {
6680            return null;
6681        }
6682        try {
6683            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6684            Intent intent = res.key.requestIntent;
6685            if (intent != null) {
6686                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6687                        || res.lastTagPrefix.equals(prefix))) {
6688                    return res.lastTag;
6689                }
6690                res.lastTagPrefix = prefix;
6691                StringBuilder sb = new StringBuilder(128);
6692                if (prefix != null) {
6693                    sb.append(prefix);
6694                }
6695                if (intent.getAction() != null) {
6696                    sb.append(intent.getAction());
6697                } else if (intent.getComponent() != null) {
6698                    intent.getComponent().appendShortString(sb);
6699                } else {
6700                    sb.append("?");
6701                }
6702                return res.lastTag = sb.toString();
6703            }
6704        } catch (ClassCastException e) {
6705        }
6706        return null;
6707    }
6708
6709    @Override
6710    public void setProcessLimit(int max) {
6711        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6712                "setProcessLimit()");
6713        synchronized (this) {
6714            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6715            mProcessLimitOverride = max;
6716        }
6717        trimApplications();
6718    }
6719
6720    @Override
6721    public int getProcessLimit() {
6722        synchronized (this) {
6723            return mProcessLimitOverride;
6724        }
6725    }
6726
6727    void foregroundTokenDied(ForegroundToken token) {
6728        synchronized (ActivityManagerService.this) {
6729            synchronized (mPidsSelfLocked) {
6730                ForegroundToken cur
6731                    = mForegroundProcesses.get(token.pid);
6732                if (cur != token) {
6733                    return;
6734                }
6735                mForegroundProcesses.remove(token.pid);
6736                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6737                if (pr == null) {
6738                    return;
6739                }
6740                pr.forcingToForeground = null;
6741                updateProcessForegroundLocked(pr, false, false);
6742            }
6743            updateOomAdjLocked();
6744        }
6745    }
6746
6747    @Override
6748    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6749        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6750                "setProcessForeground()");
6751        synchronized(this) {
6752            boolean changed = false;
6753
6754            synchronized (mPidsSelfLocked) {
6755                ProcessRecord pr = mPidsSelfLocked.get(pid);
6756                if (pr == null && isForeground) {
6757                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6758                    return;
6759                }
6760                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6761                if (oldToken != null) {
6762                    oldToken.token.unlinkToDeath(oldToken, 0);
6763                    mForegroundProcesses.remove(pid);
6764                    if (pr != null) {
6765                        pr.forcingToForeground = null;
6766                    }
6767                    changed = true;
6768                }
6769                if (isForeground && token != null) {
6770                    ForegroundToken newToken = new ForegroundToken() {
6771                        @Override
6772                        public void binderDied() {
6773                            foregroundTokenDied(this);
6774                        }
6775                    };
6776                    newToken.pid = pid;
6777                    newToken.token = token;
6778                    try {
6779                        token.linkToDeath(newToken, 0);
6780                        mForegroundProcesses.put(pid, newToken);
6781                        pr.forcingToForeground = token;
6782                        changed = true;
6783                    } catch (RemoteException e) {
6784                        // If the process died while doing this, we will later
6785                        // do the cleanup with the process death link.
6786                    }
6787                }
6788            }
6789
6790            if (changed) {
6791                updateOomAdjLocked();
6792            }
6793        }
6794    }
6795
6796    // =========================================================
6797    // PERMISSIONS
6798    // =========================================================
6799
6800    static class PermissionController extends IPermissionController.Stub {
6801        ActivityManagerService mActivityManagerService;
6802        PermissionController(ActivityManagerService activityManagerService) {
6803            mActivityManagerService = activityManagerService;
6804        }
6805
6806        @Override
6807        public boolean checkPermission(String permission, int pid, int uid) {
6808            return mActivityManagerService.checkPermission(permission, pid,
6809                    uid) == PackageManager.PERMISSION_GRANTED;
6810        }
6811    }
6812
6813    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6814        @Override
6815        public int checkComponentPermission(String permission, int pid, int uid,
6816                int owningUid, boolean exported) {
6817            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6818                    owningUid, exported);
6819        }
6820
6821        @Override
6822        public Object getAMSLock() {
6823            return ActivityManagerService.this;
6824        }
6825    }
6826
6827    /**
6828     * This can be called with or without the global lock held.
6829     */
6830    int checkComponentPermission(String permission, int pid, int uid,
6831            int owningUid, boolean exported) {
6832        // We might be performing an operation on behalf of an indirect binder
6833        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6834        // client identity accordingly before proceeding.
6835        Identity tlsIdentity = sCallerIdentity.get();
6836        if (tlsIdentity != null) {
6837            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6838                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6839            uid = tlsIdentity.uid;
6840            pid = tlsIdentity.pid;
6841        }
6842
6843        if (pid == MY_PID) {
6844            return PackageManager.PERMISSION_GRANTED;
6845        }
6846
6847        return ActivityManager.checkComponentPermission(permission, uid,
6848                owningUid, exported);
6849    }
6850
6851    /**
6852     * As the only public entry point for permissions checking, this method
6853     * can enforce the semantic that requesting a check on a null global
6854     * permission is automatically denied.  (Internally a null permission
6855     * string is used when calling {@link #checkComponentPermission} in cases
6856     * when only uid-based security is needed.)
6857     *
6858     * This can be called with or without the global lock held.
6859     */
6860    @Override
6861    public int checkPermission(String permission, int pid, int uid) {
6862        if (permission == null) {
6863            return PackageManager.PERMISSION_DENIED;
6864        }
6865        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6866    }
6867
6868    /**
6869     * Binder IPC calls go through the public entry point.
6870     * This can be called with or without the global lock held.
6871     */
6872    int checkCallingPermission(String permission) {
6873        return checkPermission(permission,
6874                Binder.getCallingPid(),
6875                UserHandle.getAppId(Binder.getCallingUid()));
6876    }
6877
6878    /**
6879     * This can be called with or without the global lock held.
6880     */
6881    void enforceCallingPermission(String permission, String func) {
6882        if (checkCallingPermission(permission)
6883                == PackageManager.PERMISSION_GRANTED) {
6884            return;
6885        }
6886
6887        String msg = "Permission Denial: " + func + " from pid="
6888                + Binder.getCallingPid()
6889                + ", uid=" + Binder.getCallingUid()
6890                + " requires " + permission;
6891        Slog.w(TAG, msg);
6892        throw new SecurityException(msg);
6893    }
6894
6895    /**
6896     * Determine if UID is holding permissions required to access {@link Uri} in
6897     * the given {@link ProviderInfo}. Final permission checking is always done
6898     * in {@link ContentProvider}.
6899     */
6900    private final boolean checkHoldingPermissionsLocked(
6901            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6902        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6903                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6904        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6905            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6906                    != PERMISSION_GRANTED) {
6907                return false;
6908            }
6909        }
6910        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6911    }
6912
6913    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6914            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6915        if (pi.applicationInfo.uid == uid) {
6916            return true;
6917        } else if (!pi.exported) {
6918            return false;
6919        }
6920
6921        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6922        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6923        try {
6924            // check if target holds top-level <provider> permissions
6925            if (!readMet && pi.readPermission != null && considerUidPermissions
6926                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6927                readMet = true;
6928            }
6929            if (!writeMet && pi.writePermission != null && considerUidPermissions
6930                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6931                writeMet = true;
6932            }
6933
6934            // track if unprotected read/write is allowed; any denied
6935            // <path-permission> below removes this ability
6936            boolean allowDefaultRead = pi.readPermission == null;
6937            boolean allowDefaultWrite = pi.writePermission == null;
6938
6939            // check if target holds any <path-permission> that match uri
6940            final PathPermission[] pps = pi.pathPermissions;
6941            if (pps != null) {
6942                final String path = grantUri.uri.getPath();
6943                int i = pps.length;
6944                while (i > 0 && (!readMet || !writeMet)) {
6945                    i--;
6946                    PathPermission pp = pps[i];
6947                    if (pp.match(path)) {
6948                        if (!readMet) {
6949                            final String pprperm = pp.getReadPermission();
6950                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6951                                    + pprperm + " for " + pp.getPath()
6952                                    + ": match=" + pp.match(path)
6953                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6954                            if (pprperm != null) {
6955                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6956                                        == PERMISSION_GRANTED) {
6957                                    readMet = true;
6958                                } else {
6959                                    allowDefaultRead = false;
6960                                }
6961                            }
6962                        }
6963                        if (!writeMet) {
6964                            final String ppwperm = pp.getWritePermission();
6965                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6966                                    + ppwperm + " for " + pp.getPath()
6967                                    + ": match=" + pp.match(path)
6968                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6969                            if (ppwperm != null) {
6970                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6971                                        == PERMISSION_GRANTED) {
6972                                    writeMet = true;
6973                                } else {
6974                                    allowDefaultWrite = false;
6975                                }
6976                            }
6977                        }
6978                    }
6979                }
6980            }
6981
6982            // grant unprotected <provider> read/write, if not blocked by
6983            // <path-permission> above
6984            if (allowDefaultRead) readMet = true;
6985            if (allowDefaultWrite) writeMet = true;
6986
6987        } catch (RemoteException e) {
6988            return false;
6989        }
6990
6991        return readMet && writeMet;
6992    }
6993
6994    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6995        ProviderInfo pi = null;
6996        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6997        if (cpr != null) {
6998            pi = cpr.info;
6999        } else {
7000            try {
7001                pi = AppGlobals.getPackageManager().resolveContentProvider(
7002                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7003            } catch (RemoteException ex) {
7004            }
7005        }
7006        return pi;
7007    }
7008
7009    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7010        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7011        if (targetUris != null) {
7012            return targetUris.get(grantUri);
7013        }
7014        return null;
7015    }
7016
7017    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7018            String targetPkg, int targetUid, GrantUri grantUri) {
7019        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7020        if (targetUris == null) {
7021            targetUris = Maps.newArrayMap();
7022            mGrantedUriPermissions.put(targetUid, targetUris);
7023        }
7024
7025        UriPermission perm = targetUris.get(grantUri);
7026        if (perm == null) {
7027            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7028            targetUris.put(grantUri, perm);
7029        }
7030
7031        return perm;
7032    }
7033
7034    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7035            final int modeFlags) {
7036        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7037        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7038                : UriPermission.STRENGTH_OWNED;
7039
7040        // Root gets to do everything.
7041        if (uid == 0) {
7042            return true;
7043        }
7044
7045        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7046        if (perms == null) return false;
7047
7048        // First look for exact match
7049        final UriPermission exactPerm = perms.get(grantUri);
7050        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7051            return true;
7052        }
7053
7054        // No exact match, look for prefixes
7055        final int N = perms.size();
7056        for (int i = 0; i < N; i++) {
7057            final UriPermission perm = perms.valueAt(i);
7058            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7059                    && perm.getStrength(modeFlags) >= minStrength) {
7060                return true;
7061            }
7062        }
7063
7064        return false;
7065    }
7066
7067    /**
7068     * @param uri This uri must NOT contain an embedded userId.
7069     * @param userId The userId in which the uri is to be resolved.
7070     */
7071    @Override
7072    public int checkUriPermission(Uri uri, int pid, int uid,
7073            final int modeFlags, int userId) {
7074        enforceNotIsolatedCaller("checkUriPermission");
7075
7076        // Another redirected-binder-call permissions check as in
7077        // {@link checkComponentPermission}.
7078        Identity tlsIdentity = sCallerIdentity.get();
7079        if (tlsIdentity != null) {
7080            uid = tlsIdentity.uid;
7081            pid = tlsIdentity.pid;
7082        }
7083
7084        // Our own process gets to do everything.
7085        if (pid == MY_PID) {
7086            return PackageManager.PERMISSION_GRANTED;
7087        }
7088        synchronized (this) {
7089            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7090                    ? PackageManager.PERMISSION_GRANTED
7091                    : PackageManager.PERMISSION_DENIED;
7092        }
7093    }
7094
7095    /**
7096     * Check if the targetPkg can be granted permission to access uri by
7097     * the callingUid using the given modeFlags.  Throws a security exception
7098     * if callingUid is not allowed to do this.  Returns the uid of the target
7099     * if the URI permission grant should be performed; returns -1 if it is not
7100     * needed (for example targetPkg already has permission to access the URI).
7101     * If you already know the uid of the target, you can supply it in
7102     * lastTargetUid else set that to -1.
7103     */
7104    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7105            final int modeFlags, int lastTargetUid) {
7106        if (!Intent.isAccessUriMode(modeFlags)) {
7107            return -1;
7108        }
7109
7110        if (targetPkg != null) {
7111            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7112                    "Checking grant " + targetPkg + " permission to " + grantUri);
7113        }
7114
7115        final IPackageManager pm = AppGlobals.getPackageManager();
7116
7117        // If this is not a content: uri, we can't do anything with it.
7118        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7119            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7120                    "Can't grant URI permission for non-content URI: " + grantUri);
7121            return -1;
7122        }
7123
7124        final String authority = grantUri.uri.getAuthority();
7125        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7126        if (pi == null) {
7127            Slog.w(TAG, "No content provider found for permission check: " +
7128                    grantUri.uri.toSafeString());
7129            return -1;
7130        }
7131
7132        int targetUid = lastTargetUid;
7133        if (targetUid < 0 && targetPkg != null) {
7134            try {
7135                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7136                if (targetUid < 0) {
7137                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7138                            "Can't grant URI permission no uid for: " + targetPkg);
7139                    return -1;
7140                }
7141            } catch (RemoteException ex) {
7142                return -1;
7143            }
7144        }
7145
7146        if (targetUid >= 0) {
7147            // First...  does the target actually need this permission?
7148            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7149                // No need to grant the target this permission.
7150                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7151                        "Target " + targetPkg + " already has full permission to " + grantUri);
7152                return -1;
7153            }
7154        } else {
7155            // First...  there is no target package, so can anyone access it?
7156            boolean allowed = pi.exported;
7157            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7158                if (pi.readPermission != null) {
7159                    allowed = false;
7160                }
7161            }
7162            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7163                if (pi.writePermission != null) {
7164                    allowed = false;
7165                }
7166            }
7167            if (allowed) {
7168                return -1;
7169            }
7170        }
7171
7172        /* There is a special cross user grant if:
7173         * - The target is on another user.
7174         * - Apps on the current user can access the uri without any uid permissions.
7175         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7176         * grant uri permissions.
7177         */
7178        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7179                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7180                modeFlags, false /*without considering the uid permissions*/);
7181
7182        // Second...  is the provider allowing granting of URI permissions?
7183        if (!specialCrossUserGrant) {
7184            if (!pi.grantUriPermissions) {
7185                throw new SecurityException("Provider " + pi.packageName
7186                        + "/" + pi.name
7187                        + " does not allow granting of Uri permissions (uri "
7188                        + grantUri + ")");
7189            }
7190            if (pi.uriPermissionPatterns != null) {
7191                final int N = pi.uriPermissionPatterns.length;
7192                boolean allowed = false;
7193                for (int i=0; i<N; i++) {
7194                    if (pi.uriPermissionPatterns[i] != null
7195                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7196                        allowed = true;
7197                        break;
7198                    }
7199                }
7200                if (!allowed) {
7201                    throw new SecurityException("Provider " + pi.packageName
7202                            + "/" + pi.name
7203                            + " does not allow granting of permission to path of Uri "
7204                            + grantUri);
7205                }
7206            }
7207        }
7208
7209        // Third...  does the caller itself have permission to access
7210        // this uri?
7211        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7212            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7213                // Require they hold a strong enough Uri permission
7214                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7215                    throw new SecurityException("Uid " + callingUid
7216                            + " does not have permission to uri " + grantUri);
7217                }
7218            }
7219        }
7220        return targetUid;
7221    }
7222
7223    /**
7224     * @param uri This uri must NOT contain an embedded userId.
7225     * @param userId The userId in which the uri is to be resolved.
7226     */
7227    @Override
7228    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7229            final int modeFlags, int userId) {
7230        enforceNotIsolatedCaller("checkGrantUriPermission");
7231        synchronized(this) {
7232            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7233                    new GrantUri(userId, uri, false), modeFlags, -1);
7234        }
7235    }
7236
7237    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7238            final int modeFlags, UriPermissionOwner owner) {
7239        if (!Intent.isAccessUriMode(modeFlags)) {
7240            return;
7241        }
7242
7243        // So here we are: the caller has the assumed permission
7244        // to the uri, and the target doesn't.  Let's now give this to
7245        // the target.
7246
7247        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7248                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7249
7250        final String authority = grantUri.uri.getAuthority();
7251        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7252        if (pi == null) {
7253            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7254            return;
7255        }
7256
7257        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7258            grantUri.prefix = true;
7259        }
7260        final UriPermission perm = findOrCreateUriPermissionLocked(
7261                pi.packageName, targetPkg, targetUid, grantUri);
7262        perm.grantModes(modeFlags, owner);
7263    }
7264
7265    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7266            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7267        if (targetPkg == null) {
7268            throw new NullPointerException("targetPkg");
7269        }
7270        int targetUid;
7271        final IPackageManager pm = AppGlobals.getPackageManager();
7272        try {
7273            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7274        } catch (RemoteException ex) {
7275            return;
7276        }
7277
7278        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7279                targetUid);
7280        if (targetUid < 0) {
7281            return;
7282        }
7283
7284        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7285                owner);
7286    }
7287
7288    static class NeededUriGrants extends ArrayList<GrantUri> {
7289        final String targetPkg;
7290        final int targetUid;
7291        final int flags;
7292
7293        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7294            this.targetPkg = targetPkg;
7295            this.targetUid = targetUid;
7296            this.flags = flags;
7297        }
7298    }
7299
7300    /**
7301     * Like checkGrantUriPermissionLocked, but takes an Intent.
7302     */
7303    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7304            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7305        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7306                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7307                + " clip=" + (intent != null ? intent.getClipData() : null)
7308                + " from " + intent + "; flags=0x"
7309                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7310
7311        if (targetPkg == null) {
7312            throw new NullPointerException("targetPkg");
7313        }
7314
7315        if (intent == null) {
7316            return null;
7317        }
7318        Uri data = intent.getData();
7319        ClipData clip = intent.getClipData();
7320        if (data == null && clip == null) {
7321            return null;
7322        }
7323        // Default userId for uris in the intent (if they don't specify it themselves)
7324        int contentUserHint = intent.getContentUserHint();
7325        if (contentUserHint == UserHandle.USER_CURRENT) {
7326            contentUserHint = UserHandle.getUserId(callingUid);
7327        }
7328        final IPackageManager pm = AppGlobals.getPackageManager();
7329        int targetUid;
7330        if (needed != null) {
7331            targetUid = needed.targetUid;
7332        } else {
7333            try {
7334                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7335            } catch (RemoteException ex) {
7336                return null;
7337            }
7338            if (targetUid < 0) {
7339                if (DEBUG_URI_PERMISSION) {
7340                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7341                            + " on user " + targetUserId);
7342                }
7343                return null;
7344            }
7345        }
7346        if (data != null) {
7347            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7348            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7349                    targetUid);
7350            if (targetUid > 0) {
7351                if (needed == null) {
7352                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7353                }
7354                needed.add(grantUri);
7355            }
7356        }
7357        if (clip != null) {
7358            for (int i=0; i<clip.getItemCount(); i++) {
7359                Uri uri = clip.getItemAt(i).getUri();
7360                if (uri != null) {
7361                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7362                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7363                            targetUid);
7364                    if (targetUid > 0) {
7365                        if (needed == null) {
7366                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7367                        }
7368                        needed.add(grantUri);
7369                    }
7370                } else {
7371                    Intent clipIntent = clip.getItemAt(i).getIntent();
7372                    if (clipIntent != null) {
7373                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7374                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7375                        if (newNeeded != null) {
7376                            needed = newNeeded;
7377                        }
7378                    }
7379                }
7380            }
7381        }
7382
7383        return needed;
7384    }
7385
7386    /**
7387     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7388     */
7389    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7390            UriPermissionOwner owner) {
7391        if (needed != null) {
7392            for (int i=0; i<needed.size(); i++) {
7393                GrantUri grantUri = needed.get(i);
7394                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7395                        grantUri, needed.flags, owner);
7396            }
7397        }
7398    }
7399
7400    void grantUriPermissionFromIntentLocked(int callingUid,
7401            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7402        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7403                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7404        if (needed == null) {
7405            return;
7406        }
7407
7408        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7409    }
7410
7411    /**
7412     * @param uri This uri must NOT contain an embedded userId.
7413     * @param userId The userId in which the uri is to be resolved.
7414     */
7415    @Override
7416    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7417            final int modeFlags, int userId) {
7418        enforceNotIsolatedCaller("grantUriPermission");
7419        GrantUri grantUri = new GrantUri(userId, uri, false);
7420        synchronized(this) {
7421            final ProcessRecord r = getRecordForAppLocked(caller);
7422            if (r == null) {
7423                throw new SecurityException("Unable to find app for caller "
7424                        + caller
7425                        + " when granting permission to uri " + grantUri);
7426            }
7427            if (targetPkg == null) {
7428                throw new IllegalArgumentException("null target");
7429            }
7430            if (grantUri == null) {
7431                throw new IllegalArgumentException("null uri");
7432            }
7433
7434            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7435                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7436                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7437                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7438
7439            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7440                    UserHandle.getUserId(r.uid));
7441        }
7442    }
7443
7444    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7445        if (perm.modeFlags == 0) {
7446            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7447                    perm.targetUid);
7448            if (perms != null) {
7449                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7450                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7451
7452                perms.remove(perm.uri);
7453                if (perms.isEmpty()) {
7454                    mGrantedUriPermissions.remove(perm.targetUid);
7455                }
7456            }
7457        }
7458    }
7459
7460    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7461        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7462
7463        final IPackageManager pm = AppGlobals.getPackageManager();
7464        final String authority = grantUri.uri.getAuthority();
7465        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7466        if (pi == null) {
7467            Slog.w(TAG, "No content provider found for permission revoke: "
7468                    + grantUri.toSafeString());
7469            return;
7470        }
7471
7472        // Does the caller have this permission on the URI?
7473        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7474            // Have they don't have direct access to the URI, then revoke any URI
7475            // permissions that have been granted to them.
7476            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7477            if (perms != null) {
7478                boolean persistChanged = false;
7479                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7480                    final UriPermission perm = it.next();
7481                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7482                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7483                        if (DEBUG_URI_PERMISSION)
7484                            Slog.v(TAG,
7485                                    "Revoking " + perm.targetUid + " permission to " + perm.uri);
7486                        persistChanged |= perm.revokeModes(
7487                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7488                        if (perm.modeFlags == 0) {
7489                            it.remove();
7490                        }
7491                    }
7492                }
7493                if (perms.isEmpty()) {
7494                    mGrantedUriPermissions.remove(callingUid);
7495                }
7496                if (persistChanged) {
7497                    schedulePersistUriGrants();
7498                }
7499            }
7500            return;
7501        }
7502
7503        boolean persistChanged = false;
7504
7505        // Go through all of the permissions and remove any that match.
7506        int N = mGrantedUriPermissions.size();
7507        for (int i = 0; i < N; i++) {
7508            final int targetUid = mGrantedUriPermissions.keyAt(i);
7509            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7510
7511            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7512                final UriPermission perm = it.next();
7513                if (perm.uri.sourceUserId == grantUri.sourceUserId
7514                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7515                    if (DEBUG_URI_PERMISSION)
7516                        Slog.v(TAG,
7517                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7518                    persistChanged |= perm.revokeModes(
7519                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7520                    if (perm.modeFlags == 0) {
7521                        it.remove();
7522                    }
7523                }
7524            }
7525
7526            if (perms.isEmpty()) {
7527                mGrantedUriPermissions.remove(targetUid);
7528                N--;
7529                i--;
7530            }
7531        }
7532
7533        if (persistChanged) {
7534            schedulePersistUriGrants();
7535        }
7536    }
7537
7538    /**
7539     * @param uri This uri must NOT contain an embedded userId.
7540     * @param userId The userId in which the uri is to be resolved.
7541     */
7542    @Override
7543    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7544            int userId) {
7545        enforceNotIsolatedCaller("revokeUriPermission");
7546        synchronized(this) {
7547            final ProcessRecord r = getRecordForAppLocked(caller);
7548            if (r == null) {
7549                throw new SecurityException("Unable to find app for caller "
7550                        + caller
7551                        + " when revoking permission to uri " + uri);
7552            }
7553            if (uri == null) {
7554                Slog.w(TAG, "revokeUriPermission: null uri");
7555                return;
7556            }
7557
7558            if (!Intent.isAccessUriMode(modeFlags)) {
7559                return;
7560            }
7561
7562            final IPackageManager pm = AppGlobals.getPackageManager();
7563            final String authority = uri.getAuthority();
7564            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7565            if (pi == null) {
7566                Slog.w(TAG, "No content provider found for permission revoke: "
7567                        + uri.toSafeString());
7568                return;
7569            }
7570
7571            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7572        }
7573    }
7574
7575    /**
7576     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7577     * given package.
7578     *
7579     * @param packageName Package name to match, or {@code null} to apply to all
7580     *            packages.
7581     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7582     *            to all users.
7583     * @param persistable If persistable grants should be removed.
7584     */
7585    private void removeUriPermissionsForPackageLocked(
7586            String packageName, int userHandle, boolean persistable) {
7587        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7588            throw new IllegalArgumentException("Must narrow by either package or user");
7589        }
7590
7591        boolean persistChanged = false;
7592
7593        int N = mGrantedUriPermissions.size();
7594        for (int i = 0; i < N; i++) {
7595            final int targetUid = mGrantedUriPermissions.keyAt(i);
7596            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7597
7598            // Only inspect grants matching user
7599            if (userHandle == UserHandle.USER_ALL
7600                    || userHandle == UserHandle.getUserId(targetUid)) {
7601                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7602                    final UriPermission perm = it.next();
7603
7604                    // Only inspect grants matching package
7605                    if (packageName == null || perm.sourcePkg.equals(packageName)
7606                            || perm.targetPkg.equals(packageName)) {
7607                        persistChanged |= perm.revokeModes(
7608                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7609
7610                        // Only remove when no modes remain; any persisted grants
7611                        // will keep this alive.
7612                        if (perm.modeFlags == 0) {
7613                            it.remove();
7614                        }
7615                    }
7616                }
7617
7618                if (perms.isEmpty()) {
7619                    mGrantedUriPermissions.remove(targetUid);
7620                    N--;
7621                    i--;
7622                }
7623            }
7624        }
7625
7626        if (persistChanged) {
7627            schedulePersistUriGrants();
7628        }
7629    }
7630
7631    @Override
7632    public IBinder newUriPermissionOwner(String name) {
7633        enforceNotIsolatedCaller("newUriPermissionOwner");
7634        synchronized(this) {
7635            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7636            return owner.getExternalTokenLocked();
7637        }
7638    }
7639
7640    /**
7641     * @param uri This uri must NOT contain an embedded userId.
7642     * @param sourceUserId The userId in which the uri is to be resolved.
7643     * @param targetUserId The userId of the app that receives the grant.
7644     */
7645    @Override
7646    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7647            final int modeFlags, int sourceUserId, int targetUserId) {
7648        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7649                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7650        synchronized(this) {
7651            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7652            if (owner == null) {
7653                throw new IllegalArgumentException("Unknown owner: " + token);
7654            }
7655            if (fromUid != Binder.getCallingUid()) {
7656                if (Binder.getCallingUid() != Process.myUid()) {
7657                    // Only system code can grant URI permissions on behalf
7658                    // of other users.
7659                    throw new SecurityException("nice try");
7660                }
7661            }
7662            if (targetPkg == null) {
7663                throw new IllegalArgumentException("null target");
7664            }
7665            if (uri == null) {
7666                throw new IllegalArgumentException("null uri");
7667            }
7668
7669            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7670                    modeFlags, owner, targetUserId);
7671        }
7672    }
7673
7674    /**
7675     * @param uri This uri must NOT contain an embedded userId.
7676     * @param userId The userId in which the uri is to be resolved.
7677     */
7678    @Override
7679    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7680        synchronized(this) {
7681            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7682            if (owner == null) {
7683                throw new IllegalArgumentException("Unknown owner: " + token);
7684            }
7685
7686            if (uri == null) {
7687                owner.removeUriPermissionsLocked(mode);
7688            } else {
7689                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7690            }
7691        }
7692    }
7693
7694    private void schedulePersistUriGrants() {
7695        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7696            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7697                    10 * DateUtils.SECOND_IN_MILLIS);
7698        }
7699    }
7700
7701    private void writeGrantedUriPermissions() {
7702        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7703
7704        // Snapshot permissions so we can persist without lock
7705        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7706        synchronized (this) {
7707            final int size = mGrantedUriPermissions.size();
7708            for (int i = 0; i < size; i++) {
7709                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7710                for (UriPermission perm : perms.values()) {
7711                    if (perm.persistedModeFlags != 0) {
7712                        persist.add(perm.snapshot());
7713                    }
7714                }
7715            }
7716        }
7717
7718        FileOutputStream fos = null;
7719        try {
7720            fos = mGrantFile.startWrite();
7721
7722            XmlSerializer out = new FastXmlSerializer();
7723            out.setOutput(fos, "utf-8");
7724            out.startDocument(null, true);
7725            out.startTag(null, TAG_URI_GRANTS);
7726            for (UriPermission.Snapshot perm : persist) {
7727                out.startTag(null, TAG_URI_GRANT);
7728                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7729                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7730                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7731                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7732                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7733                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7734                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7735                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7736                out.endTag(null, TAG_URI_GRANT);
7737            }
7738            out.endTag(null, TAG_URI_GRANTS);
7739            out.endDocument();
7740
7741            mGrantFile.finishWrite(fos);
7742        } catch (IOException e) {
7743            if (fos != null) {
7744                mGrantFile.failWrite(fos);
7745            }
7746        }
7747    }
7748
7749    private void readGrantedUriPermissionsLocked() {
7750        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7751
7752        final long now = System.currentTimeMillis();
7753
7754        FileInputStream fis = null;
7755        try {
7756            fis = mGrantFile.openRead();
7757            final XmlPullParser in = Xml.newPullParser();
7758            in.setInput(fis, null);
7759
7760            int type;
7761            while ((type = in.next()) != END_DOCUMENT) {
7762                final String tag = in.getName();
7763                if (type == START_TAG) {
7764                    if (TAG_URI_GRANT.equals(tag)) {
7765                        final int sourceUserId;
7766                        final int targetUserId;
7767                        final int userHandle = readIntAttribute(in,
7768                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7769                        if (userHandle != UserHandle.USER_NULL) {
7770                            // For backwards compatibility.
7771                            sourceUserId = userHandle;
7772                            targetUserId = userHandle;
7773                        } else {
7774                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7775                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7776                        }
7777                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7778                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7779                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7780                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7781                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7782                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7783
7784                        // Sanity check that provider still belongs to source package
7785                        final ProviderInfo pi = getProviderInfoLocked(
7786                                uri.getAuthority(), sourceUserId);
7787                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7788                            int targetUid = -1;
7789                            try {
7790                                targetUid = AppGlobals.getPackageManager()
7791                                        .getPackageUid(targetPkg, targetUserId);
7792                            } catch (RemoteException e) {
7793                            }
7794                            if (targetUid != -1) {
7795                                final UriPermission perm = findOrCreateUriPermissionLocked(
7796                                        sourcePkg, targetPkg, targetUid,
7797                                        new GrantUri(sourceUserId, uri, prefix));
7798                                perm.initPersistedModes(modeFlags, createdTime);
7799                            }
7800                        } else {
7801                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7802                                    + " but instead found " + pi);
7803                        }
7804                    }
7805                }
7806            }
7807        } catch (FileNotFoundException e) {
7808            // Missing grants is okay
7809        } catch (IOException e) {
7810            Log.wtf(TAG, "Failed reading Uri grants", e);
7811        } catch (XmlPullParserException e) {
7812            Log.wtf(TAG, "Failed reading Uri grants", e);
7813        } finally {
7814            IoUtils.closeQuietly(fis);
7815        }
7816    }
7817
7818    /**
7819     * @param uri This uri must NOT contain an embedded userId.
7820     * @param userId The userId in which the uri is to be resolved.
7821     */
7822    @Override
7823    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7824        enforceNotIsolatedCaller("takePersistableUriPermission");
7825
7826        Preconditions.checkFlagsArgument(modeFlags,
7827                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7828
7829        synchronized (this) {
7830            final int callingUid = Binder.getCallingUid();
7831            boolean persistChanged = false;
7832            GrantUri grantUri = new GrantUri(userId, uri, false);
7833
7834            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7835                    new GrantUri(userId, uri, false));
7836            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7837                    new GrantUri(userId, uri, true));
7838
7839            final boolean exactValid = (exactPerm != null)
7840                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7841            final boolean prefixValid = (prefixPerm != null)
7842                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7843
7844            if (!(exactValid || prefixValid)) {
7845                throw new SecurityException("No persistable permission grants found for UID "
7846                        + callingUid + " and Uri " + grantUri.toSafeString());
7847            }
7848
7849            if (exactValid) {
7850                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7851            }
7852            if (prefixValid) {
7853                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7854            }
7855
7856            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7857
7858            if (persistChanged) {
7859                schedulePersistUriGrants();
7860            }
7861        }
7862    }
7863
7864    /**
7865     * @param uri This uri must NOT contain an embedded userId.
7866     * @param userId The userId in which the uri is to be resolved.
7867     */
7868    @Override
7869    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7870        enforceNotIsolatedCaller("releasePersistableUriPermission");
7871
7872        Preconditions.checkFlagsArgument(modeFlags,
7873                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7874
7875        synchronized (this) {
7876            final int callingUid = Binder.getCallingUid();
7877            boolean persistChanged = false;
7878
7879            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7880                    new GrantUri(userId, uri, false));
7881            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7882                    new GrantUri(userId, uri, true));
7883            if (exactPerm == null && prefixPerm == null) {
7884                throw new SecurityException("No permission grants found for UID " + callingUid
7885                        + " and Uri " + uri.toSafeString());
7886            }
7887
7888            if (exactPerm != null) {
7889                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7890                removeUriPermissionIfNeededLocked(exactPerm);
7891            }
7892            if (prefixPerm != null) {
7893                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7894                removeUriPermissionIfNeededLocked(prefixPerm);
7895            }
7896
7897            if (persistChanged) {
7898                schedulePersistUriGrants();
7899            }
7900        }
7901    }
7902
7903    /**
7904     * Prune any older {@link UriPermission} for the given UID until outstanding
7905     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7906     *
7907     * @return if any mutations occured that require persisting.
7908     */
7909    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7910        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7911        if (perms == null) return false;
7912        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7913
7914        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7915        for (UriPermission perm : perms.values()) {
7916            if (perm.persistedModeFlags != 0) {
7917                persisted.add(perm);
7918            }
7919        }
7920
7921        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7922        if (trimCount <= 0) return false;
7923
7924        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7925        for (int i = 0; i < trimCount; i++) {
7926            final UriPermission perm = persisted.get(i);
7927
7928            if (DEBUG_URI_PERMISSION) {
7929                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7930            }
7931
7932            perm.releasePersistableModes(~0);
7933            removeUriPermissionIfNeededLocked(perm);
7934        }
7935
7936        return true;
7937    }
7938
7939    @Override
7940    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7941            String packageName, boolean incoming) {
7942        enforceNotIsolatedCaller("getPersistedUriPermissions");
7943        Preconditions.checkNotNull(packageName, "packageName");
7944
7945        final int callingUid = Binder.getCallingUid();
7946        final IPackageManager pm = AppGlobals.getPackageManager();
7947        try {
7948            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7949            if (packageUid != callingUid) {
7950                throw new SecurityException(
7951                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7952            }
7953        } catch (RemoteException e) {
7954            throw new SecurityException("Failed to verify package name ownership");
7955        }
7956
7957        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7958        synchronized (this) {
7959            if (incoming) {
7960                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7961                        callingUid);
7962                if (perms == null) {
7963                    Slog.w(TAG, "No permission grants found for " + packageName);
7964                } else {
7965                    for (UriPermission perm : perms.values()) {
7966                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7967                            result.add(perm.buildPersistedPublicApiObject());
7968                        }
7969                    }
7970                }
7971            } else {
7972                final int size = mGrantedUriPermissions.size();
7973                for (int i = 0; i < size; i++) {
7974                    final ArrayMap<GrantUri, UriPermission> perms =
7975                            mGrantedUriPermissions.valueAt(i);
7976                    for (UriPermission perm : perms.values()) {
7977                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7978                            result.add(perm.buildPersistedPublicApiObject());
7979                        }
7980                    }
7981                }
7982            }
7983        }
7984        return new ParceledListSlice<android.content.UriPermission>(result);
7985    }
7986
7987    @Override
7988    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7989        synchronized (this) {
7990            ProcessRecord app =
7991                who != null ? getRecordForAppLocked(who) : null;
7992            if (app == null) return;
7993
7994            Message msg = Message.obtain();
7995            msg.what = WAIT_FOR_DEBUGGER_MSG;
7996            msg.obj = app;
7997            msg.arg1 = waiting ? 1 : 0;
7998            mHandler.sendMessage(msg);
7999        }
8000    }
8001
8002    @Override
8003    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8004        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8005        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8006        outInfo.availMem = Process.getFreeMemory();
8007        outInfo.totalMem = Process.getTotalMemory();
8008        outInfo.threshold = homeAppMem;
8009        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8010        outInfo.hiddenAppThreshold = cachedAppMem;
8011        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8012                ProcessList.SERVICE_ADJ);
8013        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8014                ProcessList.VISIBLE_APP_ADJ);
8015        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8016                ProcessList.FOREGROUND_APP_ADJ);
8017    }
8018
8019    // =========================================================
8020    // TASK MANAGEMENT
8021    // =========================================================
8022
8023    @Override
8024    public List<IAppTask> getAppTasks(String callingPackage) {
8025        int callingUid = Binder.getCallingUid();
8026        long ident = Binder.clearCallingIdentity();
8027
8028        synchronized(this) {
8029            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8030            try {
8031                if (localLOGV) Slog.v(TAG, "getAppTasks");
8032
8033                final int N = mRecentTasks.size();
8034                for (int i = 0; i < N; i++) {
8035                    TaskRecord tr = mRecentTasks.get(i);
8036                    // Skip tasks that do not match the caller.  We don't need to verify
8037                    // callingPackage, because we are also limiting to callingUid and know
8038                    // that will limit to the correct security sandbox.
8039                    if (tr.effectiveUid != callingUid) {
8040                        continue;
8041                    }
8042                    Intent intent = tr.getBaseIntent();
8043                    if (intent == null ||
8044                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8045                        continue;
8046                    }
8047                    ActivityManager.RecentTaskInfo taskInfo =
8048                            createRecentTaskInfoFromTaskRecord(tr);
8049                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8050                    list.add(taskImpl);
8051                }
8052            } finally {
8053                Binder.restoreCallingIdentity(ident);
8054            }
8055            return list;
8056        }
8057    }
8058
8059    @Override
8060    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8061        final int callingUid = Binder.getCallingUid();
8062        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8063
8064        synchronized(this) {
8065            if (localLOGV) Slog.v(
8066                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8067
8068            final boolean allowed = checkCallingPermission(
8069                    android.Manifest.permission.GET_TASKS)
8070                    == PackageManager.PERMISSION_GRANTED;
8071            if (!allowed) {
8072                Slog.w(TAG, "getTasks: caller " + callingUid
8073                        + " does not hold GET_TASKS; limiting output");
8074            }
8075
8076            // TODO: Improve with MRU list from all ActivityStacks.
8077            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8078        }
8079
8080        return list;
8081    }
8082
8083    TaskRecord getMostRecentTask() {
8084        return mRecentTasks.get(0);
8085    }
8086
8087    /**
8088     * Creates a new RecentTaskInfo from a TaskRecord.
8089     */
8090    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8091        // Update the task description to reflect any changes in the task stack
8092        tr.updateTaskDescription();
8093
8094        // Compose the recent task info
8095        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8096        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8097        rti.persistentId = tr.taskId;
8098        rti.baseIntent = new Intent(tr.getBaseIntent());
8099        rti.origActivity = tr.origActivity;
8100        rti.description = tr.lastDescription;
8101        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8102        rti.userId = tr.userId;
8103        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8104        rti.firstActiveTime = tr.firstActiveTime;
8105        rti.lastActiveTime = tr.lastActiveTime;
8106        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8107        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8108        return rti;
8109    }
8110
8111    @Override
8112    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8113        final int callingUid = Binder.getCallingUid();
8114        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8115                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8116
8117        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8118        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8119        synchronized (this) {
8120            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
8121                    == PackageManager.PERMISSION_GRANTED;
8122            if (!allowed) {
8123                Slog.w(TAG, "getRecentTasks: caller " + callingUid
8124                        + " does not hold GET_TASKS; limiting output");
8125            }
8126            final boolean detailed = checkCallingPermission(
8127                    android.Manifest.permission.GET_DETAILED_TASKS)
8128                    == PackageManager.PERMISSION_GRANTED;
8129
8130            final int N = mRecentTasks.size();
8131            ArrayList<ActivityManager.RecentTaskInfo> res
8132                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8133                            maxNum < N ? maxNum : N);
8134
8135            final Set<Integer> includedUsers;
8136            if (includeProfiles) {
8137                includedUsers = getProfileIdsLocked(userId);
8138            } else {
8139                includedUsers = new HashSet<Integer>();
8140            }
8141            includedUsers.add(Integer.valueOf(userId));
8142
8143            for (int i=0; i<N && maxNum > 0; i++) {
8144                TaskRecord tr = mRecentTasks.get(i);
8145                // Only add calling user or related users recent tasks
8146                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8147                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8148                    continue;
8149                }
8150
8151                // Return the entry if desired by the caller.  We always return
8152                // the first entry, because callers always expect this to be the
8153                // foreground app.  We may filter others if the caller has
8154                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8155                // we should exclude the entry.
8156
8157                if (i == 0
8158                        || withExcluded
8159                        || (tr.intent == null)
8160                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8161                                == 0)) {
8162                    if (!allowed) {
8163                        // If the caller doesn't have the GET_TASKS permission, then only
8164                        // allow them to see a small subset of tasks -- their own and home.
8165                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8166                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8167                            continue;
8168                        }
8169                    }
8170                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8171                        if (tr.stack != null && tr.stack.isHomeStack()) {
8172                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8173                            continue;
8174                        }
8175                    }
8176                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8177                        // Don't include auto remove tasks that are finished or finishing.
8178                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8179                                + tr);
8180                        continue;
8181                    }
8182                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8183                            && !tr.isAvailable) {
8184                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8185                        continue;
8186                    }
8187
8188                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8189                    if (!detailed) {
8190                        rti.baseIntent.replaceExtras((Bundle)null);
8191                    }
8192
8193                    res.add(rti);
8194                    maxNum--;
8195                }
8196            }
8197            return res;
8198        }
8199    }
8200
8201    private TaskRecord recentTaskForIdLocked(int id) {
8202        final int N = mRecentTasks.size();
8203            for (int i=0; i<N; i++) {
8204                TaskRecord tr = mRecentTasks.get(i);
8205                if (tr.taskId == id) {
8206                    return tr;
8207                }
8208            }
8209            return null;
8210    }
8211
8212    @Override
8213    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8214        synchronized (this) {
8215            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8216                    "getTaskThumbnail()");
8217            TaskRecord tr = recentTaskForIdLocked(id);
8218            if (tr != null) {
8219                return tr.getTaskThumbnailLocked();
8220            }
8221        }
8222        return null;
8223    }
8224
8225    @Override
8226    public int addAppTask(IBinder activityToken, Intent intent,
8227            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8228        final int callingUid = Binder.getCallingUid();
8229        final long callingIdent = Binder.clearCallingIdentity();
8230
8231        try {
8232            synchronized (this) {
8233                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8234                if (r == null) {
8235                    throw new IllegalArgumentException("Activity does not exist; token="
8236                            + activityToken);
8237                }
8238                ComponentName comp = intent.getComponent();
8239                if (comp == null) {
8240                    throw new IllegalArgumentException("Intent " + intent
8241                            + " must specify explicit component");
8242                }
8243                if (thumbnail.getWidth() != mThumbnailWidth
8244                        || thumbnail.getHeight() != mThumbnailHeight) {
8245                    throw new IllegalArgumentException("Bad thumbnail size: got "
8246                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8247                            + mThumbnailWidth + "x" + mThumbnailHeight);
8248                }
8249                if (intent.getSelector() != null) {
8250                    intent.setSelector(null);
8251                }
8252                if (intent.getSourceBounds() != null) {
8253                    intent.setSourceBounds(null);
8254                }
8255                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8256                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8257                        // The caller has added this as an auto-remove task...  that makes no
8258                        // sense, so turn off auto-remove.
8259                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8260                    }
8261                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8262                    // Must be a new task.
8263                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8264                }
8265                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8266                    mLastAddedTaskActivity = null;
8267                }
8268                ActivityInfo ainfo = mLastAddedTaskActivity;
8269                if (ainfo == null) {
8270                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8271                            comp, 0, UserHandle.getUserId(callingUid));
8272                    if (ainfo.applicationInfo.uid != callingUid) {
8273                        throw new SecurityException(
8274                                "Can't add task for another application: target uid="
8275                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8276                    }
8277                }
8278
8279                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8280                        intent, description);
8281
8282                int trimIdx = trimRecentsForTask(task, false);
8283                if (trimIdx >= 0) {
8284                    // If this would have caused a trim, then we'll abort because that
8285                    // means it would be added at the end of the list but then just removed.
8286                    return -1;
8287                }
8288
8289                final int N = mRecentTasks.size();
8290                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8291                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8292                    tr.removedFromRecents(mTaskPersister);
8293                }
8294
8295                task.inRecents = true;
8296                mRecentTasks.add(task);
8297                r.task.stack.addTask(task, false, false);
8298
8299                task.setLastThumbnail(thumbnail);
8300                task.freeLastThumbnail();
8301
8302                return task.taskId;
8303            }
8304        } finally {
8305            Binder.restoreCallingIdentity(callingIdent);
8306        }
8307    }
8308
8309    @Override
8310    public Point getAppTaskThumbnailSize() {
8311        synchronized (this) {
8312            return new Point(mThumbnailWidth,  mThumbnailHeight);
8313        }
8314    }
8315
8316    @Override
8317    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8318        synchronized (this) {
8319            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8320            if (r != null) {
8321                r.taskDescription = td;
8322                r.task.updateTaskDescription();
8323            }
8324        }
8325    }
8326
8327    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8328        mRecentTasks.remove(tr);
8329        tr.removedFromRecents(mTaskPersister);
8330        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8331        Intent baseIntent = new Intent(
8332                tr.intent != null ? tr.intent : tr.affinityIntent);
8333        ComponentName component = baseIntent.getComponent();
8334        if (component == null) {
8335            Slog.w(TAG, "Now component for base intent of task: " + tr);
8336            return;
8337        }
8338
8339        // Find any running services associated with this app.
8340        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8341
8342        if (killProcesses) {
8343            // Find any running processes associated with this app.
8344            final String pkg = component.getPackageName();
8345            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8346            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8347            for (int i=0; i<pmap.size(); i++) {
8348                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8349                for (int j=0; j<uids.size(); j++) {
8350                    ProcessRecord proc = uids.valueAt(j);
8351                    if (proc.userId != tr.userId) {
8352                        continue;
8353                    }
8354                    if (!proc.pkgList.containsKey(pkg)) {
8355                        continue;
8356                    }
8357                    procs.add(proc);
8358                }
8359            }
8360
8361            // Kill the running processes.
8362            for (int i=0; i<procs.size(); i++) {
8363                ProcessRecord pr = procs.get(i);
8364                if (pr == mHomeProcess) {
8365                    // Don't kill the home process along with tasks from the same package.
8366                    continue;
8367                }
8368                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8369                    pr.kill("remove task", true);
8370                } else {
8371                    pr.waitingToKill = "remove task";
8372                }
8373            }
8374        }
8375    }
8376
8377    /**
8378     * Removes the task with the specified task id.
8379     *
8380     * @param taskId Identifier of the task to be removed.
8381     * @param flags Additional operational flags.  May be 0 or
8382     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8383     * @return Returns true if the given task was found and removed.
8384     */
8385    private boolean removeTaskByIdLocked(int taskId, int flags) {
8386        TaskRecord tr = recentTaskForIdLocked(taskId);
8387        if (tr != null) {
8388            tr.removeTaskActivitiesLocked();
8389            cleanUpRemovedTaskLocked(tr, flags);
8390            if (tr.isPersistable) {
8391                notifyTaskPersisterLocked(null, true);
8392            }
8393            return true;
8394        }
8395        return false;
8396    }
8397
8398    @Override
8399    public boolean removeTask(int taskId, int flags) {
8400        synchronized (this) {
8401            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8402                    "removeTask()");
8403            long ident = Binder.clearCallingIdentity();
8404            try {
8405                return removeTaskByIdLocked(taskId, flags);
8406            } finally {
8407                Binder.restoreCallingIdentity(ident);
8408            }
8409        }
8410    }
8411
8412    /**
8413     * TODO: Add mController hook
8414     */
8415    @Override
8416    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8417        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8418                "moveTaskToFront()");
8419
8420        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8421        synchronized(this) {
8422            moveTaskToFrontLocked(taskId, flags, options);
8423        }
8424    }
8425
8426    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8427        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8428                Binder.getCallingUid(), "Task to front")) {
8429            ActivityOptions.abort(options);
8430            return;
8431        }
8432        final long origId = Binder.clearCallingIdentity();
8433        try {
8434            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8435            if (task == null) {
8436                return;
8437            }
8438            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8439                mStackSupervisor.showLockTaskToast();
8440                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8441                return;
8442            }
8443            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8444            if (prev != null && prev.isRecentsActivity()) {
8445                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8446            }
8447            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8448        } finally {
8449            Binder.restoreCallingIdentity(origId);
8450        }
8451        ActivityOptions.abort(options);
8452    }
8453
8454    @Override
8455    public void moveTaskToBack(int taskId) {
8456        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8457                "moveTaskToBack()");
8458
8459        synchronized(this) {
8460            TaskRecord tr = recentTaskForIdLocked(taskId);
8461            if (tr != null) {
8462                if (tr == mStackSupervisor.mLockTaskModeTask) {
8463                    mStackSupervisor.showLockTaskToast();
8464                    return;
8465                }
8466                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8467                ActivityStack stack = tr.stack;
8468                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8469                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8470                            Binder.getCallingUid(), "Task to back")) {
8471                        return;
8472                    }
8473                }
8474                final long origId = Binder.clearCallingIdentity();
8475                try {
8476                    stack.moveTaskToBackLocked(taskId, null);
8477                } finally {
8478                    Binder.restoreCallingIdentity(origId);
8479                }
8480            }
8481        }
8482    }
8483
8484    /**
8485     * Moves an activity, and all of the other activities within the same task, to the bottom
8486     * of the history stack.  The activity's order within the task is unchanged.
8487     *
8488     * @param token A reference to the activity we wish to move
8489     * @param nonRoot If false then this only works if the activity is the root
8490     *                of a task; if true it will work for any activity in a task.
8491     * @return Returns true if the move completed, false if not.
8492     */
8493    @Override
8494    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8495        enforceNotIsolatedCaller("moveActivityTaskToBack");
8496        synchronized(this) {
8497            final long origId = Binder.clearCallingIdentity();
8498            try {
8499                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8500                if (taskId >= 0) {
8501                    if ((mStackSupervisor.mLockTaskModeTask != null)
8502                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8503                        mStackSupervisor.showLockTaskToast();
8504                        return false;
8505                    }
8506                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8507                }
8508            } finally {
8509                Binder.restoreCallingIdentity(origId);
8510            }
8511        }
8512        return false;
8513    }
8514
8515    @Override
8516    public void moveTaskBackwards(int task) {
8517        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8518                "moveTaskBackwards()");
8519
8520        synchronized(this) {
8521            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8522                    Binder.getCallingUid(), "Task backwards")) {
8523                return;
8524            }
8525            final long origId = Binder.clearCallingIdentity();
8526            moveTaskBackwardsLocked(task);
8527            Binder.restoreCallingIdentity(origId);
8528        }
8529    }
8530
8531    private final void moveTaskBackwardsLocked(int task) {
8532        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8533    }
8534
8535    @Override
8536    public IBinder getHomeActivityToken() throws RemoteException {
8537        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8538                "getHomeActivityToken()");
8539        synchronized (this) {
8540            return mStackSupervisor.getHomeActivityToken();
8541        }
8542    }
8543
8544    @Override
8545    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8546            IActivityContainerCallback callback) throws RemoteException {
8547        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8548                "createActivityContainer()");
8549        synchronized (this) {
8550            if (parentActivityToken == null) {
8551                throw new IllegalArgumentException("parent token must not be null");
8552            }
8553            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8554            if (r == null) {
8555                return null;
8556            }
8557            if (callback == null) {
8558                throw new IllegalArgumentException("callback must not be null");
8559            }
8560            return mStackSupervisor.createActivityContainer(r, callback);
8561        }
8562    }
8563
8564    @Override
8565    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8566        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8567                "deleteActivityContainer()");
8568        synchronized (this) {
8569            mStackSupervisor.deleteActivityContainer(container);
8570        }
8571    }
8572
8573    @Override
8574    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8575            throws RemoteException {
8576        synchronized (this) {
8577            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8578            if (stack != null) {
8579                return stack.mActivityContainer;
8580            }
8581            return null;
8582        }
8583    }
8584
8585    @Override
8586    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8587        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8588                "moveTaskToStack()");
8589        if (stackId == HOME_STACK_ID) {
8590            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8591                    new RuntimeException("here").fillInStackTrace());
8592        }
8593        synchronized (this) {
8594            long ident = Binder.clearCallingIdentity();
8595            try {
8596                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8597                        + stackId + " toTop=" + toTop);
8598                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8599            } finally {
8600                Binder.restoreCallingIdentity(ident);
8601            }
8602        }
8603    }
8604
8605    @Override
8606    public void resizeStack(int stackBoxId, Rect bounds) {
8607        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8608                "resizeStackBox()");
8609        long ident = Binder.clearCallingIdentity();
8610        try {
8611            mWindowManager.resizeStack(stackBoxId, bounds);
8612        } finally {
8613            Binder.restoreCallingIdentity(ident);
8614        }
8615    }
8616
8617    @Override
8618    public List<StackInfo> getAllStackInfos() {
8619        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8620                "getAllStackInfos()");
8621        long ident = Binder.clearCallingIdentity();
8622        try {
8623            synchronized (this) {
8624                return mStackSupervisor.getAllStackInfosLocked();
8625            }
8626        } finally {
8627            Binder.restoreCallingIdentity(ident);
8628        }
8629    }
8630
8631    @Override
8632    public StackInfo getStackInfo(int stackId) {
8633        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8634                "getStackInfo()");
8635        long ident = Binder.clearCallingIdentity();
8636        try {
8637            synchronized (this) {
8638                return mStackSupervisor.getStackInfoLocked(stackId);
8639            }
8640        } finally {
8641            Binder.restoreCallingIdentity(ident);
8642        }
8643    }
8644
8645    @Override
8646    public boolean isInHomeStack(int taskId) {
8647        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8648                "getStackInfo()");
8649        long ident = Binder.clearCallingIdentity();
8650        try {
8651            synchronized (this) {
8652                TaskRecord tr = recentTaskForIdLocked(taskId);
8653                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8654            }
8655        } finally {
8656            Binder.restoreCallingIdentity(ident);
8657        }
8658    }
8659
8660    @Override
8661    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8662        synchronized(this) {
8663            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8664        }
8665    }
8666
8667    private boolean isLockTaskAuthorized(String pkg) {
8668        final DevicePolicyManager dpm = (DevicePolicyManager)
8669                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8670        try {
8671            int uid = mContext.getPackageManager().getPackageUid(pkg,
8672                    Binder.getCallingUserHandle().getIdentifier());
8673            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8674        } catch (NameNotFoundException e) {
8675            return false;
8676        }
8677    }
8678
8679    void startLockTaskMode(TaskRecord task) {
8680        final String pkg;
8681        synchronized (this) {
8682            pkg = task.intent.getComponent().getPackageName();
8683        }
8684        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8685        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8686            final TaskRecord taskRecord = task;
8687            mHandler.post(new Runnable() {
8688                @Override
8689                public void run() {
8690                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8691                }
8692            });
8693            return;
8694        }
8695        long ident = Binder.clearCallingIdentity();
8696        try {
8697            synchronized (this) {
8698                // Since we lost lock on task, make sure it is still there.
8699                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8700                if (task != null) {
8701                    if (!isSystemInitiated
8702                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8703                        throw new IllegalArgumentException("Invalid task, not in foreground");
8704                    }
8705                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8706                }
8707            }
8708        } finally {
8709            Binder.restoreCallingIdentity(ident);
8710        }
8711    }
8712
8713    @Override
8714    public void startLockTaskMode(int taskId) {
8715        final TaskRecord task;
8716        long ident = Binder.clearCallingIdentity();
8717        try {
8718            synchronized (this) {
8719                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8720            }
8721        } finally {
8722            Binder.restoreCallingIdentity(ident);
8723        }
8724        if (task != null) {
8725            startLockTaskMode(task);
8726        }
8727    }
8728
8729    @Override
8730    public void startLockTaskMode(IBinder token) {
8731        final TaskRecord task;
8732        long ident = Binder.clearCallingIdentity();
8733        try {
8734            synchronized (this) {
8735                final ActivityRecord r = ActivityRecord.forToken(token);
8736                if (r == null) {
8737                    return;
8738                }
8739                task = r.task;
8740            }
8741        } finally {
8742            Binder.restoreCallingIdentity(ident);
8743        }
8744        if (task != null) {
8745            startLockTaskMode(task);
8746        }
8747    }
8748
8749    @Override
8750    public void startLockTaskModeOnCurrent() throws RemoteException {
8751        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8752                "startLockTaskModeOnCurrent");
8753        ActivityRecord r = null;
8754        synchronized (this) {
8755            r = mStackSupervisor.topRunningActivityLocked();
8756        }
8757        startLockTaskMode(r.task);
8758    }
8759
8760    @Override
8761    public void stopLockTaskMode() {
8762        // Verify that the user matches the package of the intent for the TaskRecord
8763        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8764        // and stopLockTaskMode.
8765        final int callingUid = Binder.getCallingUid();
8766        if (callingUid != Process.SYSTEM_UID) {
8767            try {
8768                String pkg =
8769                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8770                int uid = mContext.getPackageManager().getPackageUid(pkg,
8771                        Binder.getCallingUserHandle().getIdentifier());
8772                if (uid != callingUid) {
8773                    throw new SecurityException("Invalid uid, expected " + uid);
8774                }
8775            } catch (NameNotFoundException e) {
8776                Log.d(TAG, "stopLockTaskMode " + e);
8777                return;
8778            }
8779        }
8780        long ident = Binder.clearCallingIdentity();
8781        try {
8782            Log.d(TAG, "stopLockTaskMode");
8783            // Stop lock task
8784            synchronized (this) {
8785                mStackSupervisor.setLockTaskModeLocked(null, false);
8786            }
8787        } finally {
8788            Binder.restoreCallingIdentity(ident);
8789        }
8790    }
8791
8792    @Override
8793    public void stopLockTaskModeOnCurrent() throws RemoteException {
8794        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8795                "stopLockTaskModeOnCurrent");
8796        long ident = Binder.clearCallingIdentity();
8797        try {
8798            stopLockTaskMode();
8799        } finally {
8800            Binder.restoreCallingIdentity(ident);
8801        }
8802    }
8803
8804    @Override
8805    public boolean isInLockTaskMode() {
8806        synchronized (this) {
8807            return mStackSupervisor.isInLockTaskMode();
8808        }
8809    }
8810
8811    // =========================================================
8812    // CONTENT PROVIDERS
8813    // =========================================================
8814
8815    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8816        List<ProviderInfo> providers = null;
8817        try {
8818            providers = AppGlobals.getPackageManager().
8819                queryContentProviders(app.processName, app.uid,
8820                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8821        } catch (RemoteException ex) {
8822        }
8823        if (DEBUG_MU)
8824            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8825        int userId = app.userId;
8826        if (providers != null) {
8827            int N = providers.size();
8828            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8829            for (int i=0; i<N; i++) {
8830                ProviderInfo cpi =
8831                    (ProviderInfo)providers.get(i);
8832                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8833                        cpi.name, cpi.flags);
8834                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8835                    // This is a singleton provider, but a user besides the
8836                    // default user is asking to initialize a process it runs
8837                    // in...  well, no, it doesn't actually run in this process,
8838                    // it runs in the process of the default user.  Get rid of it.
8839                    providers.remove(i);
8840                    N--;
8841                    i--;
8842                    continue;
8843                }
8844
8845                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8846                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8847                if (cpr == null) {
8848                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8849                    mProviderMap.putProviderByClass(comp, cpr);
8850                }
8851                if (DEBUG_MU)
8852                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8853                app.pubProviders.put(cpi.name, cpr);
8854                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8855                    // Don't add this if it is a platform component that is marked
8856                    // to run in multiple processes, because this is actually
8857                    // part of the framework so doesn't make sense to track as a
8858                    // separate apk in the process.
8859                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8860                            mProcessStats);
8861                }
8862                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8863            }
8864        }
8865        return providers;
8866    }
8867
8868    /**
8869     * Check if {@link ProcessRecord} has a possible chance at accessing the
8870     * given {@link ProviderInfo}. Final permission checking is always done
8871     * in {@link ContentProvider}.
8872     */
8873    private final String checkContentProviderPermissionLocked(
8874            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8875        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8876        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8877        boolean checkedGrants = false;
8878        if (checkUser) {
8879            // Looking for cross-user grants before enforcing the typical cross-users permissions
8880            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8881            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8882                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8883                    return null;
8884                }
8885                checkedGrants = true;
8886            }
8887            userId = handleIncomingUser(callingPid, callingUid, userId,
8888                    false, ALLOW_NON_FULL,
8889                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8890            if (userId != tmpTargetUserId) {
8891                // When we actually went to determine the final targer user ID, this ended
8892                // up different than our initial check for the authority.  This is because
8893                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8894                // SELF.  So we need to re-check the grants again.
8895                checkedGrants = false;
8896            }
8897        }
8898        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8899                cpi.applicationInfo.uid, cpi.exported)
8900                == PackageManager.PERMISSION_GRANTED) {
8901            return null;
8902        }
8903        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8904                cpi.applicationInfo.uid, cpi.exported)
8905                == PackageManager.PERMISSION_GRANTED) {
8906            return null;
8907        }
8908
8909        PathPermission[] pps = cpi.pathPermissions;
8910        if (pps != null) {
8911            int i = pps.length;
8912            while (i > 0) {
8913                i--;
8914                PathPermission pp = pps[i];
8915                String pprperm = pp.getReadPermission();
8916                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8917                        cpi.applicationInfo.uid, cpi.exported)
8918                        == PackageManager.PERMISSION_GRANTED) {
8919                    return null;
8920                }
8921                String ppwperm = pp.getWritePermission();
8922                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8923                        cpi.applicationInfo.uid, cpi.exported)
8924                        == PackageManager.PERMISSION_GRANTED) {
8925                    return null;
8926                }
8927            }
8928        }
8929        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8930            return null;
8931        }
8932
8933        String msg;
8934        if (!cpi.exported) {
8935            msg = "Permission Denial: opening provider " + cpi.name
8936                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8937                    + ", uid=" + callingUid + ") that is not exported from uid "
8938                    + cpi.applicationInfo.uid;
8939        } else {
8940            msg = "Permission Denial: opening provider " + cpi.name
8941                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8942                    + ", uid=" + callingUid + ") requires "
8943                    + cpi.readPermission + " or " + cpi.writePermission;
8944        }
8945        Slog.w(TAG, msg);
8946        return msg;
8947    }
8948
8949    /**
8950     * Returns if the ContentProvider has granted a uri to callingUid
8951     */
8952    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8953        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8954        if (perms != null) {
8955            for (int i=perms.size()-1; i>=0; i--) {
8956                GrantUri grantUri = perms.keyAt(i);
8957                if (grantUri.sourceUserId == userId || !checkUser) {
8958                    if (matchesProvider(grantUri.uri, cpi)) {
8959                        return true;
8960                    }
8961                }
8962            }
8963        }
8964        return false;
8965    }
8966
8967    /**
8968     * Returns true if the uri authority is one of the authorities specified in the provider.
8969     */
8970    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8971        String uriAuth = uri.getAuthority();
8972        String cpiAuth = cpi.authority;
8973        if (cpiAuth.indexOf(';') == -1) {
8974            return cpiAuth.equals(uriAuth);
8975        }
8976        String[] cpiAuths = cpiAuth.split(";");
8977        int length = cpiAuths.length;
8978        for (int i = 0; i < length; i++) {
8979            if (cpiAuths[i].equals(uriAuth)) return true;
8980        }
8981        return false;
8982    }
8983
8984    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8985            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8986        if (r != null) {
8987            for (int i=0; i<r.conProviders.size(); i++) {
8988                ContentProviderConnection conn = r.conProviders.get(i);
8989                if (conn.provider == cpr) {
8990                    if (DEBUG_PROVIDER) Slog.v(TAG,
8991                            "Adding provider requested by "
8992                            + r.processName + " from process "
8993                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8994                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8995                    if (stable) {
8996                        conn.stableCount++;
8997                        conn.numStableIncs++;
8998                    } else {
8999                        conn.unstableCount++;
9000                        conn.numUnstableIncs++;
9001                    }
9002                    return conn;
9003                }
9004            }
9005            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9006            if (stable) {
9007                conn.stableCount = 1;
9008                conn.numStableIncs = 1;
9009            } else {
9010                conn.unstableCount = 1;
9011                conn.numUnstableIncs = 1;
9012            }
9013            cpr.connections.add(conn);
9014            r.conProviders.add(conn);
9015            return conn;
9016        }
9017        cpr.addExternalProcessHandleLocked(externalProcessToken);
9018        return null;
9019    }
9020
9021    boolean decProviderCountLocked(ContentProviderConnection conn,
9022            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9023        if (conn != null) {
9024            cpr = conn.provider;
9025            if (DEBUG_PROVIDER) Slog.v(TAG,
9026                    "Removing provider requested by "
9027                    + conn.client.processName + " from process "
9028                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9029                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9030            if (stable) {
9031                conn.stableCount--;
9032            } else {
9033                conn.unstableCount--;
9034            }
9035            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9036                cpr.connections.remove(conn);
9037                conn.client.conProviders.remove(conn);
9038                return true;
9039            }
9040            return false;
9041        }
9042        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9043        return false;
9044    }
9045
9046    private void checkTime(long startTime, String where) {
9047        long now = SystemClock.elapsedRealtime();
9048        if ((now-startTime) > 1000) {
9049            // If we are taking more than a second, log about it.
9050            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9051        }
9052    }
9053
9054    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9055            String name, IBinder token, boolean stable, int userId) {
9056        ContentProviderRecord cpr;
9057        ContentProviderConnection conn = null;
9058        ProviderInfo cpi = null;
9059
9060        synchronized(this) {
9061            long startTime = SystemClock.elapsedRealtime();
9062
9063            ProcessRecord r = null;
9064            if (caller != null) {
9065                r = getRecordForAppLocked(caller);
9066                if (r == null) {
9067                    throw new SecurityException(
9068                            "Unable to find app for caller " + caller
9069                          + " (pid=" + Binder.getCallingPid()
9070                          + ") when getting content provider " + name);
9071                }
9072            }
9073
9074            boolean checkCrossUser = true;
9075
9076            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9077
9078            // First check if this content provider has been published...
9079            cpr = mProviderMap.getProviderByName(name, userId);
9080            // If that didn't work, check if it exists for user 0 and then
9081            // verify that it's a singleton provider before using it.
9082            if (cpr == null && userId != UserHandle.USER_OWNER) {
9083                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9084                if (cpr != null) {
9085                    cpi = cpr.info;
9086                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9087                            cpi.name, cpi.flags)
9088                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9089                        userId = UserHandle.USER_OWNER;
9090                        checkCrossUser = false;
9091                    } else {
9092                        cpr = null;
9093                        cpi = null;
9094                    }
9095                }
9096            }
9097
9098            boolean providerRunning = cpr != null;
9099            if (providerRunning) {
9100                cpi = cpr.info;
9101                String msg;
9102                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9103                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9104                        != null) {
9105                    throw new SecurityException(msg);
9106                }
9107                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9108
9109                if (r != null && cpr.canRunHere(r)) {
9110                    // This provider has been published or is in the process
9111                    // of being published...  but it is also allowed to run
9112                    // in the caller's process, so don't make a connection
9113                    // and just let the caller instantiate its own instance.
9114                    ContentProviderHolder holder = cpr.newHolder(null);
9115                    // don't give caller the provider object, it needs
9116                    // to make its own.
9117                    holder.provider = null;
9118                    return holder;
9119                }
9120
9121                final long origId = Binder.clearCallingIdentity();
9122
9123                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9124
9125                // In this case the provider instance already exists, so we can
9126                // return it right away.
9127                conn = incProviderCountLocked(r, cpr, token, stable);
9128                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9129                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9130                        // If this is a perceptible app accessing the provider,
9131                        // make sure to count it as being accessed and thus
9132                        // back up on the LRU list.  This is good because
9133                        // content providers are often expensive to start.
9134                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9135                        updateLruProcessLocked(cpr.proc, false, null);
9136                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9137                    }
9138                }
9139
9140                if (cpr.proc != null) {
9141                    if (false) {
9142                        if (cpr.name.flattenToShortString().equals(
9143                                "com.android.providers.calendar/.CalendarProvider2")) {
9144                            Slog.v(TAG, "****************** KILLING "
9145                                + cpr.name.flattenToShortString());
9146                            Process.killProcess(cpr.proc.pid);
9147                        }
9148                    }
9149                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9150                    boolean success = updateOomAdjLocked(cpr.proc);
9151                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9152                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9153                    // NOTE: there is still a race here where a signal could be
9154                    // pending on the process even though we managed to update its
9155                    // adj level.  Not sure what to do about this, but at least
9156                    // the race is now smaller.
9157                    if (!success) {
9158                        // Uh oh...  it looks like the provider's process
9159                        // has been killed on us.  We need to wait for a new
9160                        // process to be started, and make sure its death
9161                        // doesn't kill our process.
9162                        Slog.i(TAG,
9163                                "Existing provider " + cpr.name.flattenToShortString()
9164                                + " is crashing; detaching " + r);
9165                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9166                        checkTime(startTime, "getContentProviderImpl: before appDied");
9167                        appDiedLocked(cpr.proc);
9168                        checkTime(startTime, "getContentProviderImpl: after appDied");
9169                        if (!lastRef) {
9170                            // This wasn't the last ref our process had on
9171                            // the provider...  we have now been killed, bail.
9172                            return null;
9173                        }
9174                        providerRunning = false;
9175                        conn = null;
9176                    }
9177                }
9178
9179                Binder.restoreCallingIdentity(origId);
9180            }
9181
9182            boolean singleton;
9183            if (!providerRunning) {
9184                try {
9185                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9186                    cpi = AppGlobals.getPackageManager().
9187                        resolveContentProvider(name,
9188                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9189                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9190                } catch (RemoteException ex) {
9191                }
9192                if (cpi == null) {
9193                    return null;
9194                }
9195                // If the provider is a singleton AND
9196                // (it's a call within the same user || the provider is a
9197                // privileged app)
9198                // Then allow connecting to the singleton provider
9199                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9200                        cpi.name, cpi.flags)
9201                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9202                if (singleton) {
9203                    userId = UserHandle.USER_OWNER;
9204                }
9205                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9206                checkTime(startTime, "getContentProviderImpl: got app info for user");
9207
9208                String msg;
9209                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9210                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9211                        != null) {
9212                    throw new SecurityException(msg);
9213                }
9214                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9215
9216                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9217                        && !cpi.processName.equals("system")) {
9218                    // If this content provider does not run in the system
9219                    // process, and the system is not yet ready to run other
9220                    // processes, then fail fast instead of hanging.
9221                    throw new IllegalArgumentException(
9222                            "Attempt to launch content provider before system ready");
9223                }
9224
9225                // Make sure that the user who owns this provider is started.  If not,
9226                // we don't want to allow it to run.
9227                if (mStartedUsers.get(userId) == null) {
9228                    Slog.w(TAG, "Unable to launch app "
9229                            + cpi.applicationInfo.packageName + "/"
9230                            + cpi.applicationInfo.uid + " for provider "
9231                            + name + ": user " + userId + " is stopped");
9232                    return null;
9233                }
9234
9235                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9236                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9237                cpr = mProviderMap.getProviderByClass(comp, userId);
9238                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9239                final boolean firstClass = cpr == null;
9240                if (firstClass) {
9241                    try {
9242                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9243                        ApplicationInfo ai =
9244                            AppGlobals.getPackageManager().
9245                                getApplicationInfo(
9246                                        cpi.applicationInfo.packageName,
9247                                        STOCK_PM_FLAGS, userId);
9248                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9249                        if (ai == null) {
9250                            Slog.w(TAG, "No package info for content provider "
9251                                    + cpi.name);
9252                            return null;
9253                        }
9254                        ai = getAppInfoForUser(ai, userId);
9255                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9256                    } catch (RemoteException ex) {
9257                        // pm is in same process, this will never happen.
9258                    }
9259                }
9260
9261                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9262
9263                if (r != null && cpr.canRunHere(r)) {
9264                    // If this is a multiprocess provider, then just return its
9265                    // info and allow the caller to instantiate it.  Only do
9266                    // this if the provider is the same user as the caller's
9267                    // process, or can run as root (so can be in any process).
9268                    return cpr.newHolder(null);
9269                }
9270
9271                if (DEBUG_PROVIDER) {
9272                    RuntimeException e = new RuntimeException("here");
9273                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9274                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9275                }
9276
9277                // This is single process, and our app is now connecting to it.
9278                // See if we are already in the process of launching this
9279                // provider.
9280                final int N = mLaunchingProviders.size();
9281                int i;
9282                for (i=0; i<N; i++) {
9283                    if (mLaunchingProviders.get(i) == cpr) {
9284                        break;
9285                    }
9286                }
9287
9288                // If the provider is not already being launched, then get it
9289                // started.
9290                if (i >= N) {
9291                    final long origId = Binder.clearCallingIdentity();
9292
9293                    try {
9294                        // Content provider is now in use, its package can't be stopped.
9295                        try {
9296                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9297                            AppGlobals.getPackageManager().setPackageStoppedState(
9298                                    cpr.appInfo.packageName, false, userId);
9299                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9300                        } catch (RemoteException e) {
9301                        } catch (IllegalArgumentException e) {
9302                            Slog.w(TAG, "Failed trying to unstop package "
9303                                    + cpr.appInfo.packageName + ": " + e);
9304                        }
9305
9306                        // Use existing process if already started
9307                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9308                        ProcessRecord proc = getProcessRecordLocked(
9309                                cpi.processName, cpr.appInfo.uid, false);
9310                        if (proc != null && proc.thread != null) {
9311                            if (DEBUG_PROVIDER) {
9312                                Slog.d(TAG, "Installing in existing process " + proc);
9313                            }
9314                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9315                            proc.pubProviders.put(cpi.name, cpr);
9316                            try {
9317                                proc.thread.scheduleInstallProvider(cpi);
9318                            } catch (RemoteException e) {
9319                            }
9320                        } else {
9321                            checkTime(startTime, "getContentProviderImpl: before start process");
9322                            proc = startProcessLocked(cpi.processName,
9323                                    cpr.appInfo, false, 0, "content provider",
9324                                    new ComponentName(cpi.applicationInfo.packageName,
9325                                            cpi.name), false, false, false);
9326                            checkTime(startTime, "getContentProviderImpl: after start process");
9327                            if (proc == null) {
9328                                Slog.w(TAG, "Unable to launch app "
9329                                        + cpi.applicationInfo.packageName + "/"
9330                                        + cpi.applicationInfo.uid + " for provider "
9331                                        + name + ": process is bad");
9332                                return null;
9333                            }
9334                        }
9335                        cpr.launchingApp = proc;
9336                        mLaunchingProviders.add(cpr);
9337                    } finally {
9338                        Binder.restoreCallingIdentity(origId);
9339                    }
9340                }
9341
9342                checkTime(startTime, "getContentProviderImpl: updating data structures");
9343
9344                // Make sure the provider is published (the same provider class
9345                // may be published under multiple names).
9346                if (firstClass) {
9347                    mProviderMap.putProviderByClass(comp, cpr);
9348                }
9349
9350                mProviderMap.putProviderByName(name, cpr);
9351                conn = incProviderCountLocked(r, cpr, token, stable);
9352                if (conn != null) {
9353                    conn.waiting = true;
9354                }
9355            }
9356            checkTime(startTime, "getContentProviderImpl: done!");
9357        }
9358
9359        // Wait for the provider to be published...
9360        synchronized (cpr) {
9361            while (cpr.provider == null) {
9362                if (cpr.launchingApp == null) {
9363                    Slog.w(TAG, "Unable to launch app "
9364                            + cpi.applicationInfo.packageName + "/"
9365                            + cpi.applicationInfo.uid + " for provider "
9366                            + name + ": launching app became null");
9367                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9368                            UserHandle.getUserId(cpi.applicationInfo.uid),
9369                            cpi.applicationInfo.packageName,
9370                            cpi.applicationInfo.uid, name);
9371                    return null;
9372                }
9373                try {
9374                    if (DEBUG_MU) {
9375                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9376                                + cpr.launchingApp);
9377                    }
9378                    if (conn != null) {
9379                        conn.waiting = true;
9380                    }
9381                    cpr.wait();
9382                } catch (InterruptedException ex) {
9383                } finally {
9384                    if (conn != null) {
9385                        conn.waiting = false;
9386                    }
9387                }
9388            }
9389        }
9390        return cpr != null ? cpr.newHolder(conn) : null;
9391    }
9392
9393    @Override
9394    public final ContentProviderHolder getContentProvider(
9395            IApplicationThread caller, String name, int userId, boolean stable) {
9396        enforceNotIsolatedCaller("getContentProvider");
9397        if (caller == null) {
9398            String msg = "null IApplicationThread when getting content provider "
9399                    + name;
9400            Slog.w(TAG, msg);
9401            throw new SecurityException(msg);
9402        }
9403        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9404        // with cross-user grant.
9405        return getContentProviderImpl(caller, name, null, stable, userId);
9406    }
9407
9408    public ContentProviderHolder getContentProviderExternal(
9409            String name, int userId, IBinder token) {
9410        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9411            "Do not have permission in call getContentProviderExternal()");
9412        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9413                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9414        return getContentProviderExternalUnchecked(name, token, userId);
9415    }
9416
9417    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9418            IBinder token, int userId) {
9419        return getContentProviderImpl(null, name, token, true, userId);
9420    }
9421
9422    /**
9423     * Drop a content provider from a ProcessRecord's bookkeeping
9424     */
9425    public void removeContentProvider(IBinder connection, boolean stable) {
9426        enforceNotIsolatedCaller("removeContentProvider");
9427        long ident = Binder.clearCallingIdentity();
9428        try {
9429            synchronized (this) {
9430                ContentProviderConnection conn;
9431                try {
9432                    conn = (ContentProviderConnection)connection;
9433                } catch (ClassCastException e) {
9434                    String msg ="removeContentProvider: " + connection
9435                            + " not a ContentProviderConnection";
9436                    Slog.w(TAG, msg);
9437                    throw new IllegalArgumentException(msg);
9438                }
9439                if (conn == null) {
9440                    throw new NullPointerException("connection is null");
9441                }
9442                if (decProviderCountLocked(conn, null, null, stable)) {
9443                    updateOomAdjLocked();
9444                }
9445            }
9446        } finally {
9447            Binder.restoreCallingIdentity(ident);
9448        }
9449    }
9450
9451    public void removeContentProviderExternal(String name, IBinder token) {
9452        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9453            "Do not have permission in call removeContentProviderExternal()");
9454        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
9455    }
9456
9457    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9458        synchronized (this) {
9459            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9460            if(cpr == null) {
9461                //remove from mProvidersByClass
9462                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9463                return;
9464            }
9465
9466            //update content provider record entry info
9467            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9468            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9469            if (localCpr.hasExternalProcessHandles()) {
9470                if (localCpr.removeExternalProcessHandleLocked(token)) {
9471                    updateOomAdjLocked();
9472                } else {
9473                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9474                            + " with no external reference for token: "
9475                            + token + ".");
9476                }
9477            } else {
9478                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9479                        + " with no external references.");
9480            }
9481        }
9482    }
9483
9484    public final void publishContentProviders(IApplicationThread caller,
9485            List<ContentProviderHolder> providers) {
9486        if (providers == null) {
9487            return;
9488        }
9489
9490        enforceNotIsolatedCaller("publishContentProviders");
9491        synchronized (this) {
9492            final ProcessRecord r = getRecordForAppLocked(caller);
9493            if (DEBUG_MU)
9494                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9495            if (r == null) {
9496                throw new SecurityException(
9497                        "Unable to find app for caller " + caller
9498                      + " (pid=" + Binder.getCallingPid()
9499                      + ") when publishing content providers");
9500            }
9501
9502            final long origId = Binder.clearCallingIdentity();
9503
9504            final int N = providers.size();
9505            for (int i=0; i<N; i++) {
9506                ContentProviderHolder src = providers.get(i);
9507                if (src == null || src.info == null || src.provider == null) {
9508                    continue;
9509                }
9510                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9511                if (DEBUG_MU)
9512                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9513                if (dst != null) {
9514                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9515                    mProviderMap.putProviderByClass(comp, dst);
9516                    String names[] = dst.info.authority.split(";");
9517                    for (int j = 0; j < names.length; j++) {
9518                        mProviderMap.putProviderByName(names[j], dst);
9519                    }
9520
9521                    int NL = mLaunchingProviders.size();
9522                    int j;
9523                    for (j=0; j<NL; j++) {
9524                        if (mLaunchingProviders.get(j) == dst) {
9525                            mLaunchingProviders.remove(j);
9526                            j--;
9527                            NL--;
9528                        }
9529                    }
9530                    synchronized (dst) {
9531                        dst.provider = src.provider;
9532                        dst.proc = r;
9533                        dst.notifyAll();
9534                    }
9535                    updateOomAdjLocked(r);
9536                }
9537            }
9538
9539            Binder.restoreCallingIdentity(origId);
9540        }
9541    }
9542
9543    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9544        ContentProviderConnection conn;
9545        try {
9546            conn = (ContentProviderConnection)connection;
9547        } catch (ClassCastException e) {
9548            String msg ="refContentProvider: " + connection
9549                    + " not a ContentProviderConnection";
9550            Slog.w(TAG, msg);
9551            throw new IllegalArgumentException(msg);
9552        }
9553        if (conn == null) {
9554            throw new NullPointerException("connection is null");
9555        }
9556
9557        synchronized (this) {
9558            if (stable > 0) {
9559                conn.numStableIncs += stable;
9560            }
9561            stable = conn.stableCount + stable;
9562            if (stable < 0) {
9563                throw new IllegalStateException("stableCount < 0: " + stable);
9564            }
9565
9566            if (unstable > 0) {
9567                conn.numUnstableIncs += unstable;
9568            }
9569            unstable = conn.unstableCount + unstable;
9570            if (unstable < 0) {
9571                throw new IllegalStateException("unstableCount < 0: " + unstable);
9572            }
9573
9574            if ((stable+unstable) <= 0) {
9575                throw new IllegalStateException("ref counts can't go to zero here: stable="
9576                        + stable + " unstable=" + unstable);
9577            }
9578            conn.stableCount = stable;
9579            conn.unstableCount = unstable;
9580            return !conn.dead;
9581        }
9582    }
9583
9584    public void unstableProviderDied(IBinder connection) {
9585        ContentProviderConnection conn;
9586        try {
9587            conn = (ContentProviderConnection)connection;
9588        } catch (ClassCastException e) {
9589            String msg ="refContentProvider: " + connection
9590                    + " not a ContentProviderConnection";
9591            Slog.w(TAG, msg);
9592            throw new IllegalArgumentException(msg);
9593        }
9594        if (conn == null) {
9595            throw new NullPointerException("connection is null");
9596        }
9597
9598        // Safely retrieve the content provider associated with the connection.
9599        IContentProvider provider;
9600        synchronized (this) {
9601            provider = conn.provider.provider;
9602        }
9603
9604        if (provider == null) {
9605            // Um, yeah, we're way ahead of you.
9606            return;
9607        }
9608
9609        // Make sure the caller is being honest with us.
9610        if (provider.asBinder().pingBinder()) {
9611            // Er, no, still looks good to us.
9612            synchronized (this) {
9613                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9614                        + " says " + conn + " died, but we don't agree");
9615                return;
9616            }
9617        }
9618
9619        // Well look at that!  It's dead!
9620        synchronized (this) {
9621            if (conn.provider.provider != provider) {
9622                // But something changed...  good enough.
9623                return;
9624            }
9625
9626            ProcessRecord proc = conn.provider.proc;
9627            if (proc == null || proc.thread == null) {
9628                // Seems like the process is already cleaned up.
9629                return;
9630            }
9631
9632            // As far as we're concerned, this is just like receiving a
9633            // death notification...  just a bit prematurely.
9634            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9635                    + ") early provider death");
9636            final long ident = Binder.clearCallingIdentity();
9637            try {
9638                appDiedLocked(proc);
9639            } finally {
9640                Binder.restoreCallingIdentity(ident);
9641            }
9642        }
9643    }
9644
9645    @Override
9646    public void appNotRespondingViaProvider(IBinder connection) {
9647        enforceCallingPermission(
9648                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9649
9650        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9651        if (conn == null) {
9652            Slog.w(TAG, "ContentProviderConnection is null");
9653            return;
9654        }
9655
9656        final ProcessRecord host = conn.provider.proc;
9657        if (host == null) {
9658            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9659            return;
9660        }
9661
9662        final long token = Binder.clearCallingIdentity();
9663        try {
9664            appNotResponding(host, null, null, false, "ContentProvider not responding");
9665        } finally {
9666            Binder.restoreCallingIdentity(token);
9667        }
9668    }
9669
9670    public final void installSystemProviders() {
9671        List<ProviderInfo> providers;
9672        synchronized (this) {
9673            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9674            providers = generateApplicationProvidersLocked(app);
9675            if (providers != null) {
9676                for (int i=providers.size()-1; i>=0; i--) {
9677                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9678                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9679                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9680                                + ": not system .apk");
9681                        providers.remove(i);
9682                    }
9683                }
9684            }
9685        }
9686        if (providers != null) {
9687            mSystemThread.installSystemProviders(providers);
9688        }
9689
9690        mCoreSettingsObserver = new CoreSettingsObserver(this);
9691
9692        //mUsageStatsService.monitorPackages();
9693    }
9694
9695    /**
9696     * Allows apps to retrieve the MIME type of a URI.
9697     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9698     * users, then it does not need permission to access the ContentProvider.
9699     * Either, it needs cross-user uri grants.
9700     *
9701     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9702     *
9703     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9704     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9705     */
9706    public String getProviderMimeType(Uri uri, int userId) {
9707        enforceNotIsolatedCaller("getProviderMimeType");
9708        final String name = uri.getAuthority();
9709        int callingUid = Binder.getCallingUid();
9710        int callingPid = Binder.getCallingPid();
9711        long ident = 0;
9712        boolean clearedIdentity = false;
9713        userId = unsafeConvertIncomingUser(userId);
9714        if (UserHandle.getUserId(callingUid) != userId) {
9715            if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9716                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9717                    || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9718                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9719                clearedIdentity = true;
9720                ident = Binder.clearCallingIdentity();
9721            }
9722        }
9723        ContentProviderHolder holder = null;
9724        try {
9725            holder = getContentProviderExternalUnchecked(name, null, userId);
9726            if (holder != null) {
9727                return holder.provider.getType(uri);
9728            }
9729        } catch (RemoteException e) {
9730            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9731            return null;
9732        } finally {
9733            // We need to clear the identity to call removeContentProviderExternalUnchecked
9734            if (!clearedIdentity) {
9735                ident = Binder.clearCallingIdentity();
9736            }
9737            try {
9738                if (holder != null) {
9739                    removeContentProviderExternalUnchecked(name, null, userId);
9740                }
9741            } finally {
9742                Binder.restoreCallingIdentity(ident);
9743            }
9744        }
9745
9746        return null;
9747    }
9748
9749    // =========================================================
9750    // GLOBAL MANAGEMENT
9751    // =========================================================
9752
9753    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9754            boolean isolated, int isolatedUid) {
9755        String proc = customProcess != null ? customProcess : info.processName;
9756        BatteryStatsImpl.Uid.Proc ps = null;
9757        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9758        int uid = info.uid;
9759        if (isolated) {
9760            if (isolatedUid == 0) {
9761                int userId = UserHandle.getUserId(uid);
9762                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9763                while (true) {
9764                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9765                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9766                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9767                    }
9768                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9769                    mNextIsolatedProcessUid++;
9770                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9771                        // No process for this uid, use it.
9772                        break;
9773                    }
9774                    stepsLeft--;
9775                    if (stepsLeft <= 0) {
9776                        return null;
9777                    }
9778                }
9779            } else {
9780                // Special case for startIsolatedProcess (internal only), where
9781                // the uid of the isolated process is specified by the caller.
9782                uid = isolatedUid;
9783            }
9784        }
9785        return new ProcessRecord(stats, info, proc, uid);
9786    }
9787
9788    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9789            String abiOverride) {
9790        ProcessRecord app;
9791        if (!isolated) {
9792            app = getProcessRecordLocked(info.processName, info.uid, true);
9793        } else {
9794            app = null;
9795        }
9796
9797        if (app == null) {
9798            app = newProcessRecordLocked(info, null, isolated, 0);
9799            mProcessNames.put(info.processName, app.uid, app);
9800            if (isolated) {
9801                mIsolatedProcesses.put(app.uid, app);
9802            }
9803            updateLruProcessLocked(app, false, null);
9804            updateOomAdjLocked();
9805        }
9806
9807        // This package really, really can not be stopped.
9808        try {
9809            AppGlobals.getPackageManager().setPackageStoppedState(
9810                    info.packageName, false, UserHandle.getUserId(app.uid));
9811        } catch (RemoteException e) {
9812        } catch (IllegalArgumentException e) {
9813            Slog.w(TAG, "Failed trying to unstop package "
9814                    + info.packageName + ": " + e);
9815        }
9816
9817        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9818                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9819            app.persistent = true;
9820            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9821        }
9822        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9823            mPersistentStartingProcesses.add(app);
9824            startProcessLocked(app, "added application", app.processName, abiOverride,
9825                    null /* entryPoint */, null /* entryPointArgs */);
9826        }
9827
9828        return app;
9829    }
9830
9831    public void unhandledBack() {
9832        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9833                "unhandledBack()");
9834
9835        synchronized(this) {
9836            final long origId = Binder.clearCallingIdentity();
9837            try {
9838                getFocusedStack().unhandledBackLocked();
9839            } finally {
9840                Binder.restoreCallingIdentity(origId);
9841            }
9842        }
9843    }
9844
9845    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9846        enforceNotIsolatedCaller("openContentUri");
9847        final int userId = UserHandle.getCallingUserId();
9848        String name = uri.getAuthority();
9849        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9850        ParcelFileDescriptor pfd = null;
9851        if (cph != null) {
9852            // We record the binder invoker's uid in thread-local storage before
9853            // going to the content provider to open the file.  Later, in the code
9854            // that handles all permissions checks, we look for this uid and use
9855            // that rather than the Activity Manager's own uid.  The effect is that
9856            // we do the check against the caller's permissions even though it looks
9857            // to the content provider like the Activity Manager itself is making
9858            // the request.
9859            sCallerIdentity.set(new Identity(
9860                    Binder.getCallingPid(), Binder.getCallingUid()));
9861            try {
9862                pfd = cph.provider.openFile(null, uri, "r", null);
9863            } catch (FileNotFoundException e) {
9864                // do nothing; pfd will be returned null
9865            } finally {
9866                // Ensure that whatever happens, we clean up the identity state
9867                sCallerIdentity.remove();
9868            }
9869
9870            // We've got the fd now, so we're done with the provider.
9871            removeContentProviderExternalUnchecked(name, null, userId);
9872        } else {
9873            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9874        }
9875        return pfd;
9876    }
9877
9878    // Actually is sleeping or shutting down or whatever else in the future
9879    // is an inactive state.
9880    public boolean isSleepingOrShuttingDown() {
9881        return mSleeping || mShuttingDown;
9882    }
9883
9884    public boolean isSleeping() {
9885        return mSleeping;
9886    }
9887
9888    void goingToSleep() {
9889        synchronized(this) {
9890            mWentToSleep = true;
9891            updateEventDispatchingLocked();
9892            goToSleepIfNeededLocked();
9893        }
9894    }
9895
9896    void finishRunningVoiceLocked() {
9897        if (mRunningVoice) {
9898            mRunningVoice = false;
9899            goToSleepIfNeededLocked();
9900        }
9901    }
9902
9903    void goToSleepIfNeededLocked() {
9904        if (mWentToSleep && !mRunningVoice) {
9905            if (!mSleeping) {
9906                mSleeping = true;
9907                mStackSupervisor.goingToSleepLocked();
9908
9909                // Initialize the wake times of all processes.
9910                checkExcessivePowerUsageLocked(false);
9911                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9912                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9913                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9914            }
9915        }
9916    }
9917
9918    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9919        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9920            // Never persist the home stack.
9921            return;
9922        }
9923        mTaskPersister.wakeup(task, flush);
9924    }
9925
9926    @Override
9927    public boolean shutdown(int timeout) {
9928        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9929                != PackageManager.PERMISSION_GRANTED) {
9930            throw new SecurityException("Requires permission "
9931                    + android.Manifest.permission.SHUTDOWN);
9932        }
9933
9934        boolean timedout = false;
9935
9936        synchronized(this) {
9937            mShuttingDown = true;
9938            updateEventDispatchingLocked();
9939            timedout = mStackSupervisor.shutdownLocked(timeout);
9940        }
9941
9942        mAppOpsService.shutdown();
9943        if (mUsageStatsService != null) {
9944            mUsageStatsService.prepareShutdown();
9945        }
9946        mBatteryStatsService.shutdown();
9947        synchronized (this) {
9948            mProcessStats.shutdownLocked();
9949        }
9950        notifyTaskPersisterLocked(null, true);
9951
9952        return timedout;
9953    }
9954
9955    public final void activitySlept(IBinder token) {
9956        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9957
9958        final long origId = Binder.clearCallingIdentity();
9959
9960        synchronized (this) {
9961            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9962            if (r != null) {
9963                mStackSupervisor.activitySleptLocked(r);
9964            }
9965        }
9966
9967        Binder.restoreCallingIdentity(origId);
9968    }
9969
9970    void logLockScreen(String msg) {
9971        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9972                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9973                mWentToSleep + " mSleeping=" + mSleeping);
9974    }
9975
9976    private void comeOutOfSleepIfNeededLocked() {
9977        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9978            if (mSleeping) {
9979                mSleeping = false;
9980                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9981            }
9982        }
9983    }
9984
9985    void wakingUp() {
9986        synchronized(this) {
9987            mWentToSleep = false;
9988            updateEventDispatchingLocked();
9989            comeOutOfSleepIfNeededLocked();
9990        }
9991    }
9992
9993    void startRunningVoiceLocked() {
9994        if (!mRunningVoice) {
9995            mRunningVoice = true;
9996            comeOutOfSleepIfNeededLocked();
9997        }
9998    }
9999
10000    private void updateEventDispatchingLocked() {
10001        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10002    }
10003
10004    public void setLockScreenShown(boolean shown) {
10005        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10006                != PackageManager.PERMISSION_GRANTED) {
10007            throw new SecurityException("Requires permission "
10008                    + android.Manifest.permission.DEVICE_POWER);
10009        }
10010
10011        synchronized(this) {
10012            long ident = Binder.clearCallingIdentity();
10013            try {
10014                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10015                mLockScreenShown = shown;
10016                comeOutOfSleepIfNeededLocked();
10017            } finally {
10018                Binder.restoreCallingIdentity(ident);
10019            }
10020        }
10021    }
10022
10023    @Override
10024    public void stopAppSwitches() {
10025        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10026                != PackageManager.PERMISSION_GRANTED) {
10027            throw new SecurityException("Requires permission "
10028                    + android.Manifest.permission.STOP_APP_SWITCHES);
10029        }
10030
10031        synchronized(this) {
10032            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10033                    + APP_SWITCH_DELAY_TIME;
10034            mDidAppSwitch = false;
10035            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10036            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10037            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10038        }
10039    }
10040
10041    public void resumeAppSwitches() {
10042        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10043                != PackageManager.PERMISSION_GRANTED) {
10044            throw new SecurityException("Requires permission "
10045                    + android.Manifest.permission.STOP_APP_SWITCHES);
10046        }
10047
10048        synchronized(this) {
10049            // Note that we don't execute any pending app switches... we will
10050            // let those wait until either the timeout, or the next start
10051            // activity request.
10052            mAppSwitchesAllowedTime = 0;
10053        }
10054    }
10055
10056    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
10057            String name) {
10058        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10059            return true;
10060        }
10061
10062        final int perm = checkComponentPermission(
10063                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10064                callingUid, -1, true);
10065        if (perm == PackageManager.PERMISSION_GRANTED) {
10066            return true;
10067        }
10068
10069        Slog.w(TAG, name + " request from " + callingUid + " stopped");
10070        return false;
10071    }
10072
10073    public void setDebugApp(String packageName, boolean waitForDebugger,
10074            boolean persistent) {
10075        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10076                "setDebugApp()");
10077
10078        long ident = Binder.clearCallingIdentity();
10079        try {
10080            // Note that this is not really thread safe if there are multiple
10081            // callers into it at the same time, but that's not a situation we
10082            // care about.
10083            if (persistent) {
10084                final ContentResolver resolver = mContext.getContentResolver();
10085                Settings.Global.putString(
10086                    resolver, Settings.Global.DEBUG_APP,
10087                    packageName);
10088                Settings.Global.putInt(
10089                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10090                    waitForDebugger ? 1 : 0);
10091            }
10092
10093            synchronized (this) {
10094                if (!persistent) {
10095                    mOrigDebugApp = mDebugApp;
10096                    mOrigWaitForDebugger = mWaitForDebugger;
10097                }
10098                mDebugApp = packageName;
10099                mWaitForDebugger = waitForDebugger;
10100                mDebugTransient = !persistent;
10101                if (packageName != null) {
10102                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10103                            false, UserHandle.USER_ALL, "set debug app");
10104                }
10105            }
10106        } finally {
10107            Binder.restoreCallingIdentity(ident);
10108        }
10109    }
10110
10111    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10112        synchronized (this) {
10113            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10114            if (!isDebuggable) {
10115                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10116                    throw new SecurityException("Process not debuggable: " + app.packageName);
10117                }
10118            }
10119
10120            mOpenGlTraceApp = processName;
10121        }
10122    }
10123
10124    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10125        synchronized (this) {
10126            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10127            if (!isDebuggable) {
10128                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10129                    throw new SecurityException("Process not debuggable: " + app.packageName);
10130                }
10131            }
10132            mProfileApp = processName;
10133            mProfileFile = profilerInfo.profileFile;
10134            if (mProfileFd != null) {
10135                try {
10136                    mProfileFd.close();
10137                } catch (IOException e) {
10138                }
10139                mProfileFd = null;
10140            }
10141            mProfileFd = profilerInfo.profileFd;
10142            mSamplingInterval = profilerInfo.samplingInterval;
10143            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10144            mProfileType = 0;
10145        }
10146    }
10147
10148    @Override
10149    public void setAlwaysFinish(boolean enabled) {
10150        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10151                "setAlwaysFinish()");
10152
10153        Settings.Global.putInt(
10154                mContext.getContentResolver(),
10155                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10156
10157        synchronized (this) {
10158            mAlwaysFinishActivities = enabled;
10159        }
10160    }
10161
10162    @Override
10163    public void setActivityController(IActivityController controller) {
10164        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10165                "setActivityController()");
10166        synchronized (this) {
10167            mController = controller;
10168            Watchdog.getInstance().setActivityController(controller);
10169        }
10170    }
10171
10172    @Override
10173    public void setUserIsMonkey(boolean userIsMonkey) {
10174        synchronized (this) {
10175            synchronized (mPidsSelfLocked) {
10176                final int callingPid = Binder.getCallingPid();
10177                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10178                if (precessRecord == null) {
10179                    throw new SecurityException("Unknown process: " + callingPid);
10180                }
10181                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10182                    throw new SecurityException("Only an instrumentation process "
10183                            + "with a UiAutomation can call setUserIsMonkey");
10184                }
10185            }
10186            mUserIsMonkey = userIsMonkey;
10187        }
10188    }
10189
10190    @Override
10191    public boolean isUserAMonkey() {
10192        synchronized (this) {
10193            // If there is a controller also implies the user is a monkey.
10194            return (mUserIsMonkey || mController != null);
10195        }
10196    }
10197
10198    public void requestBugReport() {
10199        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10200        SystemProperties.set("ctl.start", "bugreport");
10201    }
10202
10203    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10204        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10205    }
10206
10207    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10208        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10209            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10210        }
10211        return KEY_DISPATCHING_TIMEOUT;
10212    }
10213
10214    @Override
10215    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10216        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10217                != PackageManager.PERMISSION_GRANTED) {
10218            throw new SecurityException("Requires permission "
10219                    + android.Manifest.permission.FILTER_EVENTS);
10220        }
10221        ProcessRecord proc;
10222        long timeout;
10223        synchronized (this) {
10224            synchronized (mPidsSelfLocked) {
10225                proc = mPidsSelfLocked.get(pid);
10226            }
10227            timeout = getInputDispatchingTimeoutLocked(proc);
10228        }
10229
10230        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10231            return -1;
10232        }
10233
10234        return timeout;
10235    }
10236
10237    /**
10238     * Handle input dispatching timeouts.
10239     * Returns whether input dispatching should be aborted or not.
10240     */
10241    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10242            final ActivityRecord activity, final ActivityRecord parent,
10243            final boolean aboveSystem, String reason) {
10244        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10245                != PackageManager.PERMISSION_GRANTED) {
10246            throw new SecurityException("Requires permission "
10247                    + android.Manifest.permission.FILTER_EVENTS);
10248        }
10249
10250        final String annotation;
10251        if (reason == null) {
10252            annotation = "Input dispatching timed out";
10253        } else {
10254            annotation = "Input dispatching timed out (" + reason + ")";
10255        }
10256
10257        if (proc != null) {
10258            synchronized (this) {
10259                if (proc.debugging) {
10260                    return false;
10261                }
10262
10263                if (mDidDexOpt) {
10264                    // Give more time since we were dexopting.
10265                    mDidDexOpt = false;
10266                    return false;
10267                }
10268
10269                if (proc.instrumentationClass != null) {
10270                    Bundle info = new Bundle();
10271                    info.putString("shortMsg", "keyDispatchingTimedOut");
10272                    info.putString("longMsg", annotation);
10273                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10274                    return true;
10275                }
10276            }
10277            mHandler.post(new Runnable() {
10278                @Override
10279                public void run() {
10280                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10281                }
10282            });
10283        }
10284
10285        return true;
10286    }
10287
10288    public Bundle getAssistContextExtras(int requestType) {
10289        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10290                "getAssistContextExtras()");
10291        PendingAssistExtras pae;
10292        Bundle extras = new Bundle();
10293        synchronized (this) {
10294            ActivityRecord activity = getFocusedStack().mResumedActivity;
10295            if (activity == null) {
10296                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10297                return null;
10298            }
10299            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10300            if (activity.app == null || activity.app.thread == null) {
10301                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10302                return extras;
10303            }
10304            if (activity.app.pid == Binder.getCallingPid()) {
10305                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10306                return extras;
10307            }
10308            pae = new PendingAssistExtras(activity);
10309            try {
10310                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10311                        requestType);
10312                mPendingAssistExtras.add(pae);
10313                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10314            } catch (RemoteException e) {
10315                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10316                return extras;
10317            }
10318        }
10319        synchronized (pae) {
10320            while (!pae.haveResult) {
10321                try {
10322                    pae.wait();
10323                } catch (InterruptedException e) {
10324                }
10325            }
10326            if (pae.result != null) {
10327                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10328            }
10329        }
10330        synchronized (this) {
10331            mPendingAssistExtras.remove(pae);
10332            mHandler.removeCallbacks(pae);
10333        }
10334        return extras;
10335    }
10336
10337    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10338        PendingAssistExtras pae = (PendingAssistExtras)token;
10339        synchronized (pae) {
10340            pae.result = extras;
10341            pae.haveResult = true;
10342            pae.notifyAll();
10343        }
10344    }
10345
10346    public void registerProcessObserver(IProcessObserver observer) {
10347        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10348                "registerProcessObserver()");
10349        synchronized (this) {
10350            mProcessObservers.register(observer);
10351        }
10352    }
10353
10354    @Override
10355    public void unregisterProcessObserver(IProcessObserver observer) {
10356        synchronized (this) {
10357            mProcessObservers.unregister(observer);
10358        }
10359    }
10360
10361    @Override
10362    public boolean convertFromTranslucent(IBinder token) {
10363        final long origId = Binder.clearCallingIdentity();
10364        try {
10365            synchronized (this) {
10366                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10367                if (r == null) {
10368                    return false;
10369                }
10370                final boolean translucentChanged = r.changeWindowTranslucency(true);
10371                if (translucentChanged) {
10372                    r.task.stack.releaseBackgroundResources();
10373                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10374                }
10375                mWindowManager.setAppFullscreen(token, true);
10376                return translucentChanged;
10377            }
10378        } finally {
10379            Binder.restoreCallingIdentity(origId);
10380        }
10381    }
10382
10383    @Override
10384    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10385        final long origId = Binder.clearCallingIdentity();
10386        try {
10387            synchronized (this) {
10388                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10389                if (r == null) {
10390                    return false;
10391                }
10392                int index = r.task.mActivities.lastIndexOf(r);
10393                if (index > 0) {
10394                    ActivityRecord under = r.task.mActivities.get(index - 1);
10395                    under.returningOptions = options;
10396                }
10397                final boolean translucentChanged = r.changeWindowTranslucency(false);
10398                if (translucentChanged) {
10399                    r.task.stack.convertToTranslucent(r);
10400                }
10401                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10402                mWindowManager.setAppFullscreen(token, false);
10403                return translucentChanged;
10404            }
10405        } finally {
10406            Binder.restoreCallingIdentity(origId);
10407        }
10408    }
10409
10410    @Override
10411    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10412        final long origId = Binder.clearCallingIdentity();
10413        try {
10414            synchronized (this) {
10415                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10416                if (r != null) {
10417                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10418                }
10419            }
10420            return false;
10421        } finally {
10422            Binder.restoreCallingIdentity(origId);
10423        }
10424    }
10425
10426    @Override
10427    public boolean isBackgroundVisibleBehind(IBinder token) {
10428        final long origId = Binder.clearCallingIdentity();
10429        try {
10430            synchronized (this) {
10431                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10432                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10433                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10434                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10435                return visible;
10436            }
10437        } finally {
10438            Binder.restoreCallingIdentity(origId);
10439        }
10440    }
10441
10442    @Override
10443    public ActivityOptions getActivityOptions(IBinder token) {
10444        final long origId = Binder.clearCallingIdentity();
10445        try {
10446            synchronized (this) {
10447                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10448                if (r != null) {
10449                    final ActivityOptions activityOptions = r.pendingOptions;
10450                    r.pendingOptions = null;
10451                    return activityOptions;
10452                }
10453                return null;
10454            }
10455        } finally {
10456            Binder.restoreCallingIdentity(origId);
10457        }
10458    }
10459
10460    @Override
10461    public void setImmersive(IBinder token, boolean immersive) {
10462        synchronized(this) {
10463            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10464            if (r == null) {
10465                throw new IllegalArgumentException();
10466            }
10467            r.immersive = immersive;
10468
10469            // update associated state if we're frontmost
10470            if (r == mFocusedActivity) {
10471                if (DEBUG_IMMERSIVE) {
10472                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10473                }
10474                applyUpdateLockStateLocked(r);
10475            }
10476        }
10477    }
10478
10479    @Override
10480    public boolean isImmersive(IBinder token) {
10481        synchronized (this) {
10482            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10483            if (r == null) {
10484                throw new IllegalArgumentException();
10485            }
10486            return r.immersive;
10487        }
10488    }
10489
10490    public boolean isTopActivityImmersive() {
10491        enforceNotIsolatedCaller("startActivity");
10492        synchronized (this) {
10493            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10494            return (r != null) ? r.immersive : false;
10495        }
10496    }
10497
10498    @Override
10499    public boolean isTopOfTask(IBinder token) {
10500        synchronized (this) {
10501            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10502            if (r == null) {
10503                throw new IllegalArgumentException();
10504            }
10505            return r.task.getTopActivity() == r;
10506        }
10507    }
10508
10509    public final void enterSafeMode() {
10510        synchronized(this) {
10511            // It only makes sense to do this before the system is ready
10512            // and started launching other packages.
10513            if (!mSystemReady) {
10514                try {
10515                    AppGlobals.getPackageManager().enterSafeMode();
10516                } catch (RemoteException e) {
10517                }
10518            }
10519
10520            mSafeMode = true;
10521        }
10522    }
10523
10524    public final void showSafeModeOverlay() {
10525        View v = LayoutInflater.from(mContext).inflate(
10526                com.android.internal.R.layout.safe_mode, null);
10527        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10528        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10529        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10530        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10531        lp.gravity = Gravity.BOTTOM | Gravity.START;
10532        lp.format = v.getBackground().getOpacity();
10533        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10534                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10535        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10536        ((WindowManager)mContext.getSystemService(
10537                Context.WINDOW_SERVICE)).addView(v, lp);
10538    }
10539
10540    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10541        if (!(sender instanceof PendingIntentRecord)) {
10542            return;
10543        }
10544        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10545        synchronized (stats) {
10546            if (mBatteryStatsService.isOnBattery()) {
10547                mBatteryStatsService.enforceCallingPermission();
10548                PendingIntentRecord rec = (PendingIntentRecord)sender;
10549                int MY_UID = Binder.getCallingUid();
10550                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10551                BatteryStatsImpl.Uid.Pkg pkg =
10552                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10553                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10554                pkg.incWakeupsLocked();
10555            }
10556        }
10557    }
10558
10559    public boolean killPids(int[] pids, String pReason, boolean secure) {
10560        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10561            throw new SecurityException("killPids only available to the system");
10562        }
10563        String reason = (pReason == null) ? "Unknown" : pReason;
10564        // XXX Note: don't acquire main activity lock here, because the window
10565        // manager calls in with its locks held.
10566
10567        boolean killed = false;
10568        synchronized (mPidsSelfLocked) {
10569            int[] types = new int[pids.length];
10570            int worstType = 0;
10571            for (int i=0; i<pids.length; i++) {
10572                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10573                if (proc != null) {
10574                    int type = proc.setAdj;
10575                    types[i] = type;
10576                    if (type > worstType) {
10577                        worstType = type;
10578                    }
10579                }
10580            }
10581
10582            // If the worst oom_adj is somewhere in the cached proc LRU range,
10583            // then constrain it so we will kill all cached procs.
10584            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10585                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10586                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10587            }
10588
10589            // If this is not a secure call, don't let it kill processes that
10590            // are important.
10591            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10592                worstType = ProcessList.SERVICE_ADJ;
10593            }
10594
10595            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10596            for (int i=0; i<pids.length; i++) {
10597                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10598                if (proc == null) {
10599                    continue;
10600                }
10601                int adj = proc.setAdj;
10602                if (adj >= worstType && !proc.killedByAm) {
10603                    proc.kill(reason, true);
10604                    killed = true;
10605                }
10606            }
10607        }
10608        return killed;
10609    }
10610
10611    @Override
10612    public void killUid(int uid, String reason) {
10613        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10614            throw new SecurityException("killUid only available to the system");
10615        }
10616        synchronized (this) {
10617            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10618                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10619                    reason != null ? reason : "kill uid");
10620        }
10621    }
10622
10623    @Override
10624    public boolean killProcessesBelowForeground(String reason) {
10625        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10626            throw new SecurityException("killProcessesBelowForeground() only available to system");
10627        }
10628
10629        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10630    }
10631
10632    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10633        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10634            throw new SecurityException("killProcessesBelowAdj() only available to system");
10635        }
10636
10637        boolean killed = false;
10638        synchronized (mPidsSelfLocked) {
10639            final int size = mPidsSelfLocked.size();
10640            for (int i = 0; i < size; i++) {
10641                final int pid = mPidsSelfLocked.keyAt(i);
10642                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10643                if (proc == null) continue;
10644
10645                final int adj = proc.setAdj;
10646                if (adj > belowAdj && !proc.killedByAm) {
10647                    proc.kill(reason, true);
10648                    killed = true;
10649                }
10650            }
10651        }
10652        return killed;
10653    }
10654
10655    @Override
10656    public void hang(final IBinder who, boolean allowRestart) {
10657        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10658                != PackageManager.PERMISSION_GRANTED) {
10659            throw new SecurityException("Requires permission "
10660                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10661        }
10662
10663        final IBinder.DeathRecipient death = new DeathRecipient() {
10664            @Override
10665            public void binderDied() {
10666                synchronized (this) {
10667                    notifyAll();
10668                }
10669            }
10670        };
10671
10672        try {
10673            who.linkToDeath(death, 0);
10674        } catch (RemoteException e) {
10675            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10676            return;
10677        }
10678
10679        synchronized (this) {
10680            Watchdog.getInstance().setAllowRestart(allowRestart);
10681            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10682            synchronized (death) {
10683                while (who.isBinderAlive()) {
10684                    try {
10685                        death.wait();
10686                    } catch (InterruptedException e) {
10687                    }
10688                }
10689            }
10690            Watchdog.getInstance().setAllowRestart(true);
10691        }
10692    }
10693
10694    @Override
10695    public void restart() {
10696        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10697                != PackageManager.PERMISSION_GRANTED) {
10698            throw new SecurityException("Requires permission "
10699                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10700        }
10701
10702        Log.i(TAG, "Sending shutdown broadcast...");
10703
10704        BroadcastReceiver br = new BroadcastReceiver() {
10705            @Override public void onReceive(Context context, Intent intent) {
10706                // Now the broadcast is done, finish up the low-level shutdown.
10707                Log.i(TAG, "Shutting down activity manager...");
10708                shutdown(10000);
10709                Log.i(TAG, "Shutdown complete, restarting!");
10710                Process.killProcess(Process.myPid());
10711                System.exit(10);
10712            }
10713        };
10714
10715        // First send the high-level shut down broadcast.
10716        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10717        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10718        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10719        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10720        mContext.sendOrderedBroadcastAsUser(intent,
10721                UserHandle.ALL, null, br, mHandler, 0, null, null);
10722        */
10723        br.onReceive(mContext, intent);
10724    }
10725
10726    private long getLowRamTimeSinceIdle(long now) {
10727        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10728    }
10729
10730    @Override
10731    public void performIdleMaintenance() {
10732        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10733                != PackageManager.PERMISSION_GRANTED) {
10734            throw new SecurityException("Requires permission "
10735                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10736        }
10737
10738        synchronized (this) {
10739            final long now = SystemClock.uptimeMillis();
10740            final long timeSinceLastIdle = now - mLastIdleTime;
10741            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10742            mLastIdleTime = now;
10743            mLowRamTimeSinceLastIdle = 0;
10744            if (mLowRamStartTime != 0) {
10745                mLowRamStartTime = now;
10746            }
10747
10748            StringBuilder sb = new StringBuilder(128);
10749            sb.append("Idle maintenance over ");
10750            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10751            sb.append(" low RAM for ");
10752            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10753            Slog.i(TAG, sb.toString());
10754
10755            // If at least 1/3 of our time since the last idle period has been spent
10756            // with RAM low, then we want to kill processes.
10757            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10758
10759            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10760                ProcessRecord proc = mLruProcesses.get(i);
10761                if (proc.notCachedSinceIdle) {
10762                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10763                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10764                        if (doKilling && proc.initialIdlePss != 0
10765                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10766                            proc.kill("idle maint (pss " + proc.lastPss
10767                                    + " from " + proc.initialIdlePss + ")", true);
10768                        }
10769                    }
10770                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10771                    proc.notCachedSinceIdle = true;
10772                    proc.initialIdlePss = 0;
10773                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10774                            isSleeping(), now);
10775                }
10776            }
10777
10778            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10779            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10780        }
10781    }
10782
10783    private void retrieveSettings() {
10784        final ContentResolver resolver = mContext.getContentResolver();
10785        String debugApp = Settings.Global.getString(
10786            resolver, Settings.Global.DEBUG_APP);
10787        boolean waitForDebugger = Settings.Global.getInt(
10788            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10789        boolean alwaysFinishActivities = Settings.Global.getInt(
10790            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10791        boolean forceRtl = Settings.Global.getInt(
10792                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10793        // Transfer any global setting for forcing RTL layout, into a System Property
10794        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10795
10796        Configuration configuration = new Configuration();
10797        Settings.System.getConfiguration(resolver, configuration);
10798        if (forceRtl) {
10799            // This will take care of setting the correct layout direction flags
10800            configuration.setLayoutDirection(configuration.locale);
10801        }
10802
10803        synchronized (this) {
10804            mDebugApp = mOrigDebugApp = debugApp;
10805            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10806            mAlwaysFinishActivities = alwaysFinishActivities;
10807            // This happens before any activities are started, so we can
10808            // change mConfiguration in-place.
10809            updateConfigurationLocked(configuration, null, false, true);
10810            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10811        }
10812    }
10813
10814    /** Loads resources after the current configuration has been set. */
10815    private void loadResourcesOnSystemReady() {
10816        final Resources res = mContext.getResources();
10817        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10818        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10819        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10820    }
10821
10822    public boolean testIsSystemReady() {
10823        // no need to synchronize(this) just to read & return the value
10824        return mSystemReady;
10825    }
10826
10827    private static File getCalledPreBootReceiversFile() {
10828        File dataDir = Environment.getDataDirectory();
10829        File systemDir = new File(dataDir, "system");
10830        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10831        return fname;
10832    }
10833
10834    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10835        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10836        File file = getCalledPreBootReceiversFile();
10837        FileInputStream fis = null;
10838        try {
10839            fis = new FileInputStream(file);
10840            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10841            int fvers = dis.readInt();
10842            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10843                String vers = dis.readUTF();
10844                String codename = dis.readUTF();
10845                String build = dis.readUTF();
10846                if (android.os.Build.VERSION.RELEASE.equals(vers)
10847                        && android.os.Build.VERSION.CODENAME.equals(codename)
10848                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10849                    int num = dis.readInt();
10850                    while (num > 0) {
10851                        num--;
10852                        String pkg = dis.readUTF();
10853                        String cls = dis.readUTF();
10854                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10855                    }
10856                }
10857            }
10858        } catch (FileNotFoundException e) {
10859        } catch (IOException e) {
10860            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10861        } finally {
10862            if (fis != null) {
10863                try {
10864                    fis.close();
10865                } catch (IOException e) {
10866                }
10867            }
10868        }
10869        return lastDoneReceivers;
10870    }
10871
10872    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10873        File file = getCalledPreBootReceiversFile();
10874        FileOutputStream fos = null;
10875        DataOutputStream dos = null;
10876        try {
10877            fos = new FileOutputStream(file);
10878            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10879            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10880            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10881            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10882            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10883            dos.writeInt(list.size());
10884            for (int i=0; i<list.size(); i++) {
10885                dos.writeUTF(list.get(i).getPackageName());
10886                dos.writeUTF(list.get(i).getClassName());
10887            }
10888        } catch (IOException e) {
10889            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10890            file.delete();
10891        } finally {
10892            FileUtils.sync(fos);
10893            if (dos != null) {
10894                try {
10895                    dos.close();
10896                } catch (IOException e) {
10897                    // TODO Auto-generated catch block
10898                    e.printStackTrace();
10899                }
10900            }
10901        }
10902    }
10903
10904    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10905            ArrayList<ComponentName> doneReceivers, int userId) {
10906        boolean waitingUpdate = false;
10907        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10908        List<ResolveInfo> ris = null;
10909        try {
10910            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10911                    intent, null, 0, userId);
10912        } catch (RemoteException e) {
10913        }
10914        if (ris != null) {
10915            for (int i=ris.size()-1; i>=0; i--) {
10916                if ((ris.get(i).activityInfo.applicationInfo.flags
10917                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10918                    ris.remove(i);
10919                }
10920            }
10921            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10922
10923            // For User 0, load the version number. When delivering to a new user, deliver
10924            // to all receivers.
10925            if (userId == UserHandle.USER_OWNER) {
10926                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10927                for (int i=0; i<ris.size(); i++) {
10928                    ActivityInfo ai = ris.get(i).activityInfo;
10929                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10930                    if (lastDoneReceivers.contains(comp)) {
10931                        // We already did the pre boot receiver for this app with the current
10932                        // platform version, so don't do it again...
10933                        ris.remove(i);
10934                        i--;
10935                        // ...however, do keep it as one that has been done, so we don't
10936                        // forget about it when rewriting the file of last done receivers.
10937                        doneReceivers.add(comp);
10938                    }
10939                }
10940            }
10941
10942            // If primary user, send broadcast to all available users, else just to userId
10943            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10944                    : new int[] { userId };
10945            for (int i = 0; i < ris.size(); i++) {
10946                ActivityInfo ai = ris.get(i).activityInfo;
10947                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10948                doneReceivers.add(comp);
10949                intent.setComponent(comp);
10950                for (int j=0; j<users.length; j++) {
10951                    IIntentReceiver finisher = null;
10952                    // On last receiver and user, set up a completion callback
10953                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10954                        finisher = new IIntentReceiver.Stub() {
10955                            public void performReceive(Intent intent, int resultCode,
10956                                    String data, Bundle extras, boolean ordered,
10957                                    boolean sticky, int sendingUser) {
10958                                // The raw IIntentReceiver interface is called
10959                                // with the AM lock held, so redispatch to
10960                                // execute our code without the lock.
10961                                mHandler.post(onFinishCallback);
10962                            }
10963                        };
10964                    }
10965                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10966                            + " for user " + users[j]);
10967                    broadcastIntentLocked(null, null, intent, null, finisher,
10968                            0, null, null, null, AppOpsManager.OP_NONE,
10969                            true, false, MY_PID, Process.SYSTEM_UID,
10970                            users[j]);
10971                    if (finisher != null) {
10972                        waitingUpdate = true;
10973                    }
10974                }
10975            }
10976        }
10977
10978        return waitingUpdate;
10979    }
10980
10981    public void systemReady(final Runnable goingCallback) {
10982        synchronized(this) {
10983            if (mSystemReady) {
10984                // If we're done calling all the receivers, run the next "boot phase" passed in
10985                // by the SystemServer
10986                if (goingCallback != null) {
10987                    goingCallback.run();
10988                }
10989                return;
10990            }
10991
10992            // Make sure we have the current profile info, since it is needed for
10993            // security checks.
10994            updateCurrentProfileIdsLocked();
10995
10996            if (mRecentTasks == null) {
10997                mRecentTasks = mTaskPersister.restoreTasksLocked();
10998                if (!mRecentTasks.isEmpty()) {
10999                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11000                }
11001                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11002                mTaskPersister.startPersisting();
11003            }
11004
11005            // Check to see if there are any update receivers to run.
11006            if (!mDidUpdate) {
11007                if (mWaitingUpdate) {
11008                    return;
11009                }
11010                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11011                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11012                    public void run() {
11013                        synchronized (ActivityManagerService.this) {
11014                            mDidUpdate = true;
11015                        }
11016                        writeLastDonePreBootReceivers(doneReceivers);
11017                        showBootMessage(mContext.getText(
11018                                R.string.android_upgrading_complete),
11019                                false);
11020                        systemReady(goingCallback);
11021                    }
11022                }, doneReceivers, UserHandle.USER_OWNER);
11023
11024                if (mWaitingUpdate) {
11025                    return;
11026                }
11027                mDidUpdate = true;
11028            }
11029
11030            mAppOpsService.systemReady();
11031            mSystemReady = true;
11032        }
11033
11034        ArrayList<ProcessRecord> procsToKill = null;
11035        synchronized(mPidsSelfLocked) {
11036            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11037                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11038                if (!isAllowedWhileBooting(proc.info)){
11039                    if (procsToKill == null) {
11040                        procsToKill = new ArrayList<ProcessRecord>();
11041                    }
11042                    procsToKill.add(proc);
11043                }
11044            }
11045        }
11046
11047        synchronized(this) {
11048            if (procsToKill != null) {
11049                for (int i=procsToKill.size()-1; i>=0; i--) {
11050                    ProcessRecord proc = procsToKill.get(i);
11051                    Slog.i(TAG, "Removing system update proc: " + proc);
11052                    removeProcessLocked(proc, true, false, "system update done");
11053                }
11054            }
11055
11056            // Now that we have cleaned up any update processes, we
11057            // are ready to start launching real processes and know that
11058            // we won't trample on them any more.
11059            mProcessesReady = true;
11060        }
11061
11062        Slog.i(TAG, "System now ready");
11063        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11064            SystemClock.uptimeMillis());
11065
11066        synchronized(this) {
11067            // Make sure we have no pre-ready processes sitting around.
11068
11069            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11070                ResolveInfo ri = mContext.getPackageManager()
11071                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11072                                STOCK_PM_FLAGS);
11073                CharSequence errorMsg = null;
11074                if (ri != null) {
11075                    ActivityInfo ai = ri.activityInfo;
11076                    ApplicationInfo app = ai.applicationInfo;
11077                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11078                        mTopAction = Intent.ACTION_FACTORY_TEST;
11079                        mTopData = null;
11080                        mTopComponent = new ComponentName(app.packageName,
11081                                ai.name);
11082                    } else {
11083                        errorMsg = mContext.getResources().getText(
11084                                com.android.internal.R.string.factorytest_not_system);
11085                    }
11086                } else {
11087                    errorMsg = mContext.getResources().getText(
11088                            com.android.internal.R.string.factorytest_no_action);
11089                }
11090                if (errorMsg != null) {
11091                    mTopAction = null;
11092                    mTopData = null;
11093                    mTopComponent = null;
11094                    Message msg = Message.obtain();
11095                    msg.what = SHOW_FACTORY_ERROR_MSG;
11096                    msg.getData().putCharSequence("msg", errorMsg);
11097                    mHandler.sendMessage(msg);
11098                }
11099            }
11100        }
11101
11102        retrieveSettings();
11103        loadResourcesOnSystemReady();
11104
11105        synchronized (this) {
11106            readGrantedUriPermissionsLocked();
11107        }
11108
11109        if (goingCallback != null) goingCallback.run();
11110
11111        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11112                Integer.toString(mCurrentUserId), mCurrentUserId);
11113        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11114                Integer.toString(mCurrentUserId), mCurrentUserId);
11115        mSystemServiceManager.startUser(mCurrentUserId);
11116
11117        synchronized (this) {
11118            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11119                try {
11120                    List apps = AppGlobals.getPackageManager().
11121                        getPersistentApplications(STOCK_PM_FLAGS);
11122                    if (apps != null) {
11123                        int N = apps.size();
11124                        int i;
11125                        for (i=0; i<N; i++) {
11126                            ApplicationInfo info
11127                                = (ApplicationInfo)apps.get(i);
11128                            if (info != null &&
11129                                    !info.packageName.equals("android")) {
11130                                addAppLocked(info, false, null /* ABI override */);
11131                            }
11132                        }
11133                    }
11134                } catch (RemoteException ex) {
11135                    // pm is in same process, this will never happen.
11136                }
11137            }
11138
11139            // Start up initial activity.
11140            mBooting = true;
11141
11142            try {
11143                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11144                    Message msg = Message.obtain();
11145                    msg.what = SHOW_UID_ERROR_MSG;
11146                    mHandler.sendMessage(msg);
11147                }
11148            } catch (RemoteException e) {
11149            }
11150
11151            long ident = Binder.clearCallingIdentity();
11152            try {
11153                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11154                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11155                        | Intent.FLAG_RECEIVER_FOREGROUND);
11156                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11157                broadcastIntentLocked(null, null, intent,
11158                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11159                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11160                intent = new Intent(Intent.ACTION_USER_STARTING);
11161                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11162                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11163                broadcastIntentLocked(null, null, intent,
11164                        null, new IIntentReceiver.Stub() {
11165                            @Override
11166                            public void performReceive(Intent intent, int resultCode, String data,
11167                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11168                                    throws RemoteException {
11169                            }
11170                        }, 0, null, null,
11171                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11172                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11173            } catch (Throwable t) {
11174                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11175            } finally {
11176                Binder.restoreCallingIdentity(ident);
11177            }
11178            mStackSupervisor.resumeTopActivitiesLocked();
11179            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11180        }
11181    }
11182
11183    private boolean makeAppCrashingLocked(ProcessRecord app,
11184            String shortMsg, String longMsg, String stackTrace) {
11185        app.crashing = true;
11186        app.crashingReport = generateProcessError(app,
11187                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11188        startAppProblemLocked(app);
11189        app.stopFreezingAllLocked();
11190        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11191    }
11192
11193    private void makeAppNotRespondingLocked(ProcessRecord app,
11194            String activity, String shortMsg, String longMsg) {
11195        app.notResponding = true;
11196        app.notRespondingReport = generateProcessError(app,
11197                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11198                activity, shortMsg, longMsg, null);
11199        startAppProblemLocked(app);
11200        app.stopFreezingAllLocked();
11201    }
11202
11203    /**
11204     * Generate a process error record, suitable for attachment to a ProcessRecord.
11205     *
11206     * @param app The ProcessRecord in which the error occurred.
11207     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11208     *                      ActivityManager.AppErrorStateInfo
11209     * @param activity The activity associated with the crash, if known.
11210     * @param shortMsg Short message describing the crash.
11211     * @param longMsg Long message describing the crash.
11212     * @param stackTrace Full crash stack trace, may be null.
11213     *
11214     * @return Returns a fully-formed AppErrorStateInfo record.
11215     */
11216    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11217            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11218        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11219
11220        report.condition = condition;
11221        report.processName = app.processName;
11222        report.pid = app.pid;
11223        report.uid = app.info.uid;
11224        report.tag = activity;
11225        report.shortMsg = shortMsg;
11226        report.longMsg = longMsg;
11227        report.stackTrace = stackTrace;
11228
11229        return report;
11230    }
11231
11232    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11233        synchronized (this) {
11234            app.crashing = false;
11235            app.crashingReport = null;
11236            app.notResponding = false;
11237            app.notRespondingReport = null;
11238            if (app.anrDialog == fromDialog) {
11239                app.anrDialog = null;
11240            }
11241            if (app.waitDialog == fromDialog) {
11242                app.waitDialog = null;
11243            }
11244            if (app.pid > 0 && app.pid != MY_PID) {
11245                handleAppCrashLocked(app, null, null, null);
11246                app.kill("user request after error", true);
11247            }
11248        }
11249    }
11250
11251    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11252            String stackTrace) {
11253        long now = SystemClock.uptimeMillis();
11254
11255        Long crashTime;
11256        if (!app.isolated) {
11257            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11258        } else {
11259            crashTime = null;
11260        }
11261        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11262            // This process loses!
11263            Slog.w(TAG, "Process " + app.info.processName
11264                    + " has crashed too many times: killing!");
11265            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11266                    app.userId, app.info.processName, app.uid);
11267            mStackSupervisor.handleAppCrashLocked(app);
11268            if (!app.persistent) {
11269                // We don't want to start this process again until the user
11270                // explicitly does so...  but for persistent process, we really
11271                // need to keep it running.  If a persistent process is actually
11272                // repeatedly crashing, then badness for everyone.
11273                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11274                        app.info.processName);
11275                if (!app.isolated) {
11276                    // XXX We don't have a way to mark isolated processes
11277                    // as bad, since they don't have a peristent identity.
11278                    mBadProcesses.put(app.info.processName, app.uid,
11279                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11280                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11281                }
11282                app.bad = true;
11283                app.removed = true;
11284                // Don't let services in this process be restarted and potentially
11285                // annoy the user repeatedly.  Unless it is persistent, since those
11286                // processes run critical code.
11287                removeProcessLocked(app, false, false, "crash");
11288                mStackSupervisor.resumeTopActivitiesLocked();
11289                return false;
11290            }
11291            mStackSupervisor.resumeTopActivitiesLocked();
11292        } else {
11293            mStackSupervisor.finishTopRunningActivityLocked(app);
11294        }
11295
11296        // Bump up the crash count of any services currently running in the proc.
11297        for (int i=app.services.size()-1; i>=0; i--) {
11298            // Any services running in the application need to be placed
11299            // back in the pending list.
11300            ServiceRecord sr = app.services.valueAt(i);
11301            sr.crashCount++;
11302        }
11303
11304        // If the crashing process is what we consider to be the "home process" and it has been
11305        // replaced by a third-party app, clear the package preferred activities from packages
11306        // with a home activity running in the process to prevent a repeatedly crashing app
11307        // from blocking the user to manually clear the list.
11308        final ArrayList<ActivityRecord> activities = app.activities;
11309        if (app == mHomeProcess && activities.size() > 0
11310                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11311            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11312                final ActivityRecord r = activities.get(activityNdx);
11313                if (r.isHomeActivity()) {
11314                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11315                    try {
11316                        ActivityThread.getPackageManager()
11317                                .clearPackagePreferredActivities(r.packageName);
11318                    } catch (RemoteException c) {
11319                        // pm is in same process, this will never happen.
11320                    }
11321                }
11322            }
11323        }
11324
11325        if (!app.isolated) {
11326            // XXX Can't keep track of crash times for isolated processes,
11327            // because they don't have a perisistent identity.
11328            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11329        }
11330
11331        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11332        return true;
11333    }
11334
11335    void startAppProblemLocked(ProcessRecord app) {
11336        // If this app is not running under the current user, then we
11337        // can't give it a report button because that would require
11338        // launching the report UI under a different user.
11339        app.errorReportReceiver = null;
11340
11341        for (int userId : mCurrentProfileIds) {
11342            if (app.userId == userId) {
11343                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11344                        mContext, app.info.packageName, app.info.flags);
11345            }
11346        }
11347        skipCurrentReceiverLocked(app);
11348    }
11349
11350    void skipCurrentReceiverLocked(ProcessRecord app) {
11351        for (BroadcastQueue queue : mBroadcastQueues) {
11352            queue.skipCurrentReceiverLocked(app);
11353        }
11354    }
11355
11356    /**
11357     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11358     * The application process will exit immediately after this call returns.
11359     * @param app object of the crashing app, null for the system server
11360     * @param crashInfo describing the exception
11361     */
11362    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11363        ProcessRecord r = findAppProcess(app, "Crash");
11364        final String processName = app == null ? "system_server"
11365                : (r == null ? "unknown" : r.processName);
11366
11367        handleApplicationCrashInner("crash", r, processName, crashInfo);
11368    }
11369
11370    /* Native crash reporting uses this inner version because it needs to be somewhat
11371     * decoupled from the AM-managed cleanup lifecycle
11372     */
11373    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11374            ApplicationErrorReport.CrashInfo crashInfo) {
11375        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11376                UserHandle.getUserId(Binder.getCallingUid()), processName,
11377                r == null ? -1 : r.info.flags,
11378                crashInfo.exceptionClassName,
11379                crashInfo.exceptionMessage,
11380                crashInfo.throwFileName,
11381                crashInfo.throwLineNumber);
11382
11383        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11384
11385        crashApplication(r, crashInfo);
11386    }
11387
11388    public void handleApplicationStrictModeViolation(
11389            IBinder app,
11390            int violationMask,
11391            StrictMode.ViolationInfo info) {
11392        ProcessRecord r = findAppProcess(app, "StrictMode");
11393        if (r == null) {
11394            return;
11395        }
11396
11397        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11398            Integer stackFingerprint = info.hashCode();
11399            boolean logIt = true;
11400            synchronized (mAlreadyLoggedViolatedStacks) {
11401                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11402                    logIt = false;
11403                    // TODO: sub-sample into EventLog for these, with
11404                    // the info.durationMillis?  Then we'd get
11405                    // the relative pain numbers, without logging all
11406                    // the stack traces repeatedly.  We'd want to do
11407                    // likewise in the client code, which also does
11408                    // dup suppression, before the Binder call.
11409                } else {
11410                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11411                        mAlreadyLoggedViolatedStacks.clear();
11412                    }
11413                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11414                }
11415            }
11416            if (logIt) {
11417                logStrictModeViolationToDropBox(r, info);
11418            }
11419        }
11420
11421        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11422            AppErrorResult result = new AppErrorResult();
11423            synchronized (this) {
11424                final long origId = Binder.clearCallingIdentity();
11425
11426                Message msg = Message.obtain();
11427                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11428                HashMap<String, Object> data = new HashMap<String, Object>();
11429                data.put("result", result);
11430                data.put("app", r);
11431                data.put("violationMask", violationMask);
11432                data.put("info", info);
11433                msg.obj = data;
11434                mHandler.sendMessage(msg);
11435
11436                Binder.restoreCallingIdentity(origId);
11437            }
11438            int res = result.get();
11439            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11440        }
11441    }
11442
11443    // Depending on the policy in effect, there could be a bunch of
11444    // these in quick succession so we try to batch these together to
11445    // minimize disk writes, number of dropbox entries, and maximize
11446    // compression, by having more fewer, larger records.
11447    private void logStrictModeViolationToDropBox(
11448            ProcessRecord process,
11449            StrictMode.ViolationInfo info) {
11450        if (info == null) {
11451            return;
11452        }
11453        final boolean isSystemApp = process == null ||
11454                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11455                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11456        final String processName = process == null ? "unknown" : process.processName;
11457        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11458        final DropBoxManager dbox = (DropBoxManager)
11459                mContext.getSystemService(Context.DROPBOX_SERVICE);
11460
11461        // Exit early if the dropbox isn't configured to accept this report type.
11462        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11463
11464        boolean bufferWasEmpty;
11465        boolean needsFlush;
11466        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11467        synchronized (sb) {
11468            bufferWasEmpty = sb.length() == 0;
11469            appendDropBoxProcessHeaders(process, processName, sb);
11470            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11471            sb.append("System-App: ").append(isSystemApp).append("\n");
11472            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11473            if (info.violationNumThisLoop != 0) {
11474                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11475            }
11476            if (info.numAnimationsRunning != 0) {
11477                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11478            }
11479            if (info.broadcastIntentAction != null) {
11480                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11481            }
11482            if (info.durationMillis != -1) {
11483                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11484            }
11485            if (info.numInstances != -1) {
11486                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11487            }
11488            if (info.tags != null) {
11489                for (String tag : info.tags) {
11490                    sb.append("Span-Tag: ").append(tag).append("\n");
11491                }
11492            }
11493            sb.append("\n");
11494            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11495                sb.append(info.crashInfo.stackTrace);
11496            }
11497            sb.append("\n");
11498
11499            // Only buffer up to ~64k.  Various logging bits truncate
11500            // things at 128k.
11501            needsFlush = (sb.length() > 64 * 1024);
11502        }
11503
11504        // Flush immediately if the buffer's grown too large, or this
11505        // is a non-system app.  Non-system apps are isolated with a
11506        // different tag & policy and not batched.
11507        //
11508        // Batching is useful during internal testing with
11509        // StrictMode settings turned up high.  Without batching,
11510        // thousands of separate files could be created on boot.
11511        if (!isSystemApp || needsFlush) {
11512            new Thread("Error dump: " + dropboxTag) {
11513                @Override
11514                public void run() {
11515                    String report;
11516                    synchronized (sb) {
11517                        report = sb.toString();
11518                        sb.delete(0, sb.length());
11519                        sb.trimToSize();
11520                    }
11521                    if (report.length() != 0) {
11522                        dbox.addText(dropboxTag, report);
11523                    }
11524                }
11525            }.start();
11526            return;
11527        }
11528
11529        // System app batching:
11530        if (!bufferWasEmpty) {
11531            // An existing dropbox-writing thread is outstanding, so
11532            // we don't need to start it up.  The existing thread will
11533            // catch the buffer appends we just did.
11534            return;
11535        }
11536
11537        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11538        // (After this point, we shouldn't access AMS internal data structures.)
11539        new Thread("Error dump: " + dropboxTag) {
11540            @Override
11541            public void run() {
11542                // 5 second sleep to let stacks arrive and be batched together
11543                try {
11544                    Thread.sleep(5000);  // 5 seconds
11545                } catch (InterruptedException e) {}
11546
11547                String errorReport;
11548                synchronized (mStrictModeBuffer) {
11549                    errorReport = mStrictModeBuffer.toString();
11550                    if (errorReport.length() == 0) {
11551                        return;
11552                    }
11553                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11554                    mStrictModeBuffer.trimToSize();
11555                }
11556                dbox.addText(dropboxTag, errorReport);
11557            }
11558        }.start();
11559    }
11560
11561    /**
11562     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11563     * @param app object of the crashing app, null for the system server
11564     * @param tag reported by the caller
11565     * @param system whether this wtf is coming from the system
11566     * @param crashInfo describing the context of the error
11567     * @return true if the process should exit immediately (WTF is fatal)
11568     */
11569    public boolean handleApplicationWtf(IBinder app, final String tag, boolean system,
11570            final ApplicationErrorReport.CrashInfo crashInfo) {
11571        final ProcessRecord r = findAppProcess(app, "WTF");
11572        final String processName = app == null ? "system_server"
11573                : (r == null ? "unknown" : r.processName);
11574
11575        EventLog.writeEvent(EventLogTags.AM_WTF,
11576                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
11577                processName,
11578                r == null ? -1 : r.info.flags,
11579                tag, crashInfo.exceptionMessage);
11580
11581        if (system) {
11582            // If this is coming from the system, we could very well have low-level
11583            // system locks held, so we want to do this all asynchronously.  And we
11584            // never want this to become fatal, so there is that too.
11585            mHandler.post(new Runnable() {
11586                @Override public void run() {
11587                    addErrorToDropBox("wtf", r, processName, null, null, tag, null, null,
11588                            crashInfo);
11589                }
11590            });
11591            return false;
11592        }
11593
11594        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11595
11596        if (r != null && r.pid != Process.myPid() &&
11597                Settings.Global.getInt(mContext.getContentResolver(),
11598                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11599            crashApplication(r, crashInfo);
11600            return true;
11601        } else {
11602            return false;
11603        }
11604    }
11605
11606    /**
11607     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11608     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11609     */
11610    private ProcessRecord findAppProcess(IBinder app, String reason) {
11611        if (app == null) {
11612            return null;
11613        }
11614
11615        synchronized (this) {
11616            final int NP = mProcessNames.getMap().size();
11617            for (int ip=0; ip<NP; ip++) {
11618                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11619                final int NA = apps.size();
11620                for (int ia=0; ia<NA; ia++) {
11621                    ProcessRecord p = apps.valueAt(ia);
11622                    if (p.thread != null && p.thread.asBinder() == app) {
11623                        return p;
11624                    }
11625                }
11626            }
11627
11628            Slog.w(TAG, "Can't find mystery application for " + reason
11629                    + " from pid=" + Binder.getCallingPid()
11630                    + " uid=" + Binder.getCallingUid() + ": " + app);
11631            return null;
11632        }
11633    }
11634
11635    /**
11636     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11637     * to append various headers to the dropbox log text.
11638     */
11639    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11640            StringBuilder sb) {
11641        // Watchdog thread ends up invoking this function (with
11642        // a null ProcessRecord) to add the stack file to dropbox.
11643        // Do not acquire a lock on this (am) in such cases, as it
11644        // could cause a potential deadlock, if and when watchdog
11645        // is invoked due to unavailability of lock on am and it
11646        // would prevent watchdog from killing system_server.
11647        if (process == null) {
11648            sb.append("Process: ").append(processName).append("\n");
11649            return;
11650        }
11651        // Note: ProcessRecord 'process' is guarded by the service
11652        // instance.  (notably process.pkgList, which could otherwise change
11653        // concurrently during execution of this method)
11654        synchronized (this) {
11655            sb.append("Process: ").append(processName).append("\n");
11656            int flags = process.info.flags;
11657            IPackageManager pm = AppGlobals.getPackageManager();
11658            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11659            for (int ip=0; ip<process.pkgList.size(); ip++) {
11660                String pkg = process.pkgList.keyAt(ip);
11661                sb.append("Package: ").append(pkg);
11662                try {
11663                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11664                    if (pi != null) {
11665                        sb.append(" v").append(pi.versionCode);
11666                        if (pi.versionName != null) {
11667                            sb.append(" (").append(pi.versionName).append(")");
11668                        }
11669                    }
11670                } catch (RemoteException e) {
11671                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11672                }
11673                sb.append("\n");
11674            }
11675        }
11676    }
11677
11678    private static String processClass(ProcessRecord process) {
11679        if (process == null || process.pid == MY_PID) {
11680            return "system_server";
11681        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11682            return "system_app";
11683        } else {
11684            return "data_app";
11685        }
11686    }
11687
11688    /**
11689     * Write a description of an error (crash, WTF, ANR) to the drop box.
11690     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11691     * @param process which caused the error, null means the system server
11692     * @param activity which triggered the error, null if unknown
11693     * @param parent activity related to the error, null if unknown
11694     * @param subject line related to the error, null if absent
11695     * @param report in long form describing the error, null if absent
11696     * @param logFile to include in the report, null if none
11697     * @param crashInfo giving an application stack trace, null if absent
11698     */
11699    public void addErrorToDropBox(String eventType,
11700            ProcessRecord process, String processName, ActivityRecord activity,
11701            ActivityRecord parent, String subject,
11702            final String report, final File logFile,
11703            final ApplicationErrorReport.CrashInfo crashInfo) {
11704        // NOTE -- this must never acquire the ActivityManagerService lock,
11705        // otherwise the watchdog may be prevented from resetting the system.
11706
11707        final String dropboxTag = processClass(process) + "_" + eventType;
11708        final DropBoxManager dbox = (DropBoxManager)
11709                mContext.getSystemService(Context.DROPBOX_SERVICE);
11710
11711        // Exit early if the dropbox isn't configured to accept this report type.
11712        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11713
11714        final StringBuilder sb = new StringBuilder(1024);
11715        appendDropBoxProcessHeaders(process, processName, sb);
11716        if (activity != null) {
11717            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11718        }
11719        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11720            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11721        }
11722        if (parent != null && parent != activity) {
11723            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11724        }
11725        if (subject != null) {
11726            sb.append("Subject: ").append(subject).append("\n");
11727        }
11728        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11729        if (Debug.isDebuggerConnected()) {
11730            sb.append("Debugger: Connected\n");
11731        }
11732        sb.append("\n");
11733
11734        // Do the rest in a worker thread to avoid blocking the caller on I/O
11735        // (After this point, we shouldn't access AMS internal data structures.)
11736        Thread worker = new Thread("Error dump: " + dropboxTag) {
11737            @Override
11738            public void run() {
11739                if (report != null) {
11740                    sb.append(report);
11741                }
11742                if (logFile != null) {
11743                    try {
11744                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11745                                    "\n\n[[TRUNCATED]]"));
11746                    } catch (IOException e) {
11747                        Slog.e(TAG, "Error reading " + logFile, e);
11748                    }
11749                }
11750                if (crashInfo != null && crashInfo.stackTrace != null) {
11751                    sb.append(crashInfo.stackTrace);
11752                }
11753
11754                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11755                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11756                if (lines > 0) {
11757                    sb.append("\n");
11758
11759                    // Merge several logcat streams, and take the last N lines
11760                    InputStreamReader input = null;
11761                    try {
11762                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11763                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11764                                "-b", "crash",
11765                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11766
11767                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11768                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11769                        input = new InputStreamReader(logcat.getInputStream());
11770
11771                        int num;
11772                        char[] buf = new char[8192];
11773                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11774                    } catch (IOException e) {
11775                        Slog.e(TAG, "Error running logcat", e);
11776                    } finally {
11777                        if (input != null) try { input.close(); } catch (IOException e) {}
11778                    }
11779                }
11780
11781                dbox.addText(dropboxTag, sb.toString());
11782            }
11783        };
11784
11785        if (process == null) {
11786            // If process is null, we are being called from some internal code
11787            // and may be about to die -- run this synchronously.
11788            worker.run();
11789        } else {
11790            worker.start();
11791        }
11792    }
11793
11794    /**
11795     * Bring up the "unexpected error" dialog box for a crashing app.
11796     * Deal with edge cases (intercepts from instrumented applications,
11797     * ActivityController, error intent receivers, that sort of thing).
11798     * @param r the application crashing
11799     * @param crashInfo describing the failure
11800     */
11801    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11802        long timeMillis = System.currentTimeMillis();
11803        String shortMsg = crashInfo.exceptionClassName;
11804        String longMsg = crashInfo.exceptionMessage;
11805        String stackTrace = crashInfo.stackTrace;
11806        if (shortMsg != null && longMsg != null) {
11807            longMsg = shortMsg + ": " + longMsg;
11808        } else if (shortMsg != null) {
11809            longMsg = shortMsg;
11810        }
11811
11812        AppErrorResult result = new AppErrorResult();
11813        synchronized (this) {
11814            if (mController != null) {
11815                try {
11816                    String name = r != null ? r.processName : null;
11817                    int pid = r != null ? r.pid : Binder.getCallingPid();
11818                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11819                    if (!mController.appCrashed(name, pid,
11820                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11821                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11822                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11823                            Slog.w(TAG, "Skip killing native crashed app " + name
11824                                    + "(" + pid + ") during testing");
11825                        } else {
11826                            Slog.w(TAG, "Force-killing crashed app " + name
11827                                    + " at watcher's request");
11828                            if (r != null) {
11829                                r.kill("crash", true);
11830                            } else {
11831                                // Huh.
11832                                Process.killProcess(pid);
11833                                Process.killProcessGroup(uid, pid);
11834                            }
11835                        }
11836                        return;
11837                    }
11838                } catch (RemoteException e) {
11839                    mController = null;
11840                    Watchdog.getInstance().setActivityController(null);
11841                }
11842            }
11843
11844            final long origId = Binder.clearCallingIdentity();
11845
11846            // If this process is running instrumentation, finish it.
11847            if (r != null && r.instrumentationClass != null) {
11848                Slog.w(TAG, "Error in app " + r.processName
11849                      + " running instrumentation " + r.instrumentationClass + ":");
11850                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11851                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11852                Bundle info = new Bundle();
11853                info.putString("shortMsg", shortMsg);
11854                info.putString("longMsg", longMsg);
11855                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11856                Binder.restoreCallingIdentity(origId);
11857                return;
11858            }
11859
11860            // If we can't identify the process or it's already exceeded its crash quota,
11861            // quit right away without showing a crash dialog.
11862            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11863                Binder.restoreCallingIdentity(origId);
11864                return;
11865            }
11866
11867            Message msg = Message.obtain();
11868            msg.what = SHOW_ERROR_MSG;
11869            HashMap data = new HashMap();
11870            data.put("result", result);
11871            data.put("app", r);
11872            msg.obj = data;
11873            mHandler.sendMessage(msg);
11874
11875            Binder.restoreCallingIdentity(origId);
11876        }
11877
11878        int res = result.get();
11879
11880        Intent appErrorIntent = null;
11881        synchronized (this) {
11882            if (r != null && !r.isolated) {
11883                // XXX Can't keep track of crash time for isolated processes,
11884                // since they don't have a persistent identity.
11885                mProcessCrashTimes.put(r.info.processName, r.uid,
11886                        SystemClock.uptimeMillis());
11887            }
11888            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11889                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11890            }
11891        }
11892
11893        if (appErrorIntent != null) {
11894            try {
11895                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11896            } catch (ActivityNotFoundException e) {
11897                Slog.w(TAG, "bug report receiver dissappeared", e);
11898            }
11899        }
11900    }
11901
11902    Intent createAppErrorIntentLocked(ProcessRecord r,
11903            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11904        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11905        if (report == null) {
11906            return null;
11907        }
11908        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11909        result.setComponent(r.errorReportReceiver);
11910        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11911        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11912        return result;
11913    }
11914
11915    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11916            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11917        if (r.errorReportReceiver == null) {
11918            return null;
11919        }
11920
11921        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11922            return null;
11923        }
11924
11925        ApplicationErrorReport report = new ApplicationErrorReport();
11926        report.packageName = r.info.packageName;
11927        report.installerPackageName = r.errorReportReceiver.getPackageName();
11928        report.processName = r.processName;
11929        report.time = timeMillis;
11930        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11931
11932        if (r.crashing || r.forceCrashReport) {
11933            report.type = ApplicationErrorReport.TYPE_CRASH;
11934            report.crashInfo = crashInfo;
11935        } else if (r.notResponding) {
11936            report.type = ApplicationErrorReport.TYPE_ANR;
11937            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11938
11939            report.anrInfo.activity = r.notRespondingReport.tag;
11940            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11941            report.anrInfo.info = r.notRespondingReport.longMsg;
11942        }
11943
11944        return report;
11945    }
11946
11947    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11948        enforceNotIsolatedCaller("getProcessesInErrorState");
11949        // assume our apps are happy - lazy create the list
11950        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11951
11952        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11953                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11954        int userId = UserHandle.getUserId(Binder.getCallingUid());
11955
11956        synchronized (this) {
11957
11958            // iterate across all processes
11959            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11960                ProcessRecord app = mLruProcesses.get(i);
11961                if (!allUsers && app.userId != userId) {
11962                    continue;
11963                }
11964                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11965                    // This one's in trouble, so we'll generate a report for it
11966                    // crashes are higher priority (in case there's a crash *and* an anr)
11967                    ActivityManager.ProcessErrorStateInfo report = null;
11968                    if (app.crashing) {
11969                        report = app.crashingReport;
11970                    } else if (app.notResponding) {
11971                        report = app.notRespondingReport;
11972                    }
11973
11974                    if (report != null) {
11975                        if (errList == null) {
11976                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11977                        }
11978                        errList.add(report);
11979                    } else {
11980                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11981                                " crashing = " + app.crashing +
11982                                " notResponding = " + app.notResponding);
11983                    }
11984                }
11985            }
11986        }
11987
11988        return errList;
11989    }
11990
11991    static int procStateToImportance(int procState, int memAdj,
11992            ActivityManager.RunningAppProcessInfo currApp) {
11993        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11994        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11995            currApp.lru = memAdj;
11996        } else {
11997            currApp.lru = 0;
11998        }
11999        return imp;
12000    }
12001
12002    private void fillInProcMemInfo(ProcessRecord app,
12003            ActivityManager.RunningAppProcessInfo outInfo) {
12004        outInfo.pid = app.pid;
12005        outInfo.uid = app.info.uid;
12006        if (mHeavyWeightProcess == app) {
12007            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12008        }
12009        if (app.persistent) {
12010            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12011        }
12012        if (app.activities.size() > 0) {
12013            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12014        }
12015        outInfo.lastTrimLevel = app.trimMemoryLevel;
12016        int adj = app.curAdj;
12017        int procState = app.curProcState;
12018        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12019        outInfo.importanceReasonCode = app.adjTypeCode;
12020        outInfo.processState = app.curProcState;
12021    }
12022
12023    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12024        enforceNotIsolatedCaller("getRunningAppProcesses");
12025        // Lazy instantiation of list
12026        List<ActivityManager.RunningAppProcessInfo> runList = null;
12027        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12028                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12029        int userId = UserHandle.getUserId(Binder.getCallingUid());
12030        synchronized (this) {
12031            // Iterate across all processes
12032            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12033                ProcessRecord app = mLruProcesses.get(i);
12034                if (!allUsers && app.userId != userId) {
12035                    continue;
12036                }
12037                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12038                    // Generate process state info for running application
12039                    ActivityManager.RunningAppProcessInfo currApp =
12040                        new ActivityManager.RunningAppProcessInfo(app.processName,
12041                                app.pid, app.getPackageList());
12042                    fillInProcMemInfo(app, currApp);
12043                    if (app.adjSource instanceof ProcessRecord) {
12044                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12045                        currApp.importanceReasonImportance =
12046                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12047                                        app.adjSourceProcState);
12048                    } else if (app.adjSource instanceof ActivityRecord) {
12049                        ActivityRecord r = (ActivityRecord)app.adjSource;
12050                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12051                    }
12052                    if (app.adjTarget instanceof ComponentName) {
12053                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12054                    }
12055                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12056                    //        + " lru=" + currApp.lru);
12057                    if (runList == null) {
12058                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12059                    }
12060                    runList.add(currApp);
12061                }
12062            }
12063        }
12064        return runList;
12065    }
12066
12067    public List<ApplicationInfo> getRunningExternalApplications() {
12068        enforceNotIsolatedCaller("getRunningExternalApplications");
12069        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12070        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12071        if (runningApps != null && runningApps.size() > 0) {
12072            Set<String> extList = new HashSet<String>();
12073            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12074                if (app.pkgList != null) {
12075                    for (String pkg : app.pkgList) {
12076                        extList.add(pkg);
12077                    }
12078                }
12079            }
12080            IPackageManager pm = AppGlobals.getPackageManager();
12081            for (String pkg : extList) {
12082                try {
12083                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12084                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12085                        retList.add(info);
12086                    }
12087                } catch (RemoteException e) {
12088                }
12089            }
12090        }
12091        return retList;
12092    }
12093
12094    @Override
12095    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12096        enforceNotIsolatedCaller("getMyMemoryState");
12097        synchronized (this) {
12098            ProcessRecord proc;
12099            synchronized (mPidsSelfLocked) {
12100                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12101            }
12102            fillInProcMemInfo(proc, outInfo);
12103        }
12104    }
12105
12106    @Override
12107    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12108        if (checkCallingPermission(android.Manifest.permission.DUMP)
12109                != PackageManager.PERMISSION_GRANTED) {
12110            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12111                    + Binder.getCallingPid()
12112                    + ", uid=" + Binder.getCallingUid()
12113                    + " without permission "
12114                    + android.Manifest.permission.DUMP);
12115            return;
12116        }
12117
12118        boolean dumpAll = false;
12119        boolean dumpClient = false;
12120        String dumpPackage = null;
12121
12122        int opti = 0;
12123        while (opti < args.length) {
12124            String opt = args[opti];
12125            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12126                break;
12127            }
12128            opti++;
12129            if ("-a".equals(opt)) {
12130                dumpAll = true;
12131            } else if ("-c".equals(opt)) {
12132                dumpClient = true;
12133            } else if ("-h".equals(opt)) {
12134                pw.println("Activity manager dump options:");
12135                pw.println("  [-a] [-c] [-h] [cmd] ...");
12136                pw.println("  cmd may be one of:");
12137                pw.println("    a[ctivities]: activity stack state");
12138                pw.println("    r[recents]: recent activities state");
12139                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12140                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12141                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12142                pw.println("    o[om]: out of memory management");
12143                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12144                pw.println("    provider [COMP_SPEC]: provider client-side state");
12145                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12146                pw.println("    service [COMP_SPEC]: service client-side state");
12147                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12148                pw.println("    all: dump all activities");
12149                pw.println("    top: dump the top activity");
12150                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12151                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12152                pw.println("    a partial substring in a component name, a");
12153                pw.println("    hex object identifier.");
12154                pw.println("  -a: include all available server state.");
12155                pw.println("  -c: include client state.");
12156                return;
12157            } else {
12158                pw.println("Unknown argument: " + opt + "; use -h for help");
12159            }
12160        }
12161
12162        long origId = Binder.clearCallingIdentity();
12163        boolean more = false;
12164        // Is the caller requesting to dump a particular piece of data?
12165        if (opti < args.length) {
12166            String cmd = args[opti];
12167            opti++;
12168            if ("activities".equals(cmd) || "a".equals(cmd)) {
12169                synchronized (this) {
12170                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12171                }
12172            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12173                synchronized (this) {
12174                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12175                }
12176            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12177                String[] newArgs;
12178                String name;
12179                if (opti >= args.length) {
12180                    name = null;
12181                    newArgs = EMPTY_STRING_ARRAY;
12182                } else {
12183                    name = args[opti];
12184                    opti++;
12185                    newArgs = new String[args.length - opti];
12186                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12187                            args.length - opti);
12188                }
12189                synchronized (this) {
12190                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12191                }
12192            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12193                String[] newArgs;
12194                String name;
12195                if (opti >= args.length) {
12196                    name = null;
12197                    newArgs = EMPTY_STRING_ARRAY;
12198                } else {
12199                    name = args[opti];
12200                    opti++;
12201                    newArgs = new String[args.length - opti];
12202                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12203                            args.length - opti);
12204                }
12205                synchronized (this) {
12206                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12207                }
12208            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12209                String[] newArgs;
12210                String name;
12211                if (opti >= args.length) {
12212                    name = null;
12213                    newArgs = EMPTY_STRING_ARRAY;
12214                } else {
12215                    name = args[opti];
12216                    opti++;
12217                    newArgs = new String[args.length - opti];
12218                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12219                            args.length - opti);
12220                }
12221                synchronized (this) {
12222                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12223                }
12224            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12225                synchronized (this) {
12226                    dumpOomLocked(fd, pw, args, opti, true);
12227                }
12228            } else if ("provider".equals(cmd)) {
12229                String[] newArgs;
12230                String name;
12231                if (opti >= args.length) {
12232                    name = null;
12233                    newArgs = EMPTY_STRING_ARRAY;
12234                } else {
12235                    name = args[opti];
12236                    opti++;
12237                    newArgs = new String[args.length - opti];
12238                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12239                }
12240                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12241                    pw.println("No providers match: " + name);
12242                    pw.println("Use -h for help.");
12243                }
12244            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12245                synchronized (this) {
12246                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12247                }
12248            } else if ("service".equals(cmd)) {
12249                String[] newArgs;
12250                String name;
12251                if (opti >= args.length) {
12252                    name = null;
12253                    newArgs = EMPTY_STRING_ARRAY;
12254                } else {
12255                    name = args[opti];
12256                    opti++;
12257                    newArgs = new String[args.length - opti];
12258                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12259                            args.length - opti);
12260                }
12261                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12262                    pw.println("No services match: " + name);
12263                    pw.println("Use -h for help.");
12264                }
12265            } else if ("package".equals(cmd)) {
12266                String[] newArgs;
12267                if (opti >= args.length) {
12268                    pw.println("package: no package name specified");
12269                    pw.println("Use -h for help.");
12270                } else {
12271                    dumpPackage = args[opti];
12272                    opti++;
12273                    newArgs = new String[args.length - opti];
12274                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12275                            args.length - opti);
12276                    args = newArgs;
12277                    opti = 0;
12278                    more = true;
12279                }
12280            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12281                synchronized (this) {
12282                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12283                }
12284            } else {
12285                // Dumping a single activity?
12286                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12287                    pw.println("Bad activity command, or no activities match: " + cmd);
12288                    pw.println("Use -h for help.");
12289                }
12290            }
12291            if (!more) {
12292                Binder.restoreCallingIdentity(origId);
12293                return;
12294            }
12295        }
12296
12297        // No piece of data specified, dump everything.
12298        synchronized (this) {
12299            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12300            pw.println();
12301            if (dumpAll) {
12302                pw.println("-------------------------------------------------------------------------------");
12303            }
12304            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12305            pw.println();
12306            if (dumpAll) {
12307                pw.println("-------------------------------------------------------------------------------");
12308            }
12309            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12310            pw.println();
12311            if (dumpAll) {
12312                pw.println("-------------------------------------------------------------------------------");
12313            }
12314            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12315            pw.println();
12316            if (dumpAll) {
12317                pw.println("-------------------------------------------------------------------------------");
12318            }
12319            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12320            pw.println();
12321            if (dumpAll) {
12322                pw.println("-------------------------------------------------------------------------------");
12323            }
12324            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12325            pw.println();
12326            if (dumpAll) {
12327                pw.println("-------------------------------------------------------------------------------");
12328            }
12329            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12330        }
12331        Binder.restoreCallingIdentity(origId);
12332    }
12333
12334    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12335            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12336        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12337
12338        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12339                dumpPackage);
12340        boolean needSep = printedAnything;
12341
12342        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12343                dumpPackage, needSep, "  mFocusedActivity: ");
12344        if (printed) {
12345            printedAnything = true;
12346            needSep = false;
12347        }
12348
12349        if (dumpPackage == null) {
12350            if (needSep) {
12351                pw.println();
12352            }
12353            needSep = true;
12354            printedAnything = true;
12355            mStackSupervisor.dump(pw, "  ");
12356        }
12357
12358        if (!printedAnything) {
12359            pw.println("  (nothing)");
12360        }
12361    }
12362
12363    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12364            int opti, boolean dumpAll, String dumpPackage) {
12365        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
12366
12367        boolean printedAnything = false;
12368
12369        if (mRecentTasks.size() > 0) {
12370            boolean printedHeader = false;
12371
12372            final int N = mRecentTasks.size();
12373            for (int i=0; i<N; i++) {
12374                TaskRecord tr = mRecentTasks.get(i);
12375                if (dumpPackage != null) {
12376                    if (tr.realActivity == null ||
12377                            !dumpPackage.equals(tr.realActivity)) {
12378                        continue;
12379                    }
12380                }
12381                if (!printedHeader) {
12382                    pw.println("  Recent tasks:");
12383                    printedHeader = true;
12384                    printedAnything = true;
12385                }
12386                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12387                        pw.println(tr);
12388                if (dumpAll) {
12389                    mRecentTasks.get(i).dump(pw, "    ");
12390                }
12391            }
12392        }
12393
12394        if (!printedAnything) {
12395            pw.println("  (nothing)");
12396        }
12397    }
12398
12399    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12400            int opti, boolean dumpAll, String dumpPackage) {
12401        boolean needSep = false;
12402        boolean printedAnything = false;
12403        int numPers = 0;
12404
12405        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12406
12407        if (dumpAll) {
12408            final int NP = mProcessNames.getMap().size();
12409            for (int ip=0; ip<NP; ip++) {
12410                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12411                final int NA = procs.size();
12412                for (int ia=0; ia<NA; ia++) {
12413                    ProcessRecord r = procs.valueAt(ia);
12414                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12415                        continue;
12416                    }
12417                    if (!needSep) {
12418                        pw.println("  All known processes:");
12419                        needSep = true;
12420                        printedAnything = true;
12421                    }
12422                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12423                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12424                        pw.print(" "); pw.println(r);
12425                    r.dump(pw, "    ");
12426                    if (r.persistent) {
12427                        numPers++;
12428                    }
12429                }
12430            }
12431        }
12432
12433        if (mIsolatedProcesses.size() > 0) {
12434            boolean printed = false;
12435            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12436                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12437                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12438                    continue;
12439                }
12440                if (!printed) {
12441                    if (needSep) {
12442                        pw.println();
12443                    }
12444                    pw.println("  Isolated process list (sorted by uid):");
12445                    printedAnything = true;
12446                    printed = true;
12447                    needSep = true;
12448                }
12449                pw.println(String.format("%sIsolated #%2d: %s",
12450                        "    ", i, r.toString()));
12451            }
12452        }
12453
12454        if (mLruProcesses.size() > 0) {
12455            if (needSep) {
12456                pw.println();
12457            }
12458            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12459                    pw.print(" total, non-act at ");
12460                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12461                    pw.print(", non-svc at ");
12462                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12463                    pw.println("):");
12464            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12465            needSep = true;
12466            printedAnything = true;
12467        }
12468
12469        if (dumpAll || dumpPackage != null) {
12470            synchronized (mPidsSelfLocked) {
12471                boolean printed = false;
12472                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12473                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12474                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12475                        continue;
12476                    }
12477                    if (!printed) {
12478                        if (needSep) pw.println();
12479                        needSep = true;
12480                        pw.println("  PID mappings:");
12481                        printed = true;
12482                        printedAnything = true;
12483                    }
12484                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12485                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12486                }
12487            }
12488        }
12489
12490        if (mForegroundProcesses.size() > 0) {
12491            synchronized (mPidsSelfLocked) {
12492                boolean printed = false;
12493                for (int i=0; i<mForegroundProcesses.size(); i++) {
12494                    ProcessRecord r = mPidsSelfLocked.get(
12495                            mForegroundProcesses.valueAt(i).pid);
12496                    if (dumpPackage != null && (r == null
12497                            || !r.pkgList.containsKey(dumpPackage))) {
12498                        continue;
12499                    }
12500                    if (!printed) {
12501                        if (needSep) pw.println();
12502                        needSep = true;
12503                        pw.println("  Foreground Processes:");
12504                        printed = true;
12505                        printedAnything = true;
12506                    }
12507                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12508                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12509                }
12510            }
12511        }
12512
12513        if (mPersistentStartingProcesses.size() > 0) {
12514            if (needSep) pw.println();
12515            needSep = true;
12516            printedAnything = true;
12517            pw.println("  Persisent processes that are starting:");
12518            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12519                    "Starting Norm", "Restarting PERS", dumpPackage);
12520        }
12521
12522        if (mRemovedProcesses.size() > 0) {
12523            if (needSep) pw.println();
12524            needSep = true;
12525            printedAnything = true;
12526            pw.println("  Processes that are being removed:");
12527            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12528                    "Removed Norm", "Removed PERS", dumpPackage);
12529        }
12530
12531        if (mProcessesOnHold.size() > 0) {
12532            if (needSep) pw.println();
12533            needSep = true;
12534            printedAnything = true;
12535            pw.println("  Processes that are on old until the system is ready:");
12536            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12537                    "OnHold Norm", "OnHold PERS", dumpPackage);
12538        }
12539
12540        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12541
12542        if (mProcessCrashTimes.getMap().size() > 0) {
12543            boolean printed = false;
12544            long now = SystemClock.uptimeMillis();
12545            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12546            final int NP = pmap.size();
12547            for (int ip=0; ip<NP; ip++) {
12548                String pname = pmap.keyAt(ip);
12549                SparseArray<Long> uids = pmap.valueAt(ip);
12550                final int N = uids.size();
12551                for (int i=0; i<N; i++) {
12552                    int puid = uids.keyAt(i);
12553                    ProcessRecord r = mProcessNames.get(pname, puid);
12554                    if (dumpPackage != null && (r == null
12555                            || !r.pkgList.containsKey(dumpPackage))) {
12556                        continue;
12557                    }
12558                    if (!printed) {
12559                        if (needSep) pw.println();
12560                        needSep = true;
12561                        pw.println("  Time since processes crashed:");
12562                        printed = true;
12563                        printedAnything = true;
12564                    }
12565                    pw.print("    Process "); pw.print(pname);
12566                            pw.print(" uid "); pw.print(puid);
12567                            pw.print(": last crashed ");
12568                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12569                            pw.println(" ago");
12570                }
12571            }
12572        }
12573
12574        if (mBadProcesses.getMap().size() > 0) {
12575            boolean printed = false;
12576            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12577            final int NP = pmap.size();
12578            for (int ip=0; ip<NP; ip++) {
12579                String pname = pmap.keyAt(ip);
12580                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12581                final int N = uids.size();
12582                for (int i=0; i<N; i++) {
12583                    int puid = uids.keyAt(i);
12584                    ProcessRecord r = mProcessNames.get(pname, puid);
12585                    if (dumpPackage != null && (r == null
12586                            || !r.pkgList.containsKey(dumpPackage))) {
12587                        continue;
12588                    }
12589                    if (!printed) {
12590                        if (needSep) pw.println();
12591                        needSep = true;
12592                        pw.println("  Bad processes:");
12593                        printedAnything = true;
12594                    }
12595                    BadProcessInfo info = uids.valueAt(i);
12596                    pw.print("    Bad process "); pw.print(pname);
12597                            pw.print(" uid "); pw.print(puid);
12598                            pw.print(": crashed at time "); pw.println(info.time);
12599                    if (info.shortMsg != null) {
12600                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12601                    }
12602                    if (info.longMsg != null) {
12603                        pw.print("      Long msg: "); pw.println(info.longMsg);
12604                    }
12605                    if (info.stack != null) {
12606                        pw.println("      Stack:");
12607                        int lastPos = 0;
12608                        for (int pos=0; pos<info.stack.length(); pos++) {
12609                            if (info.stack.charAt(pos) == '\n') {
12610                                pw.print("        ");
12611                                pw.write(info.stack, lastPos, pos-lastPos);
12612                                pw.println();
12613                                lastPos = pos+1;
12614                            }
12615                        }
12616                        if (lastPos < info.stack.length()) {
12617                            pw.print("        ");
12618                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12619                            pw.println();
12620                        }
12621                    }
12622                }
12623            }
12624        }
12625
12626        if (dumpPackage == null) {
12627            pw.println();
12628            needSep = false;
12629            pw.println("  mStartedUsers:");
12630            for (int i=0; i<mStartedUsers.size(); i++) {
12631                UserStartedState uss = mStartedUsers.valueAt(i);
12632                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12633                        pw.print(": "); uss.dump("", pw);
12634            }
12635            pw.print("  mStartedUserArray: [");
12636            for (int i=0; i<mStartedUserArray.length; i++) {
12637                if (i > 0) pw.print(", ");
12638                pw.print(mStartedUserArray[i]);
12639            }
12640            pw.println("]");
12641            pw.print("  mUserLru: [");
12642            for (int i=0; i<mUserLru.size(); i++) {
12643                if (i > 0) pw.print(", ");
12644                pw.print(mUserLru.get(i));
12645            }
12646            pw.println("]");
12647            if (dumpAll) {
12648                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12649            }
12650            synchronized (mUserProfileGroupIdsSelfLocked) {
12651                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12652                    pw.println("  mUserProfileGroupIds:");
12653                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12654                        pw.print("    User #");
12655                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12656                        pw.print(" -> profile #");
12657                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12658                    }
12659                }
12660            }
12661        }
12662        if (mHomeProcess != null && (dumpPackage == null
12663                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12664            if (needSep) {
12665                pw.println();
12666                needSep = false;
12667            }
12668            pw.println("  mHomeProcess: " + mHomeProcess);
12669        }
12670        if (mPreviousProcess != null && (dumpPackage == null
12671                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12672            if (needSep) {
12673                pw.println();
12674                needSep = false;
12675            }
12676            pw.println("  mPreviousProcess: " + mPreviousProcess);
12677        }
12678        if (dumpAll) {
12679            StringBuilder sb = new StringBuilder(128);
12680            sb.append("  mPreviousProcessVisibleTime: ");
12681            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12682            pw.println(sb);
12683        }
12684        if (mHeavyWeightProcess != null && (dumpPackage == null
12685                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12686            if (needSep) {
12687                pw.println();
12688                needSep = false;
12689            }
12690            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12691        }
12692        if (dumpPackage == null) {
12693            pw.println("  mConfiguration: " + mConfiguration);
12694        }
12695        if (dumpAll) {
12696            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12697            if (mCompatModePackages.getPackages().size() > 0) {
12698                boolean printed = false;
12699                for (Map.Entry<String, Integer> entry
12700                        : mCompatModePackages.getPackages().entrySet()) {
12701                    String pkg = entry.getKey();
12702                    int mode = entry.getValue();
12703                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12704                        continue;
12705                    }
12706                    if (!printed) {
12707                        pw.println("  mScreenCompatPackages:");
12708                        printed = true;
12709                    }
12710                    pw.print("    "); pw.print(pkg); pw.print(": ");
12711                            pw.print(mode); pw.println();
12712                }
12713            }
12714        }
12715        if (dumpPackage == null) {
12716            if (mSleeping || mWentToSleep || mLockScreenShown) {
12717                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12718                        + " mLockScreenShown " + mLockScreenShown);
12719            }
12720            if (mShuttingDown || mRunningVoice) {
12721                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12722            }
12723        }
12724        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12725                || mOrigWaitForDebugger) {
12726            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12727                    || dumpPackage.equals(mOrigDebugApp)) {
12728                if (needSep) {
12729                    pw.println();
12730                    needSep = false;
12731                }
12732                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12733                        + " mDebugTransient=" + mDebugTransient
12734                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12735            }
12736        }
12737        if (mOpenGlTraceApp != null) {
12738            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12739                if (needSep) {
12740                    pw.println();
12741                    needSep = false;
12742                }
12743                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12744            }
12745        }
12746        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12747                || mProfileFd != null) {
12748            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12749                if (needSep) {
12750                    pw.println();
12751                    needSep = false;
12752                }
12753                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12754                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12755                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12756                        + mAutoStopProfiler);
12757                pw.println("  mProfileType=" + mProfileType);
12758            }
12759        }
12760        if (dumpPackage == null) {
12761            if (mAlwaysFinishActivities || mController != null) {
12762                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12763                        + " mController=" + mController);
12764            }
12765            if (dumpAll) {
12766                pw.println("  Total persistent processes: " + numPers);
12767                pw.println("  mProcessesReady=" + mProcessesReady
12768                        + " mSystemReady=" + mSystemReady);
12769                pw.println("  mBooting=" + mBooting
12770                        + " mBooted=" + mBooted
12771                        + " mFactoryTest=" + mFactoryTest);
12772                pw.print("  mLastPowerCheckRealtime=");
12773                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12774                        pw.println("");
12775                pw.print("  mLastPowerCheckUptime=");
12776                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12777                        pw.println("");
12778                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12779                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12780                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12781                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12782                        + " (" + mLruProcesses.size() + " total)"
12783                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12784                        + " mNumServiceProcs=" + mNumServiceProcs
12785                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12786                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12787                        + " mLastMemoryLevel" + mLastMemoryLevel
12788                        + " mLastNumProcesses" + mLastNumProcesses);
12789                long now = SystemClock.uptimeMillis();
12790                pw.print("  mLastIdleTime=");
12791                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12792                        pw.print(" mLowRamSinceLastIdle=");
12793                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12794                        pw.println();
12795            }
12796        }
12797
12798        if (!printedAnything) {
12799            pw.println("  (nothing)");
12800        }
12801    }
12802
12803    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12804            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12805        if (mProcessesToGc.size() > 0) {
12806            boolean printed = false;
12807            long now = SystemClock.uptimeMillis();
12808            for (int i=0; i<mProcessesToGc.size(); i++) {
12809                ProcessRecord proc = mProcessesToGc.get(i);
12810                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12811                    continue;
12812                }
12813                if (!printed) {
12814                    if (needSep) pw.println();
12815                    needSep = true;
12816                    pw.println("  Processes that are waiting to GC:");
12817                    printed = true;
12818                }
12819                pw.print("    Process "); pw.println(proc);
12820                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12821                        pw.print(", last gced=");
12822                        pw.print(now-proc.lastRequestedGc);
12823                        pw.print(" ms ago, last lowMem=");
12824                        pw.print(now-proc.lastLowMemory);
12825                        pw.println(" ms ago");
12826
12827            }
12828        }
12829        return needSep;
12830    }
12831
12832    void printOomLevel(PrintWriter pw, String name, int adj) {
12833        pw.print("    ");
12834        if (adj >= 0) {
12835            pw.print(' ');
12836            if (adj < 10) pw.print(' ');
12837        } else {
12838            if (adj > -10) pw.print(' ');
12839        }
12840        pw.print(adj);
12841        pw.print(": ");
12842        pw.print(name);
12843        pw.print(" (");
12844        pw.print(mProcessList.getMemLevel(adj)/1024);
12845        pw.println(" kB)");
12846    }
12847
12848    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12849            int opti, boolean dumpAll) {
12850        boolean needSep = false;
12851
12852        if (mLruProcesses.size() > 0) {
12853            if (needSep) pw.println();
12854            needSep = true;
12855            pw.println("  OOM levels:");
12856            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12857            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12858            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12859            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12860            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12861            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12862            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12863            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12864            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12865            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12866            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12867            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12868            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12869
12870            if (needSep) pw.println();
12871            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12872                    pw.print(" total, non-act at ");
12873                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12874                    pw.print(", non-svc at ");
12875                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12876                    pw.println("):");
12877            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12878            needSep = true;
12879        }
12880
12881        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12882
12883        pw.println();
12884        pw.println("  mHomeProcess: " + mHomeProcess);
12885        pw.println("  mPreviousProcess: " + mPreviousProcess);
12886        if (mHeavyWeightProcess != null) {
12887            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12888        }
12889
12890        return true;
12891    }
12892
12893    /**
12894     * There are three ways to call this:
12895     *  - no provider specified: dump all the providers
12896     *  - a flattened component name that matched an existing provider was specified as the
12897     *    first arg: dump that one provider
12898     *  - the first arg isn't the flattened component name of an existing provider:
12899     *    dump all providers whose component contains the first arg as a substring
12900     */
12901    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12902            int opti, boolean dumpAll) {
12903        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12904    }
12905
12906    static class ItemMatcher {
12907        ArrayList<ComponentName> components;
12908        ArrayList<String> strings;
12909        ArrayList<Integer> objects;
12910        boolean all;
12911
12912        ItemMatcher() {
12913            all = true;
12914        }
12915
12916        void build(String name) {
12917            ComponentName componentName = ComponentName.unflattenFromString(name);
12918            if (componentName != null) {
12919                if (components == null) {
12920                    components = new ArrayList<ComponentName>();
12921                }
12922                components.add(componentName);
12923                all = false;
12924            } else {
12925                int objectId = 0;
12926                // Not a '/' separated full component name; maybe an object ID?
12927                try {
12928                    objectId = Integer.parseInt(name, 16);
12929                    if (objects == null) {
12930                        objects = new ArrayList<Integer>();
12931                    }
12932                    objects.add(objectId);
12933                    all = false;
12934                } catch (RuntimeException e) {
12935                    // Not an integer; just do string match.
12936                    if (strings == null) {
12937                        strings = new ArrayList<String>();
12938                    }
12939                    strings.add(name);
12940                    all = false;
12941                }
12942            }
12943        }
12944
12945        int build(String[] args, int opti) {
12946            for (; opti<args.length; opti++) {
12947                String name = args[opti];
12948                if ("--".equals(name)) {
12949                    return opti+1;
12950                }
12951                build(name);
12952            }
12953            return opti;
12954        }
12955
12956        boolean match(Object object, ComponentName comp) {
12957            if (all) {
12958                return true;
12959            }
12960            if (components != null) {
12961                for (int i=0; i<components.size(); i++) {
12962                    if (components.get(i).equals(comp)) {
12963                        return true;
12964                    }
12965                }
12966            }
12967            if (objects != null) {
12968                for (int i=0; i<objects.size(); i++) {
12969                    if (System.identityHashCode(object) == objects.get(i)) {
12970                        return true;
12971                    }
12972                }
12973            }
12974            if (strings != null) {
12975                String flat = comp.flattenToString();
12976                for (int i=0; i<strings.size(); i++) {
12977                    if (flat.contains(strings.get(i))) {
12978                        return true;
12979                    }
12980                }
12981            }
12982            return false;
12983        }
12984    }
12985
12986    /**
12987     * There are three things that cmd can be:
12988     *  - a flattened component name that matches an existing activity
12989     *  - the cmd arg isn't the flattened component name of an existing activity:
12990     *    dump all activity whose component contains the cmd as a substring
12991     *  - A hex number of the ActivityRecord object instance.
12992     */
12993    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12994            int opti, boolean dumpAll) {
12995        ArrayList<ActivityRecord> activities;
12996
12997        synchronized (this) {
12998            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12999        }
13000
13001        if (activities.size() <= 0) {
13002            return false;
13003        }
13004
13005        String[] newArgs = new String[args.length - opti];
13006        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13007
13008        TaskRecord lastTask = null;
13009        boolean needSep = false;
13010        for (int i=activities.size()-1; i>=0; i--) {
13011            ActivityRecord r = activities.get(i);
13012            if (needSep) {
13013                pw.println();
13014            }
13015            needSep = true;
13016            synchronized (this) {
13017                if (lastTask != r.task) {
13018                    lastTask = r.task;
13019                    pw.print("TASK "); pw.print(lastTask.affinity);
13020                            pw.print(" id="); pw.println(lastTask.taskId);
13021                    if (dumpAll) {
13022                        lastTask.dump(pw, "  ");
13023                    }
13024                }
13025            }
13026            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13027        }
13028        return true;
13029    }
13030
13031    /**
13032     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13033     * there is a thread associated with the activity.
13034     */
13035    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13036            final ActivityRecord r, String[] args, boolean dumpAll) {
13037        String innerPrefix = prefix + "  ";
13038        synchronized (this) {
13039            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13040                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13041                    pw.print(" pid=");
13042                    if (r.app != null) pw.println(r.app.pid);
13043                    else pw.println("(not running)");
13044            if (dumpAll) {
13045                r.dump(pw, innerPrefix);
13046            }
13047        }
13048        if (r.app != null && r.app.thread != null) {
13049            // flush anything that is already in the PrintWriter since the thread is going
13050            // to write to the file descriptor directly
13051            pw.flush();
13052            try {
13053                TransferPipe tp = new TransferPipe();
13054                try {
13055                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13056                            r.appToken, innerPrefix, args);
13057                    tp.go(fd);
13058                } finally {
13059                    tp.kill();
13060                }
13061            } catch (IOException e) {
13062                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13063            } catch (RemoteException e) {
13064                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13065            }
13066        }
13067    }
13068
13069    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13070            int opti, boolean dumpAll, String dumpPackage) {
13071        boolean needSep = false;
13072        boolean onlyHistory = false;
13073        boolean printedAnything = false;
13074
13075        if ("history".equals(dumpPackage)) {
13076            if (opti < args.length && "-s".equals(args[opti])) {
13077                dumpAll = false;
13078            }
13079            onlyHistory = true;
13080            dumpPackage = null;
13081        }
13082
13083        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13084        if (!onlyHistory && dumpAll) {
13085            if (mRegisteredReceivers.size() > 0) {
13086                boolean printed = false;
13087                Iterator it = mRegisteredReceivers.values().iterator();
13088                while (it.hasNext()) {
13089                    ReceiverList r = (ReceiverList)it.next();
13090                    if (dumpPackage != null && (r.app == null ||
13091                            !dumpPackage.equals(r.app.info.packageName))) {
13092                        continue;
13093                    }
13094                    if (!printed) {
13095                        pw.println("  Registered Receivers:");
13096                        needSep = true;
13097                        printed = true;
13098                        printedAnything = true;
13099                    }
13100                    pw.print("  * "); pw.println(r);
13101                    r.dump(pw, "    ");
13102                }
13103            }
13104
13105            if (mReceiverResolver.dump(pw, needSep ?
13106                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13107                    "    ", dumpPackage, false)) {
13108                needSep = true;
13109                printedAnything = true;
13110            }
13111        }
13112
13113        for (BroadcastQueue q : mBroadcastQueues) {
13114            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13115            printedAnything |= needSep;
13116        }
13117
13118        needSep = true;
13119
13120        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13121            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13122                if (needSep) {
13123                    pw.println();
13124                }
13125                needSep = true;
13126                printedAnything = true;
13127                pw.print("  Sticky broadcasts for user ");
13128                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13129                StringBuilder sb = new StringBuilder(128);
13130                for (Map.Entry<String, ArrayList<Intent>> ent
13131                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13132                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13133                    if (dumpAll) {
13134                        pw.println(":");
13135                        ArrayList<Intent> intents = ent.getValue();
13136                        final int N = intents.size();
13137                        for (int i=0; i<N; i++) {
13138                            sb.setLength(0);
13139                            sb.append("    Intent: ");
13140                            intents.get(i).toShortString(sb, false, true, false, false);
13141                            pw.println(sb.toString());
13142                            Bundle bundle = intents.get(i).getExtras();
13143                            if (bundle != null) {
13144                                pw.print("      ");
13145                                pw.println(bundle.toString());
13146                            }
13147                        }
13148                    } else {
13149                        pw.println("");
13150                    }
13151                }
13152            }
13153        }
13154
13155        if (!onlyHistory && dumpAll) {
13156            pw.println();
13157            for (BroadcastQueue queue : mBroadcastQueues) {
13158                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13159                        + queue.mBroadcastsScheduled);
13160            }
13161            pw.println("  mHandler:");
13162            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13163            needSep = true;
13164            printedAnything = true;
13165        }
13166
13167        if (!printedAnything) {
13168            pw.println("  (nothing)");
13169        }
13170    }
13171
13172    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13173            int opti, boolean dumpAll, String dumpPackage) {
13174        boolean needSep;
13175        boolean printedAnything = false;
13176
13177        ItemMatcher matcher = new ItemMatcher();
13178        matcher.build(args, opti);
13179
13180        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13181
13182        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13183        printedAnything |= needSep;
13184
13185        if (mLaunchingProviders.size() > 0) {
13186            boolean printed = false;
13187            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13188                ContentProviderRecord r = mLaunchingProviders.get(i);
13189                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13190                    continue;
13191                }
13192                if (!printed) {
13193                    if (needSep) pw.println();
13194                    needSep = true;
13195                    pw.println("  Launching content providers:");
13196                    printed = true;
13197                    printedAnything = true;
13198                }
13199                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13200                        pw.println(r);
13201            }
13202        }
13203
13204        if (mGrantedUriPermissions.size() > 0) {
13205            boolean printed = false;
13206            int dumpUid = -2;
13207            if (dumpPackage != null) {
13208                try {
13209                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13210                } catch (NameNotFoundException e) {
13211                    dumpUid = -1;
13212                }
13213            }
13214            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13215                int uid = mGrantedUriPermissions.keyAt(i);
13216                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13217                    continue;
13218                }
13219                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13220                if (!printed) {
13221                    if (needSep) pw.println();
13222                    needSep = true;
13223                    pw.println("  Granted Uri Permissions:");
13224                    printed = true;
13225                    printedAnything = true;
13226                }
13227                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13228                for (UriPermission perm : perms.values()) {
13229                    pw.print("    "); pw.println(perm);
13230                    if (dumpAll) {
13231                        perm.dump(pw, "      ");
13232                    }
13233                }
13234            }
13235        }
13236
13237        if (!printedAnything) {
13238            pw.println("  (nothing)");
13239        }
13240    }
13241
13242    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13243            int opti, boolean dumpAll, String dumpPackage) {
13244        boolean printed = false;
13245
13246        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13247
13248        if (mIntentSenderRecords.size() > 0) {
13249            Iterator<WeakReference<PendingIntentRecord>> it
13250                    = mIntentSenderRecords.values().iterator();
13251            while (it.hasNext()) {
13252                WeakReference<PendingIntentRecord> ref = it.next();
13253                PendingIntentRecord rec = ref != null ? ref.get(): null;
13254                if (dumpPackage != null && (rec == null
13255                        || !dumpPackage.equals(rec.key.packageName))) {
13256                    continue;
13257                }
13258                printed = true;
13259                if (rec != null) {
13260                    pw.print("  * "); pw.println(rec);
13261                    if (dumpAll) {
13262                        rec.dump(pw, "    ");
13263                    }
13264                } else {
13265                    pw.print("  * "); pw.println(ref);
13266                }
13267            }
13268        }
13269
13270        if (!printed) {
13271            pw.println("  (nothing)");
13272        }
13273    }
13274
13275    private static final int dumpProcessList(PrintWriter pw,
13276            ActivityManagerService service, List list,
13277            String prefix, String normalLabel, String persistentLabel,
13278            String dumpPackage) {
13279        int numPers = 0;
13280        final int N = list.size()-1;
13281        for (int i=N; i>=0; i--) {
13282            ProcessRecord r = (ProcessRecord)list.get(i);
13283            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13284                continue;
13285            }
13286            pw.println(String.format("%s%s #%2d: %s",
13287                    prefix, (r.persistent ? persistentLabel : normalLabel),
13288                    i, r.toString()));
13289            if (r.persistent) {
13290                numPers++;
13291            }
13292        }
13293        return numPers;
13294    }
13295
13296    private static final boolean dumpProcessOomList(PrintWriter pw,
13297            ActivityManagerService service, List<ProcessRecord> origList,
13298            String prefix, String normalLabel, String persistentLabel,
13299            boolean inclDetails, String dumpPackage) {
13300
13301        ArrayList<Pair<ProcessRecord, Integer>> list
13302                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13303        for (int i=0; i<origList.size(); i++) {
13304            ProcessRecord r = origList.get(i);
13305            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13306                continue;
13307            }
13308            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13309        }
13310
13311        if (list.size() <= 0) {
13312            return false;
13313        }
13314
13315        Comparator<Pair<ProcessRecord, Integer>> comparator
13316                = new Comparator<Pair<ProcessRecord, Integer>>() {
13317            @Override
13318            public int compare(Pair<ProcessRecord, Integer> object1,
13319                    Pair<ProcessRecord, Integer> object2) {
13320                if (object1.first.setAdj != object2.first.setAdj) {
13321                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13322                }
13323                if (object1.second.intValue() != object2.second.intValue()) {
13324                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13325                }
13326                return 0;
13327            }
13328        };
13329
13330        Collections.sort(list, comparator);
13331
13332        final long curRealtime = SystemClock.elapsedRealtime();
13333        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13334        final long curUptime = SystemClock.uptimeMillis();
13335        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13336
13337        for (int i=list.size()-1; i>=0; i--) {
13338            ProcessRecord r = list.get(i).first;
13339            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13340            char schedGroup;
13341            switch (r.setSchedGroup) {
13342                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13343                    schedGroup = 'B';
13344                    break;
13345                case Process.THREAD_GROUP_DEFAULT:
13346                    schedGroup = 'F';
13347                    break;
13348                default:
13349                    schedGroup = '?';
13350                    break;
13351            }
13352            char foreground;
13353            if (r.foregroundActivities) {
13354                foreground = 'A';
13355            } else if (r.foregroundServices) {
13356                foreground = 'S';
13357            } else {
13358                foreground = ' ';
13359            }
13360            String procState = ProcessList.makeProcStateString(r.curProcState);
13361            pw.print(prefix);
13362            pw.print(r.persistent ? persistentLabel : normalLabel);
13363            pw.print(" #");
13364            int num = (origList.size()-1)-list.get(i).second;
13365            if (num < 10) pw.print(' ');
13366            pw.print(num);
13367            pw.print(": ");
13368            pw.print(oomAdj);
13369            pw.print(' ');
13370            pw.print(schedGroup);
13371            pw.print('/');
13372            pw.print(foreground);
13373            pw.print('/');
13374            pw.print(procState);
13375            pw.print(" trm:");
13376            if (r.trimMemoryLevel < 10) pw.print(' ');
13377            pw.print(r.trimMemoryLevel);
13378            pw.print(' ');
13379            pw.print(r.toShortString());
13380            pw.print(" (");
13381            pw.print(r.adjType);
13382            pw.println(')');
13383            if (r.adjSource != null || r.adjTarget != null) {
13384                pw.print(prefix);
13385                pw.print("    ");
13386                if (r.adjTarget instanceof ComponentName) {
13387                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13388                } else if (r.adjTarget != null) {
13389                    pw.print(r.adjTarget.toString());
13390                } else {
13391                    pw.print("{null}");
13392                }
13393                pw.print("<=");
13394                if (r.adjSource instanceof ProcessRecord) {
13395                    pw.print("Proc{");
13396                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13397                    pw.println("}");
13398                } else if (r.adjSource != null) {
13399                    pw.println(r.adjSource.toString());
13400                } else {
13401                    pw.println("{null}");
13402                }
13403            }
13404            if (inclDetails) {
13405                pw.print(prefix);
13406                pw.print("    ");
13407                pw.print("oom: max="); pw.print(r.maxAdj);
13408                pw.print(" curRaw="); pw.print(r.curRawAdj);
13409                pw.print(" setRaw="); pw.print(r.setRawAdj);
13410                pw.print(" cur="); pw.print(r.curAdj);
13411                pw.print(" set="); pw.println(r.setAdj);
13412                pw.print(prefix);
13413                pw.print("    ");
13414                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13415                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13416                pw.print(" lastPss="); pw.print(r.lastPss);
13417                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13418                pw.print(prefix);
13419                pw.print("    ");
13420                pw.print("cached="); pw.print(r.cached);
13421                pw.print(" empty="); pw.print(r.empty);
13422                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13423
13424                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13425                    if (r.lastWakeTime != 0) {
13426                        long wtime;
13427                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13428                        synchronized (stats) {
13429                            wtime = stats.getProcessWakeTime(r.info.uid,
13430                                    r.pid, curRealtime);
13431                        }
13432                        long timeUsed = wtime - r.lastWakeTime;
13433                        pw.print(prefix);
13434                        pw.print("    ");
13435                        pw.print("keep awake over ");
13436                        TimeUtils.formatDuration(realtimeSince, pw);
13437                        pw.print(" used ");
13438                        TimeUtils.formatDuration(timeUsed, pw);
13439                        pw.print(" (");
13440                        pw.print((timeUsed*100)/realtimeSince);
13441                        pw.println("%)");
13442                    }
13443                    if (r.lastCpuTime != 0) {
13444                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13445                        pw.print(prefix);
13446                        pw.print("    ");
13447                        pw.print("run cpu over ");
13448                        TimeUtils.formatDuration(uptimeSince, pw);
13449                        pw.print(" used ");
13450                        TimeUtils.formatDuration(timeUsed, pw);
13451                        pw.print(" (");
13452                        pw.print((timeUsed*100)/uptimeSince);
13453                        pw.println("%)");
13454                    }
13455                }
13456            }
13457        }
13458        return true;
13459    }
13460
13461    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
13462        ArrayList<ProcessRecord> procs;
13463        synchronized (this) {
13464            if (args != null && args.length > start
13465                    && args[start].charAt(0) != '-') {
13466                procs = new ArrayList<ProcessRecord>();
13467                int pid = -1;
13468                try {
13469                    pid = Integer.parseInt(args[start]);
13470                } catch (NumberFormatException e) {
13471                }
13472                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13473                    ProcessRecord proc = mLruProcesses.get(i);
13474                    if (proc.pid == pid) {
13475                        procs.add(proc);
13476                    } else if (proc.processName.equals(args[start])) {
13477                        procs.add(proc);
13478                    }
13479                }
13480                if (procs.size() <= 0) {
13481                    return null;
13482                }
13483            } else {
13484                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13485            }
13486        }
13487        return procs;
13488    }
13489
13490    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13491            PrintWriter pw, String[] args) {
13492        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13493        if (procs == null) {
13494            pw.println("No process found for: " + args[0]);
13495            return;
13496        }
13497
13498        long uptime = SystemClock.uptimeMillis();
13499        long realtime = SystemClock.elapsedRealtime();
13500        pw.println("Applications Graphics Acceleration Info:");
13501        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13502
13503        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13504            ProcessRecord r = procs.get(i);
13505            if (r.thread != null) {
13506                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13507                pw.flush();
13508                try {
13509                    TransferPipe tp = new TransferPipe();
13510                    try {
13511                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13512                        tp.go(fd);
13513                    } finally {
13514                        tp.kill();
13515                    }
13516                } catch (IOException e) {
13517                    pw.println("Failure while dumping the app: " + r);
13518                    pw.flush();
13519                } catch (RemoteException e) {
13520                    pw.println("Got a RemoteException while dumping the app " + r);
13521                    pw.flush();
13522                }
13523            }
13524        }
13525    }
13526
13527    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13528        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13529        if (procs == null) {
13530            pw.println("No process found for: " + args[0]);
13531            return;
13532        }
13533
13534        pw.println("Applications Database Info:");
13535
13536        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13537            ProcessRecord r = procs.get(i);
13538            if (r.thread != null) {
13539                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13540                pw.flush();
13541                try {
13542                    TransferPipe tp = new TransferPipe();
13543                    try {
13544                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13545                        tp.go(fd);
13546                    } finally {
13547                        tp.kill();
13548                    }
13549                } catch (IOException e) {
13550                    pw.println("Failure while dumping the app: " + r);
13551                    pw.flush();
13552                } catch (RemoteException e) {
13553                    pw.println("Got a RemoteException while dumping the app " + r);
13554                    pw.flush();
13555                }
13556            }
13557        }
13558    }
13559
13560    final static class MemItem {
13561        final boolean isProc;
13562        final String label;
13563        final String shortLabel;
13564        final long pss;
13565        final int id;
13566        final boolean hasActivities;
13567        ArrayList<MemItem> subitems;
13568
13569        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13570                boolean _hasActivities) {
13571            isProc = true;
13572            label = _label;
13573            shortLabel = _shortLabel;
13574            pss = _pss;
13575            id = _id;
13576            hasActivities = _hasActivities;
13577        }
13578
13579        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13580            isProc = false;
13581            label = _label;
13582            shortLabel = _shortLabel;
13583            pss = _pss;
13584            id = _id;
13585            hasActivities = false;
13586        }
13587    }
13588
13589    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13590            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13591        if (sort && !isCompact) {
13592            Collections.sort(items, new Comparator<MemItem>() {
13593                @Override
13594                public int compare(MemItem lhs, MemItem rhs) {
13595                    if (lhs.pss < rhs.pss) {
13596                        return 1;
13597                    } else if (lhs.pss > rhs.pss) {
13598                        return -1;
13599                    }
13600                    return 0;
13601                }
13602            });
13603        }
13604
13605        for (int i=0; i<items.size(); i++) {
13606            MemItem mi = items.get(i);
13607            if (!isCompact) {
13608                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13609            } else if (mi.isProc) {
13610                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13611                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13612                pw.println(mi.hasActivities ? ",a" : ",e");
13613            } else {
13614                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13615                pw.println(mi.pss);
13616            }
13617            if (mi.subitems != null) {
13618                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13619                        true, isCompact);
13620            }
13621        }
13622    }
13623
13624    // These are in KB.
13625    static final long[] DUMP_MEM_BUCKETS = new long[] {
13626        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13627        120*1024, 160*1024, 200*1024,
13628        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13629        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13630    };
13631
13632    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13633            boolean stackLike) {
13634        int start = label.lastIndexOf('.');
13635        if (start >= 0) start++;
13636        else start = 0;
13637        int end = label.length();
13638        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13639            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13640                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13641                out.append(bucket);
13642                out.append(stackLike ? "MB." : "MB ");
13643                out.append(label, start, end);
13644                return;
13645            }
13646        }
13647        out.append(memKB/1024);
13648        out.append(stackLike ? "MB." : "MB ");
13649        out.append(label, start, end);
13650    }
13651
13652    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13653            ProcessList.NATIVE_ADJ,
13654            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13655            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13656            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13657            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13658            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13659    };
13660    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13661            "Native",
13662            "System", "Persistent", "Foreground",
13663            "Visible", "Perceptible",
13664            "Heavy Weight", "Backup",
13665            "A Services", "Home",
13666            "Previous", "B Services", "Cached"
13667    };
13668    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13669            "native",
13670            "sys", "pers", "fore",
13671            "vis", "percept",
13672            "heavy", "backup",
13673            "servicea", "home",
13674            "prev", "serviceb", "cached"
13675    };
13676
13677    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13678            long realtime, boolean isCheckinRequest, boolean isCompact) {
13679        if (isCheckinRequest || isCompact) {
13680            // short checkin version
13681            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13682        } else {
13683            pw.println("Applications Memory Usage (kB):");
13684            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13685        }
13686    }
13687
13688    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13689            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13690        boolean dumpDetails = false;
13691        boolean dumpFullDetails = false;
13692        boolean dumpDalvik = false;
13693        boolean oomOnly = false;
13694        boolean isCompact = false;
13695        boolean localOnly = false;
13696
13697        int opti = 0;
13698        while (opti < args.length) {
13699            String opt = args[opti];
13700            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13701                break;
13702            }
13703            opti++;
13704            if ("-a".equals(opt)) {
13705                dumpDetails = true;
13706                dumpFullDetails = true;
13707                dumpDalvik = true;
13708            } else if ("-d".equals(opt)) {
13709                dumpDalvik = true;
13710            } else if ("-c".equals(opt)) {
13711                isCompact = true;
13712            } else if ("--oom".equals(opt)) {
13713                oomOnly = true;
13714            } else if ("--local".equals(opt)) {
13715                localOnly = true;
13716            } else if ("-h".equals(opt)) {
13717                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13718                pw.println("  -a: include all available information for each process.");
13719                pw.println("  -d: include dalvik details when dumping process details.");
13720                pw.println("  -c: dump in a compact machine-parseable representation.");
13721                pw.println("  --oom: only show processes organized by oom adj.");
13722                pw.println("  --local: only collect details locally, don't call process.");
13723                pw.println("If [process] is specified it can be the name or ");
13724                pw.println("pid of a specific process to dump.");
13725                return;
13726            } else {
13727                pw.println("Unknown argument: " + opt + "; use -h for help");
13728            }
13729        }
13730
13731        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13732        long uptime = SystemClock.uptimeMillis();
13733        long realtime = SystemClock.elapsedRealtime();
13734        final long[] tmpLong = new long[1];
13735
13736        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13737        if (procs == null) {
13738            // No Java processes.  Maybe they want to print a native process.
13739            if (args != null && args.length > opti
13740                    && args[opti].charAt(0) != '-') {
13741                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13742                        = new ArrayList<ProcessCpuTracker.Stats>();
13743                updateCpuStatsNow();
13744                int findPid = -1;
13745                try {
13746                    findPid = Integer.parseInt(args[opti]);
13747                } catch (NumberFormatException e) {
13748                }
13749                synchronized (mProcessCpuTracker) {
13750                    final int N = mProcessCpuTracker.countStats();
13751                    for (int i=0; i<N; i++) {
13752                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13753                        if (st.pid == findPid || (st.baseName != null
13754                                && st.baseName.equals(args[opti]))) {
13755                            nativeProcs.add(st);
13756                        }
13757                    }
13758                }
13759                if (nativeProcs.size() > 0) {
13760                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13761                            isCompact);
13762                    Debug.MemoryInfo mi = null;
13763                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13764                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13765                        final int pid = r.pid;
13766                        if (!isCheckinRequest && dumpDetails) {
13767                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13768                        }
13769                        if (mi == null) {
13770                            mi = new Debug.MemoryInfo();
13771                        }
13772                        if (dumpDetails || (!brief && !oomOnly)) {
13773                            Debug.getMemoryInfo(pid, mi);
13774                        } else {
13775                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13776                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13777                        }
13778                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13779                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13780                        if (isCheckinRequest) {
13781                            pw.println();
13782                        }
13783                    }
13784                    return;
13785                }
13786            }
13787            pw.println("No process found for: " + args[opti]);
13788            return;
13789        }
13790
13791        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13792            dumpDetails = true;
13793        }
13794
13795        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13796
13797        String[] innerArgs = new String[args.length-opti];
13798        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13799
13800        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13801        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13802        long nativePss=0, dalvikPss=0, otherPss=0;
13803        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13804
13805        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13806        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13807                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13808
13809        long totalPss = 0;
13810        long cachedPss = 0;
13811
13812        Debug.MemoryInfo mi = null;
13813        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13814            final ProcessRecord r = procs.get(i);
13815            final IApplicationThread thread;
13816            final int pid;
13817            final int oomAdj;
13818            final boolean hasActivities;
13819            synchronized (this) {
13820                thread = r.thread;
13821                pid = r.pid;
13822                oomAdj = r.getSetAdjWithServices();
13823                hasActivities = r.activities.size() > 0;
13824            }
13825            if (thread != null) {
13826                if (!isCheckinRequest && dumpDetails) {
13827                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13828                }
13829                if (mi == null) {
13830                    mi = new Debug.MemoryInfo();
13831                }
13832                if (dumpDetails || (!brief && !oomOnly)) {
13833                    Debug.getMemoryInfo(pid, mi);
13834                } else {
13835                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13836                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13837                }
13838                if (dumpDetails) {
13839                    if (localOnly) {
13840                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13841                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13842                        if (isCheckinRequest) {
13843                            pw.println();
13844                        }
13845                    } else {
13846                        try {
13847                            pw.flush();
13848                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13849                                    dumpDalvik, innerArgs);
13850                        } catch (RemoteException e) {
13851                            if (!isCheckinRequest) {
13852                                pw.println("Got RemoteException!");
13853                                pw.flush();
13854                            }
13855                        }
13856                    }
13857                }
13858
13859                final long myTotalPss = mi.getTotalPss();
13860                final long myTotalUss = mi.getTotalUss();
13861
13862                synchronized (this) {
13863                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13864                        // Record this for posterity if the process has been stable.
13865                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13866                    }
13867                }
13868
13869                if (!isCheckinRequest && mi != null) {
13870                    totalPss += myTotalPss;
13871                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13872                            (hasActivities ? " / activities)" : ")"),
13873                            r.processName, myTotalPss, pid, hasActivities);
13874                    procMems.add(pssItem);
13875                    procMemsMap.put(pid, pssItem);
13876
13877                    nativePss += mi.nativePss;
13878                    dalvikPss += mi.dalvikPss;
13879                    otherPss += mi.otherPss;
13880                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13881                        long mem = mi.getOtherPss(j);
13882                        miscPss[j] += mem;
13883                        otherPss -= mem;
13884                    }
13885
13886                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13887                        cachedPss += myTotalPss;
13888                    }
13889
13890                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13891                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13892                                || oomIndex == (oomPss.length-1)) {
13893                            oomPss[oomIndex] += myTotalPss;
13894                            if (oomProcs[oomIndex] == null) {
13895                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13896                            }
13897                            oomProcs[oomIndex].add(pssItem);
13898                            break;
13899                        }
13900                    }
13901                }
13902            }
13903        }
13904
13905        long nativeProcTotalPss = 0;
13906
13907        if (!isCheckinRequest && procs.size() > 1) {
13908            // If we are showing aggregations, also look for native processes to
13909            // include so that our aggregations are more accurate.
13910            updateCpuStatsNow();
13911            synchronized (mProcessCpuTracker) {
13912                final int N = mProcessCpuTracker.countStats();
13913                for (int i=0; i<N; i++) {
13914                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13915                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13916                        if (mi == null) {
13917                            mi = new Debug.MemoryInfo();
13918                        }
13919                        if (!brief && !oomOnly) {
13920                            Debug.getMemoryInfo(st.pid, mi);
13921                        } else {
13922                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13923                            mi.nativePrivateDirty = (int)tmpLong[0];
13924                        }
13925
13926                        final long myTotalPss = mi.getTotalPss();
13927                        totalPss += myTotalPss;
13928                        nativeProcTotalPss += myTotalPss;
13929
13930                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13931                                st.name, myTotalPss, st.pid, false);
13932                        procMems.add(pssItem);
13933
13934                        nativePss += mi.nativePss;
13935                        dalvikPss += mi.dalvikPss;
13936                        otherPss += mi.otherPss;
13937                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13938                            long mem = mi.getOtherPss(j);
13939                            miscPss[j] += mem;
13940                            otherPss -= mem;
13941                        }
13942                        oomPss[0] += myTotalPss;
13943                        if (oomProcs[0] == null) {
13944                            oomProcs[0] = new ArrayList<MemItem>();
13945                        }
13946                        oomProcs[0].add(pssItem);
13947                    }
13948                }
13949            }
13950
13951            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13952
13953            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13954            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13955            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13956            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13957                String label = Debug.MemoryInfo.getOtherLabel(j);
13958                catMems.add(new MemItem(label, label, miscPss[j], j));
13959            }
13960
13961            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13962            for (int j=0; j<oomPss.length; j++) {
13963                if (oomPss[j] != 0) {
13964                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13965                            : DUMP_MEM_OOM_LABEL[j];
13966                    MemItem item = new MemItem(label, label, oomPss[j],
13967                            DUMP_MEM_OOM_ADJ[j]);
13968                    item.subitems = oomProcs[j];
13969                    oomMems.add(item);
13970                }
13971            }
13972
13973            if (!brief && !oomOnly && !isCompact) {
13974                pw.println();
13975                pw.println("Total PSS by process:");
13976                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13977                pw.println();
13978            }
13979            if (!isCompact) {
13980                pw.println("Total PSS by OOM adjustment:");
13981            }
13982            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13983            if (!brief && !oomOnly) {
13984                PrintWriter out = categoryPw != null ? categoryPw : pw;
13985                if (!isCompact) {
13986                    out.println();
13987                    out.println("Total PSS by category:");
13988                }
13989                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13990            }
13991            if (!isCompact) {
13992                pw.println();
13993            }
13994            MemInfoReader memInfo = new MemInfoReader();
13995            memInfo.readMemInfo();
13996            if (nativeProcTotalPss > 0) {
13997                synchronized (this) {
13998                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13999                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14000                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
14001                            nativeProcTotalPss);
14002                }
14003            }
14004            if (!brief) {
14005                if (!isCompact) {
14006                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14007                    pw.print(" kB (status ");
14008                    switch (mLastMemoryLevel) {
14009                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14010                            pw.println("normal)");
14011                            break;
14012                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14013                            pw.println("moderate)");
14014                            break;
14015                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14016                            pw.println("low)");
14017                            break;
14018                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14019                            pw.println("critical)");
14020                            break;
14021                        default:
14022                            pw.print(mLastMemoryLevel);
14023                            pw.println(")");
14024                            break;
14025                    }
14026                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14027                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14028                            pw.print(cachedPss); pw.print(" cached pss + ");
14029                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
14030                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14031                } else {
14032                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14033                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14034                            + memInfo.getFreeSizeKb()); pw.print(",");
14035                    pw.println(totalPss - cachedPss);
14036                }
14037            }
14038            if (!isCompact) {
14039                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14040                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
14041                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
14042                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14043                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
14044                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
14045                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
14046                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14047                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14048                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
14049                        - memInfo.getSlabSizeKb()); pw.println(" kB");
14050            }
14051            if (!brief) {
14052                if (memInfo.getZramTotalSizeKb() != 0) {
14053                    if (!isCompact) {
14054                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14055                                pw.print(" kB physical used for ");
14056                                pw.print(memInfo.getSwapTotalSizeKb()
14057                                        - memInfo.getSwapFreeSizeKb());
14058                                pw.print(" kB in swap (");
14059                                pw.print(memInfo.getSwapTotalSizeKb());
14060                                pw.println(" kB total swap)");
14061                    } else {
14062                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14063                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14064                                pw.println(memInfo.getSwapFreeSizeKb());
14065                    }
14066                }
14067                final int[] SINGLE_LONG_FORMAT = new int[] {
14068                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14069                };
14070                long[] longOut = new long[1];
14071                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14072                        SINGLE_LONG_FORMAT, null, longOut, null);
14073                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14074                longOut[0] = 0;
14075                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14076                        SINGLE_LONG_FORMAT, null, longOut, null);
14077                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14078                longOut[0] = 0;
14079                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14080                        SINGLE_LONG_FORMAT, null, longOut, null);
14081                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14082                longOut[0] = 0;
14083                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14084                        SINGLE_LONG_FORMAT, null, longOut, null);
14085                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14086                if (!isCompact) {
14087                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
14088                        pw.print("      KSM: "); pw.print(sharing);
14089                                pw.print(" kB saved from shared ");
14090                                pw.print(shared); pw.println(" kB");
14091                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
14092                                pw.print(voltile); pw.println(" kB volatile");
14093                    }
14094                    pw.print("   Tuning: ");
14095                    pw.print(ActivityManager.staticGetMemoryClass());
14096                    pw.print(" (large ");
14097                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14098                    pw.print("), oom ");
14099                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14100                    pw.print(" kB");
14101                    pw.print(", restore limit ");
14102                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14103                    pw.print(" kB");
14104                    if (ActivityManager.isLowRamDeviceStatic()) {
14105                        pw.print(" (low-ram)");
14106                    }
14107                    if (ActivityManager.isHighEndGfx()) {
14108                        pw.print(" (high-end-gfx)");
14109                    }
14110                    pw.println();
14111                } else {
14112                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
14113                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
14114                    pw.println(voltile);
14115                    pw.print("tuning,");
14116                    pw.print(ActivityManager.staticGetMemoryClass());
14117                    pw.print(',');
14118                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14119                    pw.print(',');
14120                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14121                    if (ActivityManager.isLowRamDeviceStatic()) {
14122                        pw.print(",low-ram");
14123                    }
14124                    if (ActivityManager.isHighEndGfx()) {
14125                        pw.print(",high-end-gfx");
14126                    }
14127                    pw.println();
14128                }
14129            }
14130        }
14131    }
14132
14133    /**
14134     * Searches array of arguments for the specified string
14135     * @param args array of argument strings
14136     * @param value value to search for
14137     * @return true if the value is contained in the array
14138     */
14139    private static boolean scanArgs(String[] args, String value) {
14140        if (args != null) {
14141            for (String arg : args) {
14142                if (value.equals(arg)) {
14143                    return true;
14144                }
14145            }
14146        }
14147        return false;
14148    }
14149
14150    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14151            ContentProviderRecord cpr, boolean always) {
14152        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14153
14154        if (!inLaunching || always) {
14155            synchronized (cpr) {
14156                cpr.launchingApp = null;
14157                cpr.notifyAll();
14158            }
14159            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14160            String names[] = cpr.info.authority.split(";");
14161            for (int j = 0; j < names.length; j++) {
14162                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14163            }
14164        }
14165
14166        for (int i=0; i<cpr.connections.size(); i++) {
14167            ContentProviderConnection conn = cpr.connections.get(i);
14168            if (conn.waiting) {
14169                // If this connection is waiting for the provider, then we don't
14170                // need to mess with its process unless we are always removing
14171                // or for some reason the provider is not currently launching.
14172                if (inLaunching && !always) {
14173                    continue;
14174                }
14175            }
14176            ProcessRecord capp = conn.client;
14177            conn.dead = true;
14178            if (conn.stableCount > 0) {
14179                if (!capp.persistent && capp.thread != null
14180                        && capp.pid != 0
14181                        && capp.pid != MY_PID) {
14182                    capp.kill("depends on provider "
14183                            + cpr.name.flattenToShortString()
14184                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14185                }
14186            } else if (capp.thread != null && conn.provider.provider != null) {
14187                try {
14188                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14189                } catch (RemoteException e) {
14190                }
14191                // In the protocol here, we don't expect the client to correctly
14192                // clean up this connection, we'll just remove it.
14193                cpr.connections.remove(i);
14194                conn.client.conProviders.remove(conn);
14195            }
14196        }
14197
14198        if (inLaunching && always) {
14199            mLaunchingProviders.remove(cpr);
14200        }
14201        return inLaunching;
14202    }
14203
14204    /**
14205     * Main code for cleaning up a process when it has gone away.  This is
14206     * called both as a result of the process dying, or directly when stopping
14207     * a process when running in single process mode.
14208     */
14209    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
14210            boolean restarting, boolean allowRestart, int index) {
14211        if (index >= 0) {
14212            removeLruProcessLocked(app);
14213            ProcessList.remove(app.pid);
14214        }
14215
14216        mProcessesToGc.remove(app);
14217        mPendingPssProcesses.remove(app);
14218
14219        // Dismiss any open dialogs.
14220        if (app.crashDialog != null && !app.forceCrashReport) {
14221            app.crashDialog.dismiss();
14222            app.crashDialog = null;
14223        }
14224        if (app.anrDialog != null) {
14225            app.anrDialog.dismiss();
14226            app.anrDialog = null;
14227        }
14228        if (app.waitDialog != null) {
14229            app.waitDialog.dismiss();
14230            app.waitDialog = null;
14231        }
14232
14233        app.crashing = false;
14234        app.notResponding = false;
14235
14236        app.resetPackageList(mProcessStats);
14237        app.unlinkDeathRecipient();
14238        app.makeInactive(mProcessStats);
14239        app.waitingToKill = null;
14240        app.forcingToForeground = null;
14241        updateProcessForegroundLocked(app, false, false);
14242        app.foregroundActivities = false;
14243        app.hasShownUi = false;
14244        app.treatLikeActivity = false;
14245        app.hasAboveClient = false;
14246        app.hasClientActivities = false;
14247
14248        mServices.killServicesLocked(app, allowRestart);
14249
14250        boolean restart = false;
14251
14252        // Remove published content providers.
14253        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14254            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14255            final boolean always = app.bad || !allowRestart;
14256            if (removeDyingProviderLocked(app, cpr, always) || always) {
14257                // We left the provider in the launching list, need to
14258                // restart it.
14259                restart = true;
14260            }
14261
14262            cpr.provider = null;
14263            cpr.proc = null;
14264        }
14265        app.pubProviders.clear();
14266
14267        // Take care of any launching providers waiting for this process.
14268        if (checkAppInLaunchingProvidersLocked(app, false)) {
14269            restart = true;
14270        }
14271
14272        // Unregister from connected content providers.
14273        if (!app.conProviders.isEmpty()) {
14274            for (int i=0; i<app.conProviders.size(); i++) {
14275                ContentProviderConnection conn = app.conProviders.get(i);
14276                conn.provider.connections.remove(conn);
14277            }
14278            app.conProviders.clear();
14279        }
14280
14281        // At this point there may be remaining entries in mLaunchingProviders
14282        // where we were the only one waiting, so they are no longer of use.
14283        // Look for these and clean up if found.
14284        // XXX Commented out for now.  Trying to figure out a way to reproduce
14285        // the actual situation to identify what is actually going on.
14286        if (false) {
14287            for (int i=0; i<mLaunchingProviders.size(); i++) {
14288                ContentProviderRecord cpr = (ContentProviderRecord)
14289                        mLaunchingProviders.get(i);
14290                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14291                    synchronized (cpr) {
14292                        cpr.launchingApp = null;
14293                        cpr.notifyAll();
14294                    }
14295                }
14296            }
14297        }
14298
14299        skipCurrentReceiverLocked(app);
14300
14301        // Unregister any receivers.
14302        for (int i=app.receivers.size()-1; i>=0; i--) {
14303            removeReceiverLocked(app.receivers.valueAt(i));
14304        }
14305        app.receivers.clear();
14306
14307        // If the app is undergoing backup, tell the backup manager about it
14308        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14309            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14310                    + mBackupTarget.appInfo + " died during backup");
14311            try {
14312                IBackupManager bm = IBackupManager.Stub.asInterface(
14313                        ServiceManager.getService(Context.BACKUP_SERVICE));
14314                bm.agentDisconnected(app.info.packageName);
14315            } catch (RemoteException e) {
14316                // can't happen; backup manager is local
14317            }
14318        }
14319
14320        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14321            ProcessChangeItem item = mPendingProcessChanges.get(i);
14322            if (item.pid == app.pid) {
14323                mPendingProcessChanges.remove(i);
14324                mAvailProcessChanges.add(item);
14325            }
14326        }
14327        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14328
14329        // If the caller is restarting this app, then leave it in its
14330        // current lists and let the caller take care of it.
14331        if (restarting) {
14332            return;
14333        }
14334
14335        if (!app.persistent || app.isolated) {
14336            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14337                    "Removing non-persistent process during cleanup: " + app);
14338            mProcessNames.remove(app.processName, app.uid);
14339            mIsolatedProcesses.remove(app.uid);
14340            if (mHeavyWeightProcess == app) {
14341                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14342                        mHeavyWeightProcess.userId, 0));
14343                mHeavyWeightProcess = null;
14344            }
14345        } else if (!app.removed) {
14346            // This app is persistent, so we need to keep its record around.
14347            // If it is not already on the pending app list, add it there
14348            // and start a new process for it.
14349            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14350                mPersistentStartingProcesses.add(app);
14351                restart = true;
14352            }
14353        }
14354        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14355                "Clean-up removing on hold: " + app);
14356        mProcessesOnHold.remove(app);
14357
14358        if (app == mHomeProcess) {
14359            mHomeProcess = null;
14360        }
14361        if (app == mPreviousProcess) {
14362            mPreviousProcess = null;
14363        }
14364
14365        if (restart && !app.isolated) {
14366            // We have components that still need to be running in the
14367            // process, so re-launch it.
14368            mProcessNames.put(app.processName, app.uid, app);
14369            startProcessLocked(app, "restart", app.processName);
14370        } else if (app.pid > 0 && app.pid != MY_PID) {
14371            // Goodbye!
14372            boolean removed;
14373            synchronized (mPidsSelfLocked) {
14374                mPidsSelfLocked.remove(app.pid);
14375                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14376            }
14377            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14378            if (app.isolated) {
14379                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14380            }
14381            app.setPid(0);
14382        }
14383    }
14384
14385    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14386        // Look through the content providers we are waiting to have launched,
14387        // and if any run in this process then either schedule a restart of
14388        // the process or kill the client waiting for it if this process has
14389        // gone bad.
14390        int NL = mLaunchingProviders.size();
14391        boolean restart = false;
14392        for (int i=0; i<NL; i++) {
14393            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14394            if (cpr.launchingApp == app) {
14395                if (!alwaysBad && !app.bad) {
14396                    restart = true;
14397                } else {
14398                    removeDyingProviderLocked(app, cpr, true);
14399                    // cpr should have been removed from mLaunchingProviders
14400                    NL = mLaunchingProviders.size();
14401                    i--;
14402                }
14403            }
14404        }
14405        return restart;
14406    }
14407
14408    // =========================================================
14409    // SERVICES
14410    // =========================================================
14411
14412    @Override
14413    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14414            int flags) {
14415        enforceNotIsolatedCaller("getServices");
14416        synchronized (this) {
14417            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14418        }
14419    }
14420
14421    @Override
14422    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14423        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14424        synchronized (this) {
14425            return mServices.getRunningServiceControlPanelLocked(name);
14426        }
14427    }
14428
14429    @Override
14430    public ComponentName startService(IApplicationThread caller, Intent service,
14431            String resolvedType, int userId) {
14432        enforceNotIsolatedCaller("startService");
14433        // Refuse possible leaked file descriptors
14434        if (service != null && service.hasFileDescriptors() == true) {
14435            throw new IllegalArgumentException("File descriptors passed in Intent");
14436        }
14437
14438        if (DEBUG_SERVICE)
14439            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14440        synchronized(this) {
14441            final int callingPid = Binder.getCallingPid();
14442            final int callingUid = Binder.getCallingUid();
14443            final long origId = Binder.clearCallingIdentity();
14444            ComponentName res = mServices.startServiceLocked(caller, service,
14445                    resolvedType, callingPid, callingUid, userId);
14446            Binder.restoreCallingIdentity(origId);
14447            return res;
14448        }
14449    }
14450
14451    ComponentName startServiceInPackage(int uid,
14452            Intent service, String resolvedType, int userId) {
14453        synchronized(this) {
14454            if (DEBUG_SERVICE)
14455                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14456            final long origId = Binder.clearCallingIdentity();
14457            ComponentName res = mServices.startServiceLocked(null, service,
14458                    resolvedType, -1, uid, userId);
14459            Binder.restoreCallingIdentity(origId);
14460            return res;
14461        }
14462    }
14463
14464    @Override
14465    public int stopService(IApplicationThread caller, Intent service,
14466            String resolvedType, int userId) {
14467        enforceNotIsolatedCaller("stopService");
14468        // Refuse possible leaked file descriptors
14469        if (service != null && service.hasFileDescriptors() == true) {
14470            throw new IllegalArgumentException("File descriptors passed in Intent");
14471        }
14472
14473        synchronized(this) {
14474            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14475        }
14476    }
14477
14478    @Override
14479    public IBinder peekService(Intent service, String resolvedType) {
14480        enforceNotIsolatedCaller("peekService");
14481        // Refuse possible leaked file descriptors
14482        if (service != null && service.hasFileDescriptors() == true) {
14483            throw new IllegalArgumentException("File descriptors passed in Intent");
14484        }
14485        synchronized(this) {
14486            return mServices.peekServiceLocked(service, resolvedType);
14487        }
14488    }
14489
14490    @Override
14491    public boolean stopServiceToken(ComponentName className, IBinder token,
14492            int startId) {
14493        synchronized(this) {
14494            return mServices.stopServiceTokenLocked(className, token, startId);
14495        }
14496    }
14497
14498    @Override
14499    public void setServiceForeground(ComponentName className, IBinder token,
14500            int id, Notification notification, boolean removeNotification) {
14501        synchronized(this) {
14502            mServices.setServiceForegroundLocked(className, token, id, notification,
14503                    removeNotification);
14504        }
14505    }
14506
14507    @Override
14508    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14509            boolean requireFull, String name, String callerPackage) {
14510        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14511                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14512    }
14513
14514    int unsafeConvertIncomingUser(int userId) {
14515        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14516                ? mCurrentUserId : userId;
14517    }
14518
14519    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14520            int allowMode, String name, String callerPackage) {
14521        final int callingUserId = UserHandle.getUserId(callingUid);
14522        if (callingUserId == userId) {
14523            return userId;
14524        }
14525
14526        // Note that we may be accessing mCurrentUserId outside of a lock...
14527        // shouldn't be a big deal, if this is being called outside
14528        // of a locked context there is intrinsically a race with
14529        // the value the caller will receive and someone else changing it.
14530        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14531        // we will switch to the calling user if access to the current user fails.
14532        int targetUserId = unsafeConvertIncomingUser(userId);
14533
14534        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14535            final boolean allow;
14536            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14537                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14538                // If the caller has this permission, they always pass go.  And collect $200.
14539                allow = true;
14540            } else if (allowMode == ALLOW_FULL_ONLY) {
14541                // We require full access, sucks to be you.
14542                allow = false;
14543            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14544                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14545                // If the caller does not have either permission, they are always doomed.
14546                allow = false;
14547            } else if (allowMode == ALLOW_NON_FULL) {
14548                // We are blanket allowing non-full access, you lucky caller!
14549                allow = true;
14550            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14551                // We may or may not allow this depending on whether the two users are
14552                // in the same profile.
14553                synchronized (mUserProfileGroupIdsSelfLocked) {
14554                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14555                            UserInfo.NO_PROFILE_GROUP_ID);
14556                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14557                            UserInfo.NO_PROFILE_GROUP_ID);
14558                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14559                            && callingProfile == targetProfile;
14560                }
14561            } else {
14562                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14563            }
14564            if (!allow) {
14565                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14566                    // In this case, they would like to just execute as their
14567                    // owner user instead of failing.
14568                    targetUserId = callingUserId;
14569                } else {
14570                    StringBuilder builder = new StringBuilder(128);
14571                    builder.append("Permission Denial: ");
14572                    builder.append(name);
14573                    if (callerPackage != null) {
14574                        builder.append(" from ");
14575                        builder.append(callerPackage);
14576                    }
14577                    builder.append(" asks to run as user ");
14578                    builder.append(userId);
14579                    builder.append(" but is calling from user ");
14580                    builder.append(UserHandle.getUserId(callingUid));
14581                    builder.append("; this requires ");
14582                    builder.append(INTERACT_ACROSS_USERS_FULL);
14583                    if (allowMode != ALLOW_FULL_ONLY) {
14584                        builder.append(" or ");
14585                        builder.append(INTERACT_ACROSS_USERS);
14586                    }
14587                    String msg = builder.toString();
14588                    Slog.w(TAG, msg);
14589                    throw new SecurityException(msg);
14590                }
14591            }
14592        }
14593        if (!allowAll && targetUserId < 0) {
14594            throw new IllegalArgumentException(
14595                    "Call does not support special user #" + targetUserId);
14596        }
14597        return targetUserId;
14598    }
14599
14600    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14601            String className, int flags) {
14602        boolean result = false;
14603        // For apps that don't have pre-defined UIDs, check for permission
14604        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14605            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14606                if (ActivityManager.checkUidPermission(
14607                        INTERACT_ACROSS_USERS,
14608                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14609                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14610                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14611                            + " requests FLAG_SINGLE_USER, but app does not hold "
14612                            + INTERACT_ACROSS_USERS;
14613                    Slog.w(TAG, msg);
14614                    throw new SecurityException(msg);
14615                }
14616                // Permission passed
14617                result = true;
14618            }
14619        } else if ("system".equals(componentProcessName)) {
14620            result = true;
14621        } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14622                && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14623            // Phone app is allowed to export singleuser providers.
14624            result = true;
14625        } else {
14626            // App with pre-defined UID, check if it's a persistent app
14627            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14628        }
14629        if (DEBUG_MU) {
14630            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14631                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14632        }
14633        return result;
14634    }
14635
14636    /**
14637     * Checks to see if the caller is in the same app as the singleton
14638     * component, or the component is in a special app. It allows special apps
14639     * to export singleton components but prevents exporting singleton
14640     * components for regular apps.
14641     */
14642    boolean isValidSingletonCall(int callingUid, int componentUid) {
14643        int componentAppId = UserHandle.getAppId(componentUid);
14644        return UserHandle.isSameApp(callingUid, componentUid)
14645                || componentAppId == Process.SYSTEM_UID
14646                || componentAppId == Process.PHONE_UID
14647                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14648                        == PackageManager.PERMISSION_GRANTED;
14649    }
14650
14651    public int bindService(IApplicationThread caller, IBinder token,
14652            Intent service, String resolvedType,
14653            IServiceConnection connection, int flags, int userId) {
14654        enforceNotIsolatedCaller("bindService");
14655        // Refuse possible leaked file descriptors
14656        if (service != null && service.hasFileDescriptors() == true) {
14657            throw new IllegalArgumentException("File descriptors passed in Intent");
14658        }
14659
14660        synchronized(this) {
14661            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14662                    connection, flags, userId);
14663        }
14664    }
14665
14666    public boolean unbindService(IServiceConnection connection) {
14667        synchronized (this) {
14668            return mServices.unbindServiceLocked(connection);
14669        }
14670    }
14671
14672    public void publishService(IBinder token, Intent intent, IBinder service) {
14673        // Refuse possible leaked file descriptors
14674        if (intent != null && intent.hasFileDescriptors() == true) {
14675            throw new IllegalArgumentException("File descriptors passed in Intent");
14676        }
14677
14678        synchronized(this) {
14679            if (!(token instanceof ServiceRecord)) {
14680                throw new IllegalArgumentException("Invalid service token");
14681            }
14682            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14683        }
14684    }
14685
14686    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14687        // Refuse possible leaked file descriptors
14688        if (intent != null && intent.hasFileDescriptors() == true) {
14689            throw new IllegalArgumentException("File descriptors passed in Intent");
14690        }
14691
14692        synchronized(this) {
14693            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14694        }
14695    }
14696
14697    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14698        synchronized(this) {
14699            if (!(token instanceof ServiceRecord)) {
14700                throw new IllegalArgumentException("Invalid service token");
14701            }
14702            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14703        }
14704    }
14705
14706    // =========================================================
14707    // BACKUP AND RESTORE
14708    // =========================================================
14709
14710    // Cause the target app to be launched if necessary and its backup agent
14711    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14712    // activity manager to announce its creation.
14713    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14714        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14715        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14716
14717        synchronized(this) {
14718            // !!! TODO: currently no check here that we're already bound
14719            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14720            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14721            synchronized (stats) {
14722                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14723            }
14724
14725            // Backup agent is now in use, its package can't be stopped.
14726            try {
14727                AppGlobals.getPackageManager().setPackageStoppedState(
14728                        app.packageName, false, UserHandle.getUserId(app.uid));
14729            } catch (RemoteException e) {
14730            } catch (IllegalArgumentException e) {
14731                Slog.w(TAG, "Failed trying to unstop package "
14732                        + app.packageName + ": " + e);
14733            }
14734
14735            BackupRecord r = new BackupRecord(ss, app, backupMode);
14736            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14737                    ? new ComponentName(app.packageName, app.backupAgentName)
14738                    : new ComponentName("android", "FullBackupAgent");
14739            // startProcessLocked() returns existing proc's record if it's already running
14740            ProcessRecord proc = startProcessLocked(app.processName, app,
14741                    false, 0, "backup", hostingName, false, false, false);
14742            if (proc == null) {
14743                Slog.e(TAG, "Unable to start backup agent process " + r);
14744                return false;
14745            }
14746
14747            r.app = proc;
14748            mBackupTarget = r;
14749            mBackupAppName = app.packageName;
14750
14751            // Try not to kill the process during backup
14752            updateOomAdjLocked(proc);
14753
14754            // If the process is already attached, schedule the creation of the backup agent now.
14755            // If it is not yet live, this will be done when it attaches to the framework.
14756            if (proc.thread != null) {
14757                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14758                try {
14759                    proc.thread.scheduleCreateBackupAgent(app,
14760                            compatibilityInfoForPackageLocked(app), backupMode);
14761                } catch (RemoteException e) {
14762                    // Will time out on the backup manager side
14763                }
14764            } else {
14765                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14766            }
14767            // Invariants: at this point, the target app process exists and the application
14768            // is either already running or in the process of coming up.  mBackupTarget and
14769            // mBackupAppName describe the app, so that when it binds back to the AM we
14770            // know that it's scheduled for a backup-agent operation.
14771        }
14772
14773        return true;
14774    }
14775
14776    @Override
14777    public void clearPendingBackup() {
14778        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14779        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14780
14781        synchronized (this) {
14782            mBackupTarget = null;
14783            mBackupAppName = null;
14784        }
14785    }
14786
14787    // A backup agent has just come up
14788    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14789        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14790                + " = " + agent);
14791
14792        synchronized(this) {
14793            if (!agentPackageName.equals(mBackupAppName)) {
14794                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14795                return;
14796            }
14797        }
14798
14799        long oldIdent = Binder.clearCallingIdentity();
14800        try {
14801            IBackupManager bm = IBackupManager.Stub.asInterface(
14802                    ServiceManager.getService(Context.BACKUP_SERVICE));
14803            bm.agentConnected(agentPackageName, agent);
14804        } catch (RemoteException e) {
14805            // can't happen; the backup manager service is local
14806        } catch (Exception e) {
14807            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14808            e.printStackTrace();
14809        } finally {
14810            Binder.restoreCallingIdentity(oldIdent);
14811        }
14812    }
14813
14814    // done with this agent
14815    public void unbindBackupAgent(ApplicationInfo appInfo) {
14816        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14817        if (appInfo == null) {
14818            Slog.w(TAG, "unbind backup agent for null app");
14819            return;
14820        }
14821
14822        synchronized(this) {
14823            try {
14824                if (mBackupAppName == null) {
14825                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14826                    return;
14827                }
14828
14829                if (!mBackupAppName.equals(appInfo.packageName)) {
14830                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14831                    return;
14832                }
14833
14834                // Not backing this app up any more; reset its OOM adjustment
14835                final ProcessRecord proc = mBackupTarget.app;
14836                updateOomAdjLocked(proc);
14837
14838                // If the app crashed during backup, 'thread' will be null here
14839                if (proc.thread != null) {
14840                    try {
14841                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14842                                compatibilityInfoForPackageLocked(appInfo));
14843                    } catch (Exception e) {
14844                        Slog.e(TAG, "Exception when unbinding backup agent:");
14845                        e.printStackTrace();
14846                    }
14847                }
14848            } finally {
14849                mBackupTarget = null;
14850                mBackupAppName = null;
14851            }
14852        }
14853    }
14854    // =========================================================
14855    // BROADCASTS
14856    // =========================================================
14857
14858    private final List getStickiesLocked(String action, IntentFilter filter,
14859            List cur, int userId) {
14860        final ContentResolver resolver = mContext.getContentResolver();
14861        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14862        if (stickies == null) {
14863            return cur;
14864        }
14865        final ArrayList<Intent> list = stickies.get(action);
14866        if (list == null) {
14867            return cur;
14868        }
14869        int N = list.size();
14870        for (int i=0; i<N; i++) {
14871            Intent intent = list.get(i);
14872            if (filter.match(resolver, intent, true, TAG) >= 0) {
14873                if (cur == null) {
14874                    cur = new ArrayList<Intent>();
14875                }
14876                cur.add(intent);
14877            }
14878        }
14879        return cur;
14880    }
14881
14882    boolean isPendingBroadcastProcessLocked(int pid) {
14883        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14884                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14885    }
14886
14887    void skipPendingBroadcastLocked(int pid) {
14888            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14889            for (BroadcastQueue queue : mBroadcastQueues) {
14890                queue.skipPendingBroadcastLocked(pid);
14891            }
14892    }
14893
14894    // The app just attached; send any pending broadcasts that it should receive
14895    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14896        boolean didSomething = false;
14897        for (BroadcastQueue queue : mBroadcastQueues) {
14898            didSomething |= queue.sendPendingBroadcastsLocked(app);
14899        }
14900        return didSomething;
14901    }
14902
14903    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14904            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14905        enforceNotIsolatedCaller("registerReceiver");
14906        int callingUid;
14907        int callingPid;
14908        synchronized(this) {
14909            ProcessRecord callerApp = null;
14910            if (caller != null) {
14911                callerApp = getRecordForAppLocked(caller);
14912                if (callerApp == null) {
14913                    throw new SecurityException(
14914                            "Unable to find app for caller " + caller
14915                            + " (pid=" + Binder.getCallingPid()
14916                            + ") when registering receiver " + receiver);
14917                }
14918                if (callerApp.info.uid != Process.SYSTEM_UID &&
14919                        !callerApp.pkgList.containsKey(callerPackage) &&
14920                        !"android".equals(callerPackage)) {
14921                    throw new SecurityException("Given caller package " + callerPackage
14922                            + " is not running in process " + callerApp);
14923                }
14924                callingUid = callerApp.info.uid;
14925                callingPid = callerApp.pid;
14926            } else {
14927                callerPackage = null;
14928                callingUid = Binder.getCallingUid();
14929                callingPid = Binder.getCallingPid();
14930            }
14931
14932            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14933                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14934
14935            List allSticky = null;
14936
14937            // Look for any matching sticky broadcasts...
14938            Iterator actions = filter.actionsIterator();
14939            if (actions != null) {
14940                while (actions.hasNext()) {
14941                    String action = (String)actions.next();
14942                    allSticky = getStickiesLocked(action, filter, allSticky,
14943                            UserHandle.USER_ALL);
14944                    allSticky = getStickiesLocked(action, filter, allSticky,
14945                            UserHandle.getUserId(callingUid));
14946                }
14947            } else {
14948                allSticky = getStickiesLocked(null, filter, allSticky,
14949                        UserHandle.USER_ALL);
14950                allSticky = getStickiesLocked(null, filter, allSticky,
14951                        UserHandle.getUserId(callingUid));
14952            }
14953
14954            // The first sticky in the list is returned directly back to
14955            // the client.
14956            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14957
14958            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14959                    + ": " + sticky);
14960
14961            if (receiver == null) {
14962                return sticky;
14963            }
14964
14965            ReceiverList rl
14966                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14967            if (rl == null) {
14968                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14969                        userId, receiver);
14970                if (rl.app != null) {
14971                    rl.app.receivers.add(rl);
14972                } else {
14973                    try {
14974                        receiver.asBinder().linkToDeath(rl, 0);
14975                    } catch (RemoteException e) {
14976                        return sticky;
14977                    }
14978                    rl.linkedToDeath = true;
14979                }
14980                mRegisteredReceivers.put(receiver.asBinder(), rl);
14981            } else if (rl.uid != callingUid) {
14982                throw new IllegalArgumentException(
14983                        "Receiver requested to register for uid " + callingUid
14984                        + " was previously registered for uid " + rl.uid);
14985            } else if (rl.pid != callingPid) {
14986                throw new IllegalArgumentException(
14987                        "Receiver requested to register for pid " + callingPid
14988                        + " was previously registered for pid " + rl.pid);
14989            } else if (rl.userId != userId) {
14990                throw new IllegalArgumentException(
14991                        "Receiver requested to register for user " + userId
14992                        + " was previously registered for user " + rl.userId);
14993            }
14994            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14995                    permission, callingUid, userId);
14996            rl.add(bf);
14997            if (!bf.debugCheck()) {
14998                Slog.w(TAG, "==> For Dynamic broadast");
14999            }
15000            mReceiverResolver.addFilter(bf);
15001
15002            // Enqueue broadcasts for all existing stickies that match
15003            // this filter.
15004            if (allSticky != null) {
15005                ArrayList receivers = new ArrayList();
15006                receivers.add(bf);
15007
15008                int N = allSticky.size();
15009                for (int i=0; i<N; i++) {
15010                    Intent intent = (Intent)allSticky.get(i);
15011                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15012                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15013                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15014                            null, null, false, true, true, -1);
15015                    queue.enqueueParallelBroadcastLocked(r);
15016                    queue.scheduleBroadcastsLocked();
15017                }
15018            }
15019
15020            return sticky;
15021        }
15022    }
15023
15024    public void unregisterReceiver(IIntentReceiver receiver) {
15025        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15026
15027        final long origId = Binder.clearCallingIdentity();
15028        try {
15029            boolean doTrim = false;
15030
15031            synchronized(this) {
15032                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15033                if (rl != null) {
15034                    if (rl.curBroadcast != null) {
15035                        BroadcastRecord r = rl.curBroadcast;
15036                        final boolean doNext = finishReceiverLocked(
15037                                receiver.asBinder(), r.resultCode, r.resultData,
15038                                r.resultExtras, r.resultAbort);
15039                        if (doNext) {
15040                            doTrim = true;
15041                            r.queue.processNextBroadcast(false);
15042                        }
15043                    }
15044
15045                    if (rl.app != null) {
15046                        rl.app.receivers.remove(rl);
15047                    }
15048                    removeReceiverLocked(rl);
15049                    if (rl.linkedToDeath) {
15050                        rl.linkedToDeath = false;
15051                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15052                    }
15053                }
15054            }
15055
15056            // If we actually concluded any broadcasts, we might now be able
15057            // to trim the recipients' apps from our working set
15058            if (doTrim) {
15059                trimApplications();
15060                return;
15061            }
15062
15063        } finally {
15064            Binder.restoreCallingIdentity(origId);
15065        }
15066    }
15067
15068    void removeReceiverLocked(ReceiverList rl) {
15069        mRegisteredReceivers.remove(rl.receiver.asBinder());
15070        int N = rl.size();
15071        for (int i=0; i<N; i++) {
15072            mReceiverResolver.removeFilter(rl.get(i));
15073        }
15074    }
15075
15076    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15077        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15078            ProcessRecord r = mLruProcesses.get(i);
15079            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15080                try {
15081                    r.thread.dispatchPackageBroadcast(cmd, packages);
15082                } catch (RemoteException ex) {
15083                }
15084            }
15085        }
15086    }
15087
15088    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15089            int[] users) {
15090        List<ResolveInfo> receivers = null;
15091        try {
15092            HashSet<ComponentName> singleUserReceivers = null;
15093            boolean scannedFirstReceivers = false;
15094            for (int user : users) {
15095                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15096                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15097                if (user != 0 && newReceivers != null) {
15098                    // If this is not the primary user, we need to check for
15099                    // any receivers that should be filtered out.
15100                    for (int i=0; i<newReceivers.size(); i++) {
15101                        ResolveInfo ri = newReceivers.get(i);
15102                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15103                            newReceivers.remove(i);
15104                            i--;
15105                        }
15106                    }
15107                }
15108                if (newReceivers != null && newReceivers.size() == 0) {
15109                    newReceivers = null;
15110                }
15111                if (receivers == null) {
15112                    receivers = newReceivers;
15113                } else if (newReceivers != null) {
15114                    // We need to concatenate the additional receivers
15115                    // found with what we have do far.  This would be easy,
15116                    // but we also need to de-dup any receivers that are
15117                    // singleUser.
15118                    if (!scannedFirstReceivers) {
15119                        // Collect any single user receivers we had already retrieved.
15120                        scannedFirstReceivers = true;
15121                        for (int i=0; i<receivers.size(); i++) {
15122                            ResolveInfo ri = receivers.get(i);
15123                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15124                                ComponentName cn = new ComponentName(
15125                                        ri.activityInfo.packageName, ri.activityInfo.name);
15126                                if (singleUserReceivers == null) {
15127                                    singleUserReceivers = new HashSet<ComponentName>();
15128                                }
15129                                singleUserReceivers.add(cn);
15130                            }
15131                        }
15132                    }
15133                    // Add the new results to the existing results, tracking
15134                    // and de-dupping single user receivers.
15135                    for (int i=0; i<newReceivers.size(); i++) {
15136                        ResolveInfo ri = newReceivers.get(i);
15137                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15138                            ComponentName cn = new ComponentName(
15139                                    ri.activityInfo.packageName, ri.activityInfo.name);
15140                            if (singleUserReceivers == null) {
15141                                singleUserReceivers = new HashSet<ComponentName>();
15142                            }
15143                            if (!singleUserReceivers.contains(cn)) {
15144                                singleUserReceivers.add(cn);
15145                                receivers.add(ri);
15146                            }
15147                        } else {
15148                            receivers.add(ri);
15149                        }
15150                    }
15151                }
15152            }
15153        } catch (RemoteException ex) {
15154            // pm is in same process, this will never happen.
15155        }
15156        return receivers;
15157    }
15158
15159    private final int broadcastIntentLocked(ProcessRecord callerApp,
15160            String callerPackage, Intent intent, String resolvedType,
15161            IIntentReceiver resultTo, int resultCode, String resultData,
15162            Bundle map, String requiredPermission, int appOp,
15163            boolean ordered, boolean sticky, int callingPid, int callingUid,
15164            int userId) {
15165        intent = new Intent(intent);
15166
15167        // By default broadcasts do not go to stopped apps.
15168        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15169
15170        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15171            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15172            + " ordered=" + ordered + " userid=" + userId);
15173        if ((resultTo != null) && !ordered) {
15174            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15175        }
15176
15177        userId = handleIncomingUser(callingPid, callingUid, userId,
15178                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15179
15180        // Make sure that the user who is receiving this broadcast is started.
15181        // If not, we will just skip it.
15182
15183
15184        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15185            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15186                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15187                Slog.w(TAG, "Skipping broadcast of " + intent
15188                        + ": user " + userId + " is stopped");
15189                return ActivityManager.BROADCAST_SUCCESS;
15190            }
15191        }
15192
15193        /*
15194         * Prevent non-system code (defined here to be non-persistent
15195         * processes) from sending protected broadcasts.
15196         */
15197        int callingAppId = UserHandle.getAppId(callingUid);
15198        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15199            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15200            || callingAppId == Process.NFC_UID || callingUid == 0) {
15201            // Always okay.
15202        } else if (callerApp == null || !callerApp.persistent) {
15203            try {
15204                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15205                        intent.getAction())) {
15206                    String msg = "Permission Denial: not allowed to send broadcast "
15207                            + intent.getAction() + " from pid="
15208                            + callingPid + ", uid=" + callingUid;
15209                    Slog.w(TAG, msg);
15210                    throw new SecurityException(msg);
15211                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15212                    // Special case for compatibility: we don't want apps to send this,
15213                    // but historically it has not been protected and apps may be using it
15214                    // to poke their own app widget.  So, instead of making it protected,
15215                    // just limit it to the caller.
15216                    if (callerApp == null) {
15217                        String msg = "Permission Denial: not allowed to send broadcast "
15218                                + intent.getAction() + " from unknown caller.";
15219                        Slog.w(TAG, msg);
15220                        throw new SecurityException(msg);
15221                    } else if (intent.getComponent() != null) {
15222                        // They are good enough to send to an explicit component...  verify
15223                        // it is being sent to the calling app.
15224                        if (!intent.getComponent().getPackageName().equals(
15225                                callerApp.info.packageName)) {
15226                            String msg = "Permission Denial: not allowed to send broadcast "
15227                                    + intent.getAction() + " to "
15228                                    + intent.getComponent().getPackageName() + " from "
15229                                    + callerApp.info.packageName;
15230                            Slog.w(TAG, msg);
15231                            throw new SecurityException(msg);
15232                        }
15233                    } else {
15234                        // Limit broadcast to their own package.
15235                        intent.setPackage(callerApp.info.packageName);
15236                    }
15237                }
15238            } catch (RemoteException e) {
15239                Slog.w(TAG, "Remote exception", e);
15240                return ActivityManager.BROADCAST_SUCCESS;
15241            }
15242        }
15243
15244        // Handle special intents: if this broadcast is from the package
15245        // manager about a package being removed, we need to remove all of
15246        // its activities from the history stack.
15247        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15248                intent.getAction());
15249        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15250                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15251                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15252                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15253                || uidRemoved) {
15254            if (checkComponentPermission(
15255                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15256                    callingPid, callingUid, -1, true)
15257                    == PackageManager.PERMISSION_GRANTED) {
15258                if (uidRemoved) {
15259                    final Bundle intentExtras = intent.getExtras();
15260                    final int uid = intentExtras != null
15261                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15262                    if (uid >= 0) {
15263                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15264                        synchronized (bs) {
15265                            bs.removeUidStatsLocked(uid);
15266                        }
15267                        mAppOpsService.uidRemoved(uid);
15268                    }
15269                } else {
15270                    // If resources are unavailable just force stop all
15271                    // those packages and flush the attribute cache as well.
15272                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15273                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15274                        if (list != null && (list.length > 0)) {
15275                            for (String pkg : list) {
15276                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15277                                        "storage unmount");
15278                            }
15279                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15280                            sendPackageBroadcastLocked(
15281                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15282                        }
15283                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15284                            intent.getAction())) {
15285                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15286                    } else {
15287                        Uri data = intent.getData();
15288                        String ssp;
15289                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15290                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15291                                    intent.getAction());
15292                            boolean fullUninstall = removed &&
15293                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15294                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15295                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15296                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15297                                        false, fullUninstall, userId,
15298                                        removed ? "pkg removed" : "pkg changed");
15299                            }
15300                            if (removed) {
15301                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15302                                        new String[] {ssp}, userId);
15303                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15304                                    mAppOpsService.packageRemoved(
15305                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15306
15307                                    // Remove all permissions granted from/to this package
15308                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15309                                }
15310                            }
15311                        }
15312                    }
15313                }
15314            } else {
15315                String msg = "Permission Denial: " + intent.getAction()
15316                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15317                        + ", uid=" + callingUid + ")"
15318                        + " requires "
15319                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15320                Slog.w(TAG, msg);
15321                throw new SecurityException(msg);
15322            }
15323
15324        // Special case for adding a package: by default turn on compatibility
15325        // mode.
15326        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15327            Uri data = intent.getData();
15328            String ssp;
15329            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15330                mCompatModePackages.handlePackageAddedLocked(ssp,
15331                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15332            }
15333        }
15334
15335        /*
15336         * If this is the time zone changed action, queue up a message that will reset the timezone
15337         * of all currently running processes. This message will get queued up before the broadcast
15338         * happens.
15339         */
15340        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15341            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15342        }
15343
15344        /*
15345         * If the user set the time, let all running processes know.
15346         */
15347        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15348            final int is24Hour = intent.getBooleanExtra(
15349                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15350            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15351            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15352            synchronized (stats) {
15353                stats.noteCurrentTimeChangedLocked();
15354            }
15355        }
15356
15357        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15358            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15359        }
15360
15361        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15362            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15363            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15364        }
15365
15366        // Add to the sticky list if requested.
15367        if (sticky) {
15368            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15369                    callingPid, callingUid)
15370                    != PackageManager.PERMISSION_GRANTED) {
15371                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15372                        + callingPid + ", uid=" + callingUid
15373                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15374                Slog.w(TAG, msg);
15375                throw new SecurityException(msg);
15376            }
15377            if (requiredPermission != null) {
15378                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15379                        + " and enforce permission " + requiredPermission);
15380                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15381            }
15382            if (intent.getComponent() != null) {
15383                throw new SecurityException(
15384                        "Sticky broadcasts can't target a specific component");
15385            }
15386            // We use userId directly here, since the "all" target is maintained
15387            // as a separate set of sticky broadcasts.
15388            if (userId != UserHandle.USER_ALL) {
15389                // But first, if this is not a broadcast to all users, then
15390                // make sure it doesn't conflict with an existing broadcast to
15391                // all users.
15392                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15393                        UserHandle.USER_ALL);
15394                if (stickies != null) {
15395                    ArrayList<Intent> list = stickies.get(intent.getAction());
15396                    if (list != null) {
15397                        int N = list.size();
15398                        int i;
15399                        for (i=0; i<N; i++) {
15400                            if (intent.filterEquals(list.get(i))) {
15401                                throw new IllegalArgumentException(
15402                                        "Sticky broadcast " + intent + " for user "
15403                                        + userId + " conflicts with existing global broadcast");
15404                            }
15405                        }
15406                    }
15407                }
15408            }
15409            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15410            if (stickies == null) {
15411                stickies = new ArrayMap<String, ArrayList<Intent>>();
15412                mStickyBroadcasts.put(userId, stickies);
15413            }
15414            ArrayList<Intent> list = stickies.get(intent.getAction());
15415            if (list == null) {
15416                list = new ArrayList<Intent>();
15417                stickies.put(intent.getAction(), list);
15418            }
15419            int N = list.size();
15420            int i;
15421            for (i=0; i<N; i++) {
15422                if (intent.filterEquals(list.get(i))) {
15423                    // This sticky already exists, replace it.
15424                    list.set(i, new Intent(intent));
15425                    break;
15426                }
15427            }
15428            if (i >= N) {
15429                list.add(new Intent(intent));
15430            }
15431        }
15432
15433        int[] users;
15434        if (userId == UserHandle.USER_ALL) {
15435            // Caller wants broadcast to go to all started users.
15436            users = mStartedUserArray;
15437        } else {
15438            // Caller wants broadcast to go to one specific user.
15439            users = new int[] {userId};
15440        }
15441
15442        // Figure out who all will receive this broadcast.
15443        List receivers = null;
15444        List<BroadcastFilter> registeredReceivers = null;
15445        // Need to resolve the intent to interested receivers...
15446        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15447                 == 0) {
15448            receivers = collectReceiverComponents(intent, resolvedType, users);
15449        }
15450        if (intent.getComponent() == null) {
15451            registeredReceivers = mReceiverResolver.queryIntent(intent,
15452                    resolvedType, false, userId);
15453        }
15454
15455        final boolean replacePending =
15456                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15457
15458        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15459                + " replacePending=" + replacePending);
15460
15461        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15462        if (!ordered && NR > 0) {
15463            // If we are not serializing this broadcast, then send the
15464            // registered receivers separately so they don't wait for the
15465            // components to be launched.
15466            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15467            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15468                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15469                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15470                    ordered, sticky, false, userId);
15471            if (DEBUG_BROADCAST) Slog.v(
15472                    TAG, "Enqueueing parallel broadcast " + r);
15473            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15474            if (!replaced) {
15475                queue.enqueueParallelBroadcastLocked(r);
15476                queue.scheduleBroadcastsLocked();
15477            }
15478            registeredReceivers = null;
15479            NR = 0;
15480        }
15481
15482        // Merge into one list.
15483        int ir = 0;
15484        if (receivers != null) {
15485            // A special case for PACKAGE_ADDED: do not allow the package
15486            // being added to see this broadcast.  This prevents them from
15487            // using this as a back door to get run as soon as they are
15488            // installed.  Maybe in the future we want to have a special install
15489            // broadcast or such for apps, but we'd like to deliberately make
15490            // this decision.
15491            String skipPackages[] = null;
15492            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15493                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15494                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15495                Uri data = intent.getData();
15496                if (data != null) {
15497                    String pkgName = data.getSchemeSpecificPart();
15498                    if (pkgName != null) {
15499                        skipPackages = new String[] { pkgName };
15500                    }
15501                }
15502            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15503                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15504            }
15505            if (skipPackages != null && (skipPackages.length > 0)) {
15506                for (String skipPackage : skipPackages) {
15507                    if (skipPackage != null) {
15508                        int NT = receivers.size();
15509                        for (int it=0; it<NT; it++) {
15510                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15511                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15512                                receivers.remove(it);
15513                                it--;
15514                                NT--;
15515                            }
15516                        }
15517                    }
15518                }
15519            }
15520
15521            int NT = receivers != null ? receivers.size() : 0;
15522            int it = 0;
15523            ResolveInfo curt = null;
15524            BroadcastFilter curr = null;
15525            while (it < NT && ir < NR) {
15526                if (curt == null) {
15527                    curt = (ResolveInfo)receivers.get(it);
15528                }
15529                if (curr == null) {
15530                    curr = registeredReceivers.get(ir);
15531                }
15532                if (curr.getPriority() >= curt.priority) {
15533                    // Insert this broadcast record into the final list.
15534                    receivers.add(it, curr);
15535                    ir++;
15536                    curr = null;
15537                    it++;
15538                    NT++;
15539                } else {
15540                    // Skip to the next ResolveInfo in the final list.
15541                    it++;
15542                    curt = null;
15543                }
15544            }
15545        }
15546        while (ir < NR) {
15547            if (receivers == null) {
15548                receivers = new ArrayList();
15549            }
15550            receivers.add(registeredReceivers.get(ir));
15551            ir++;
15552        }
15553
15554        if ((receivers != null && receivers.size() > 0)
15555                || resultTo != null) {
15556            BroadcastQueue queue = broadcastQueueForIntent(intent);
15557            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15558                    callerPackage, callingPid, callingUid, resolvedType,
15559                    requiredPermission, appOp, receivers, resultTo, resultCode,
15560                    resultData, map, ordered, sticky, false, userId);
15561            if (DEBUG_BROADCAST) Slog.v(
15562                    TAG, "Enqueueing ordered broadcast " + r
15563                    + ": prev had " + queue.mOrderedBroadcasts.size());
15564            if (DEBUG_BROADCAST) {
15565                int seq = r.intent.getIntExtra("seq", -1);
15566                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15567            }
15568            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15569            if (!replaced) {
15570                queue.enqueueOrderedBroadcastLocked(r);
15571                queue.scheduleBroadcastsLocked();
15572            }
15573        }
15574
15575        return ActivityManager.BROADCAST_SUCCESS;
15576    }
15577
15578    final Intent verifyBroadcastLocked(Intent intent) {
15579        // Refuse possible leaked file descriptors
15580        if (intent != null && intent.hasFileDescriptors() == true) {
15581            throw new IllegalArgumentException("File descriptors passed in Intent");
15582        }
15583
15584        int flags = intent.getFlags();
15585
15586        if (!mProcessesReady) {
15587            // if the caller really truly claims to know what they're doing, go
15588            // ahead and allow the broadcast without launching any receivers
15589            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15590                intent = new Intent(intent);
15591                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15592            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15593                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15594                        + " before boot completion");
15595                throw new IllegalStateException("Cannot broadcast before boot completed");
15596            }
15597        }
15598
15599        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15600            throw new IllegalArgumentException(
15601                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15602        }
15603
15604        return intent;
15605    }
15606
15607    public final int broadcastIntent(IApplicationThread caller,
15608            Intent intent, String resolvedType, IIntentReceiver resultTo,
15609            int resultCode, String resultData, Bundle map,
15610            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15611        enforceNotIsolatedCaller("broadcastIntent");
15612        synchronized(this) {
15613            intent = verifyBroadcastLocked(intent);
15614
15615            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15616            final int callingPid = Binder.getCallingPid();
15617            final int callingUid = Binder.getCallingUid();
15618            final long origId = Binder.clearCallingIdentity();
15619            int res = broadcastIntentLocked(callerApp,
15620                    callerApp != null ? callerApp.info.packageName : null,
15621                    intent, resolvedType, resultTo,
15622                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15623                    callingPid, callingUid, userId);
15624            Binder.restoreCallingIdentity(origId);
15625            return res;
15626        }
15627    }
15628
15629    int broadcastIntentInPackage(String packageName, int uid,
15630            Intent intent, String resolvedType, IIntentReceiver resultTo,
15631            int resultCode, String resultData, Bundle map,
15632            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15633        synchronized(this) {
15634            intent = verifyBroadcastLocked(intent);
15635
15636            final long origId = Binder.clearCallingIdentity();
15637            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15638                    resultTo, resultCode, resultData, map, requiredPermission,
15639                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15640            Binder.restoreCallingIdentity(origId);
15641            return res;
15642        }
15643    }
15644
15645    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15646        // Refuse possible leaked file descriptors
15647        if (intent != null && intent.hasFileDescriptors() == true) {
15648            throw new IllegalArgumentException("File descriptors passed in Intent");
15649        }
15650
15651        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15652                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15653
15654        synchronized(this) {
15655            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15656                    != PackageManager.PERMISSION_GRANTED) {
15657                String msg = "Permission Denial: unbroadcastIntent() from pid="
15658                        + Binder.getCallingPid()
15659                        + ", uid=" + Binder.getCallingUid()
15660                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15661                Slog.w(TAG, msg);
15662                throw new SecurityException(msg);
15663            }
15664            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15665            if (stickies != null) {
15666                ArrayList<Intent> list = stickies.get(intent.getAction());
15667                if (list != null) {
15668                    int N = list.size();
15669                    int i;
15670                    for (i=0; i<N; i++) {
15671                        if (intent.filterEquals(list.get(i))) {
15672                            list.remove(i);
15673                            break;
15674                        }
15675                    }
15676                    if (list.size() <= 0) {
15677                        stickies.remove(intent.getAction());
15678                    }
15679                }
15680                if (stickies.size() <= 0) {
15681                    mStickyBroadcasts.remove(userId);
15682                }
15683            }
15684        }
15685    }
15686
15687    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15688            String resultData, Bundle resultExtras, boolean resultAbort) {
15689        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15690        if (r == null) {
15691            Slog.w(TAG, "finishReceiver called but not found on queue");
15692            return false;
15693        }
15694
15695        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15696    }
15697
15698    void backgroundServicesFinishedLocked(int userId) {
15699        for (BroadcastQueue queue : mBroadcastQueues) {
15700            queue.backgroundServicesFinishedLocked(userId);
15701        }
15702    }
15703
15704    public void finishReceiver(IBinder who, int resultCode, String resultData,
15705            Bundle resultExtras, boolean resultAbort) {
15706        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15707
15708        // Refuse possible leaked file descriptors
15709        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15710            throw new IllegalArgumentException("File descriptors passed in Bundle");
15711        }
15712
15713        final long origId = Binder.clearCallingIdentity();
15714        try {
15715            boolean doNext = false;
15716            BroadcastRecord r;
15717
15718            synchronized(this) {
15719                r = broadcastRecordForReceiverLocked(who);
15720                if (r != null) {
15721                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15722                        resultData, resultExtras, resultAbort, true);
15723                }
15724            }
15725
15726            if (doNext) {
15727                r.queue.processNextBroadcast(false);
15728            }
15729            trimApplications();
15730        } finally {
15731            Binder.restoreCallingIdentity(origId);
15732        }
15733    }
15734
15735    // =========================================================
15736    // INSTRUMENTATION
15737    // =========================================================
15738
15739    public boolean startInstrumentation(ComponentName className,
15740            String profileFile, int flags, Bundle arguments,
15741            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15742            int userId, String abiOverride) {
15743        enforceNotIsolatedCaller("startInstrumentation");
15744        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15745                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15746        // Refuse possible leaked file descriptors
15747        if (arguments != null && arguments.hasFileDescriptors()) {
15748            throw new IllegalArgumentException("File descriptors passed in Bundle");
15749        }
15750
15751        synchronized(this) {
15752            InstrumentationInfo ii = null;
15753            ApplicationInfo ai = null;
15754            try {
15755                ii = mContext.getPackageManager().getInstrumentationInfo(
15756                    className, STOCK_PM_FLAGS);
15757                ai = AppGlobals.getPackageManager().getApplicationInfo(
15758                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15759            } catch (PackageManager.NameNotFoundException e) {
15760            } catch (RemoteException e) {
15761            }
15762            if (ii == null) {
15763                reportStartInstrumentationFailure(watcher, className,
15764                        "Unable to find instrumentation info for: " + className);
15765                return false;
15766            }
15767            if (ai == null) {
15768                reportStartInstrumentationFailure(watcher, className,
15769                        "Unable to find instrumentation target package: " + ii.targetPackage);
15770                return false;
15771            }
15772
15773            int match = mContext.getPackageManager().checkSignatures(
15774                    ii.targetPackage, ii.packageName);
15775            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15776                String msg = "Permission Denial: starting instrumentation "
15777                        + className + " from pid="
15778                        + Binder.getCallingPid()
15779                        + ", uid=" + Binder.getCallingPid()
15780                        + " not allowed because package " + ii.packageName
15781                        + " does not have a signature matching the target "
15782                        + ii.targetPackage;
15783                reportStartInstrumentationFailure(watcher, className, msg);
15784                throw new SecurityException(msg);
15785            }
15786
15787            final long origId = Binder.clearCallingIdentity();
15788            // Instrumentation can kill and relaunch even persistent processes
15789            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15790                    "start instr");
15791            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15792            app.instrumentationClass = className;
15793            app.instrumentationInfo = ai;
15794            app.instrumentationProfileFile = profileFile;
15795            app.instrumentationArguments = arguments;
15796            app.instrumentationWatcher = watcher;
15797            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15798            app.instrumentationResultClass = className;
15799            Binder.restoreCallingIdentity(origId);
15800        }
15801
15802        return true;
15803    }
15804
15805    /**
15806     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15807     * error to the logs, but if somebody is watching, send the report there too.  This enables
15808     * the "am" command to report errors with more information.
15809     *
15810     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15811     * @param cn The component name of the instrumentation.
15812     * @param report The error report.
15813     */
15814    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15815            ComponentName cn, String report) {
15816        Slog.w(TAG, report);
15817        try {
15818            if (watcher != null) {
15819                Bundle results = new Bundle();
15820                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15821                results.putString("Error", report);
15822                watcher.instrumentationStatus(cn, -1, results);
15823            }
15824        } catch (RemoteException e) {
15825            Slog.w(TAG, e);
15826        }
15827    }
15828
15829    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15830        if (app.instrumentationWatcher != null) {
15831            try {
15832                // NOTE:  IInstrumentationWatcher *must* be oneway here
15833                app.instrumentationWatcher.instrumentationFinished(
15834                    app.instrumentationClass,
15835                    resultCode,
15836                    results);
15837            } catch (RemoteException e) {
15838            }
15839        }
15840        if (app.instrumentationUiAutomationConnection != null) {
15841            try {
15842                app.instrumentationUiAutomationConnection.shutdown();
15843            } catch (RemoteException re) {
15844                /* ignore */
15845            }
15846            // Only a UiAutomation can set this flag and now that
15847            // it is finished we make sure it is reset to its default.
15848            mUserIsMonkey = false;
15849        }
15850        app.instrumentationWatcher = null;
15851        app.instrumentationUiAutomationConnection = null;
15852        app.instrumentationClass = null;
15853        app.instrumentationInfo = null;
15854        app.instrumentationProfileFile = null;
15855        app.instrumentationArguments = null;
15856
15857        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15858                "finished inst");
15859    }
15860
15861    public void finishInstrumentation(IApplicationThread target,
15862            int resultCode, Bundle results) {
15863        int userId = UserHandle.getCallingUserId();
15864        // Refuse possible leaked file descriptors
15865        if (results != null && results.hasFileDescriptors()) {
15866            throw new IllegalArgumentException("File descriptors passed in Intent");
15867        }
15868
15869        synchronized(this) {
15870            ProcessRecord app = getRecordForAppLocked(target);
15871            if (app == null) {
15872                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15873                return;
15874            }
15875            final long origId = Binder.clearCallingIdentity();
15876            finishInstrumentationLocked(app, resultCode, results);
15877            Binder.restoreCallingIdentity(origId);
15878        }
15879    }
15880
15881    // =========================================================
15882    // CONFIGURATION
15883    // =========================================================
15884
15885    public ConfigurationInfo getDeviceConfigurationInfo() {
15886        ConfigurationInfo config = new ConfigurationInfo();
15887        synchronized (this) {
15888            config.reqTouchScreen = mConfiguration.touchscreen;
15889            config.reqKeyboardType = mConfiguration.keyboard;
15890            config.reqNavigation = mConfiguration.navigation;
15891            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15892                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15893                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15894            }
15895            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15896                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15897                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15898            }
15899            config.reqGlEsVersion = GL_ES_VERSION;
15900        }
15901        return config;
15902    }
15903
15904    ActivityStack getFocusedStack() {
15905        return mStackSupervisor.getFocusedStack();
15906    }
15907
15908    public Configuration getConfiguration() {
15909        Configuration ci;
15910        synchronized(this) {
15911            ci = new Configuration(mConfiguration);
15912        }
15913        return ci;
15914    }
15915
15916    public void updatePersistentConfiguration(Configuration values) {
15917        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15918                "updateConfiguration()");
15919        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15920                "updateConfiguration()");
15921        if (values == null) {
15922            throw new NullPointerException("Configuration must not be null");
15923        }
15924
15925        synchronized(this) {
15926            final long origId = Binder.clearCallingIdentity();
15927            updateConfigurationLocked(values, null, true, false);
15928            Binder.restoreCallingIdentity(origId);
15929        }
15930    }
15931
15932    public void updateConfiguration(Configuration values) {
15933        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15934                "updateConfiguration()");
15935
15936        synchronized(this) {
15937            if (values == null && mWindowManager != null) {
15938                // sentinel: fetch the current configuration from the window manager
15939                values = mWindowManager.computeNewConfiguration();
15940            }
15941
15942            if (mWindowManager != null) {
15943                mProcessList.applyDisplaySize(mWindowManager);
15944            }
15945
15946            final long origId = Binder.clearCallingIdentity();
15947            if (values != null) {
15948                Settings.System.clearConfiguration(values);
15949            }
15950            updateConfigurationLocked(values, null, false, false);
15951            Binder.restoreCallingIdentity(origId);
15952        }
15953    }
15954
15955    /**
15956     * Do either or both things: (1) change the current configuration, and (2)
15957     * make sure the given activity is running with the (now) current
15958     * configuration.  Returns true if the activity has been left running, or
15959     * false if <var>starting</var> is being destroyed to match the new
15960     * configuration.
15961     * @param persistent TODO
15962     */
15963    boolean updateConfigurationLocked(Configuration values,
15964            ActivityRecord starting, boolean persistent, boolean initLocale) {
15965        int changes = 0;
15966
15967        if (values != null) {
15968            Configuration newConfig = new Configuration(mConfiguration);
15969            changes = newConfig.updateFrom(values);
15970            if (changes != 0) {
15971                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15972                    Slog.i(TAG, "Updating configuration to: " + values);
15973                }
15974
15975                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15976
15977                if (values.locale != null && !initLocale) {
15978                    saveLocaleLocked(values.locale,
15979                                     !values.locale.equals(mConfiguration.locale),
15980                                     values.userSetLocale);
15981                }
15982
15983                mConfigurationSeq++;
15984                if (mConfigurationSeq <= 0) {
15985                    mConfigurationSeq = 1;
15986                }
15987                newConfig.seq = mConfigurationSeq;
15988                mConfiguration = newConfig;
15989                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15990                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
15991                //mUsageStatsService.noteStartConfig(newConfig);
15992
15993                final Configuration configCopy = new Configuration(mConfiguration);
15994
15995                // TODO: If our config changes, should we auto dismiss any currently
15996                // showing dialogs?
15997                mShowDialogs = shouldShowDialogs(newConfig);
15998
15999                AttributeCache ac = AttributeCache.instance();
16000                if (ac != null) {
16001                    ac.updateConfiguration(configCopy);
16002                }
16003
16004                // Make sure all resources in our process are updated
16005                // right now, so that anyone who is going to retrieve
16006                // resource values after we return will be sure to get
16007                // the new ones.  This is especially important during
16008                // boot, where the first config change needs to guarantee
16009                // all resources have that config before following boot
16010                // code is executed.
16011                mSystemThread.applyConfigurationToResources(configCopy);
16012
16013                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16014                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16015                    msg.obj = new Configuration(configCopy);
16016                    mHandler.sendMessage(msg);
16017                }
16018
16019                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16020                    ProcessRecord app = mLruProcesses.get(i);
16021                    try {
16022                        if (app.thread != null) {
16023                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16024                                    + app.processName + " new config " + mConfiguration);
16025                            app.thread.scheduleConfigurationChanged(configCopy);
16026                        }
16027                    } catch (Exception e) {
16028                    }
16029                }
16030                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16031                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16032                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16033                        | Intent.FLAG_RECEIVER_FOREGROUND);
16034                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16035                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16036                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16037                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16038                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16039                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16040                    broadcastIntentLocked(null, null, intent,
16041                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16042                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16043                }
16044            }
16045        }
16046
16047        boolean kept = true;
16048        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16049        // mainStack is null during startup.
16050        if (mainStack != null) {
16051            if (changes != 0 && starting == null) {
16052                // If the configuration changed, and the caller is not already
16053                // in the process of starting an activity, then find the top
16054                // activity to check if its configuration needs to change.
16055                starting = mainStack.topRunningActivityLocked(null);
16056            }
16057
16058            if (starting != null) {
16059                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16060                // And we need to make sure at this point that all other activities
16061                // are made visible with the correct configuration.
16062                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16063            }
16064        }
16065
16066        if (values != null && mWindowManager != null) {
16067            mWindowManager.setNewConfiguration(mConfiguration);
16068        }
16069
16070        return kept;
16071    }
16072
16073    /**
16074     * Decide based on the configuration whether we should shouw the ANR,
16075     * crash, etc dialogs.  The idea is that if there is no affordnace to
16076     * press the on-screen buttons, we shouldn't show the dialog.
16077     *
16078     * A thought: SystemUI might also want to get told about this, the Power
16079     * dialog / global actions also might want different behaviors.
16080     */
16081    private static final boolean shouldShowDialogs(Configuration config) {
16082        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16083                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16084    }
16085
16086    /**
16087     * Save the locale.  You must be inside a synchronized (this) block.
16088     */
16089    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16090        if(isDiff) {
16091            SystemProperties.set("user.language", l.getLanguage());
16092            SystemProperties.set("user.region", l.getCountry());
16093        }
16094
16095        if(isPersist) {
16096            SystemProperties.set("persist.sys.language", l.getLanguage());
16097            SystemProperties.set("persist.sys.country", l.getCountry());
16098            SystemProperties.set("persist.sys.localevar", l.getVariant());
16099        }
16100    }
16101
16102    @Override
16103    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16104        synchronized (this) {
16105            ActivityRecord srec = ActivityRecord.forToken(token);
16106            if (srec.task != null && srec.task.stack != null) {
16107                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16108            }
16109        }
16110        return false;
16111    }
16112
16113    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16114            Intent resultData) {
16115
16116        synchronized (this) {
16117            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16118            if (stack != null) {
16119                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16120            }
16121            return false;
16122        }
16123    }
16124
16125    public int getLaunchedFromUid(IBinder activityToken) {
16126        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16127        if (srec == null) {
16128            return -1;
16129        }
16130        return srec.launchedFromUid;
16131    }
16132
16133    public String getLaunchedFromPackage(IBinder activityToken) {
16134        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16135        if (srec == null) {
16136            return null;
16137        }
16138        return srec.launchedFromPackage;
16139    }
16140
16141    // =========================================================
16142    // LIFETIME MANAGEMENT
16143    // =========================================================
16144
16145    // Returns which broadcast queue the app is the current [or imminent] receiver
16146    // on, or 'null' if the app is not an active broadcast recipient.
16147    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16148        BroadcastRecord r = app.curReceiver;
16149        if (r != null) {
16150            return r.queue;
16151        }
16152
16153        // It's not the current receiver, but it might be starting up to become one
16154        synchronized (this) {
16155            for (BroadcastQueue queue : mBroadcastQueues) {
16156                r = queue.mPendingBroadcast;
16157                if (r != null && r.curApp == app) {
16158                    // found it; report which queue it's in
16159                    return queue;
16160                }
16161            }
16162        }
16163
16164        return null;
16165    }
16166
16167    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16168            boolean doingAll, long now) {
16169        if (mAdjSeq == app.adjSeq) {
16170            // This adjustment has already been computed.
16171            return app.curRawAdj;
16172        }
16173
16174        if (app.thread == null) {
16175            app.adjSeq = mAdjSeq;
16176            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16177            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16178            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16179        }
16180
16181        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16182        app.adjSource = null;
16183        app.adjTarget = null;
16184        app.empty = false;
16185        app.cached = false;
16186
16187        final int activitiesSize = app.activities.size();
16188
16189        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16190            // The max adjustment doesn't allow this app to be anything
16191            // below foreground, so it is not worth doing work for it.
16192            app.adjType = "fixed";
16193            app.adjSeq = mAdjSeq;
16194            app.curRawAdj = app.maxAdj;
16195            app.foregroundActivities = false;
16196            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16197            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16198            // System processes can do UI, and when they do we want to have
16199            // them trim their memory after the user leaves the UI.  To
16200            // facilitate this, here we need to determine whether or not it
16201            // is currently showing UI.
16202            app.systemNoUi = true;
16203            if (app == TOP_APP) {
16204                app.systemNoUi = false;
16205            } else if (activitiesSize > 0) {
16206                for (int j = 0; j < activitiesSize; j++) {
16207                    final ActivityRecord r = app.activities.get(j);
16208                    if (r.visible) {
16209                        app.systemNoUi = false;
16210                    }
16211                }
16212            }
16213            if (!app.systemNoUi) {
16214                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16215            }
16216            return (app.curAdj=app.maxAdj);
16217        }
16218
16219        app.systemNoUi = false;
16220
16221        // Determine the importance of the process, starting with most
16222        // important to least, and assign an appropriate OOM adjustment.
16223        int adj;
16224        int schedGroup;
16225        int procState;
16226        boolean foregroundActivities = false;
16227        BroadcastQueue queue;
16228        if (app == TOP_APP) {
16229            // The last app on the list is the foreground app.
16230            adj = ProcessList.FOREGROUND_APP_ADJ;
16231            schedGroup = Process.THREAD_GROUP_DEFAULT;
16232            app.adjType = "top-activity";
16233            foregroundActivities = true;
16234            procState = ActivityManager.PROCESS_STATE_TOP;
16235        } else if (app.instrumentationClass != null) {
16236            // Don't want to kill running instrumentation.
16237            adj = ProcessList.FOREGROUND_APP_ADJ;
16238            schedGroup = Process.THREAD_GROUP_DEFAULT;
16239            app.adjType = "instrumentation";
16240            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16241        } else if ((queue = isReceivingBroadcast(app)) != null) {
16242            // An app that is currently receiving a broadcast also
16243            // counts as being in the foreground for OOM killer purposes.
16244            // It's placed in a sched group based on the nature of the
16245            // broadcast as reflected by which queue it's active in.
16246            adj = ProcessList.FOREGROUND_APP_ADJ;
16247            schedGroup = (queue == mFgBroadcastQueue)
16248                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16249            app.adjType = "broadcast";
16250            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16251        } else if (app.executingServices.size() > 0) {
16252            // An app that is currently executing a service callback also
16253            // counts as being in the foreground.
16254            adj = ProcessList.FOREGROUND_APP_ADJ;
16255            schedGroup = app.execServicesFg ?
16256                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16257            app.adjType = "exec-service";
16258            procState = ActivityManager.PROCESS_STATE_SERVICE;
16259            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16260        } else {
16261            // As far as we know the process is empty.  We may change our mind later.
16262            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16263            // At this point we don't actually know the adjustment.  Use the cached adj
16264            // value that the caller wants us to.
16265            adj = cachedAdj;
16266            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16267            app.cached = true;
16268            app.empty = true;
16269            app.adjType = "cch-empty";
16270        }
16271
16272        // Examine all activities if not already foreground.
16273        if (!foregroundActivities && activitiesSize > 0) {
16274            for (int j = 0; j < activitiesSize; j++) {
16275                final ActivityRecord r = app.activities.get(j);
16276                if (r.app != app) {
16277                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16278                            + app + "?!?");
16279                    continue;
16280                }
16281                if (r.visible) {
16282                    // App has a visible activity; only upgrade adjustment.
16283                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16284                        adj = ProcessList.VISIBLE_APP_ADJ;
16285                        app.adjType = "visible";
16286                    }
16287                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16288                        procState = ActivityManager.PROCESS_STATE_TOP;
16289                    }
16290                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16291                    app.cached = false;
16292                    app.empty = false;
16293                    foregroundActivities = true;
16294                    break;
16295                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16296                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16297                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16298                        app.adjType = "pausing";
16299                    }
16300                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16301                        procState = ActivityManager.PROCESS_STATE_TOP;
16302                    }
16303                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16304                    app.cached = false;
16305                    app.empty = false;
16306                    foregroundActivities = true;
16307                } else if (r.state == ActivityState.STOPPING) {
16308                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16309                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16310                        app.adjType = "stopping";
16311                    }
16312                    // For the process state, we will at this point consider the
16313                    // process to be cached.  It will be cached either as an activity
16314                    // or empty depending on whether the activity is finishing.  We do
16315                    // this so that we can treat the process as cached for purposes of
16316                    // memory trimming (determing current memory level, trim command to
16317                    // send to process) since there can be an arbitrary number of stopping
16318                    // processes and they should soon all go into the cached state.
16319                    if (!r.finishing) {
16320                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16321                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16322                        }
16323                    }
16324                    app.cached = false;
16325                    app.empty = false;
16326                    foregroundActivities = true;
16327                } else {
16328                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16329                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16330                        app.adjType = "cch-act";
16331                    }
16332                }
16333            }
16334        }
16335
16336        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16337            if (app.foregroundServices) {
16338                // The user is aware of this app, so make it visible.
16339                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16340                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16341                app.cached = false;
16342                app.adjType = "fg-service";
16343                schedGroup = Process.THREAD_GROUP_DEFAULT;
16344            } else if (app.forcingToForeground != null) {
16345                // The user is aware of this app, so make it visible.
16346                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16347                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16348                app.cached = false;
16349                app.adjType = "force-fg";
16350                app.adjSource = app.forcingToForeground;
16351                schedGroup = Process.THREAD_GROUP_DEFAULT;
16352            }
16353        }
16354
16355        if (app == mHeavyWeightProcess) {
16356            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16357                // We don't want to kill the current heavy-weight process.
16358                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16359                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16360                app.cached = false;
16361                app.adjType = "heavy";
16362            }
16363            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16364                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16365            }
16366        }
16367
16368        if (app == mHomeProcess) {
16369            if (adj > ProcessList.HOME_APP_ADJ) {
16370                // This process is hosting what we currently consider to be the
16371                // home app, so we don't want to let it go into the background.
16372                adj = ProcessList.HOME_APP_ADJ;
16373                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16374                app.cached = false;
16375                app.adjType = "home";
16376            }
16377            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16378                procState = ActivityManager.PROCESS_STATE_HOME;
16379            }
16380        }
16381
16382        if (app == mPreviousProcess && app.activities.size() > 0) {
16383            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16384                // This was the previous process that showed UI to the user.
16385                // We want to try to keep it around more aggressively, to give
16386                // a good experience around switching between two apps.
16387                adj = ProcessList.PREVIOUS_APP_ADJ;
16388                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16389                app.cached = false;
16390                app.adjType = "previous";
16391            }
16392            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16393                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16394            }
16395        }
16396
16397        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16398                + " reason=" + app.adjType);
16399
16400        // By default, we use the computed adjustment.  It may be changed if
16401        // there are applications dependent on our services or providers, but
16402        // this gives us a baseline and makes sure we don't get into an
16403        // infinite recursion.
16404        app.adjSeq = mAdjSeq;
16405        app.curRawAdj = adj;
16406        app.hasStartedServices = false;
16407
16408        if (mBackupTarget != null && app == mBackupTarget.app) {
16409            // If possible we want to avoid killing apps while they're being backed up
16410            if (adj > ProcessList.BACKUP_APP_ADJ) {
16411                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16412                adj = ProcessList.BACKUP_APP_ADJ;
16413                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16414                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16415                }
16416                app.adjType = "backup";
16417                app.cached = false;
16418            }
16419            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16420                procState = ActivityManager.PROCESS_STATE_BACKUP;
16421            }
16422        }
16423
16424        boolean mayBeTop = false;
16425
16426        for (int is = app.services.size()-1;
16427                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16428                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16429                        || procState > ActivityManager.PROCESS_STATE_TOP);
16430                is--) {
16431            ServiceRecord s = app.services.valueAt(is);
16432            if (s.startRequested) {
16433                app.hasStartedServices = true;
16434                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16435                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16436                }
16437                if (app.hasShownUi && app != mHomeProcess) {
16438                    // If this process has shown some UI, let it immediately
16439                    // go to the LRU list because it may be pretty heavy with
16440                    // UI stuff.  We'll tag it with a label just to help
16441                    // debug and understand what is going on.
16442                    if (adj > ProcessList.SERVICE_ADJ) {
16443                        app.adjType = "cch-started-ui-services";
16444                    }
16445                } else {
16446                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16447                        // This service has seen some activity within
16448                        // recent memory, so we will keep its process ahead
16449                        // of the background processes.
16450                        if (adj > ProcessList.SERVICE_ADJ) {
16451                            adj = ProcessList.SERVICE_ADJ;
16452                            app.adjType = "started-services";
16453                            app.cached = false;
16454                        }
16455                    }
16456                    // If we have let the service slide into the background
16457                    // state, still have some text describing what it is doing
16458                    // even though the service no longer has an impact.
16459                    if (adj > ProcessList.SERVICE_ADJ) {
16460                        app.adjType = "cch-started-services";
16461                    }
16462                }
16463            }
16464            for (int conni = s.connections.size()-1;
16465                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16466                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16467                            || procState > ActivityManager.PROCESS_STATE_TOP);
16468                    conni--) {
16469                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16470                for (int i = 0;
16471                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16472                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16473                                || procState > ActivityManager.PROCESS_STATE_TOP);
16474                        i++) {
16475                    // XXX should compute this based on the max of
16476                    // all connected clients.
16477                    ConnectionRecord cr = clist.get(i);
16478                    if (cr.binding.client == app) {
16479                        // Binding to ourself is not interesting.
16480                        continue;
16481                    }
16482                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16483                        ProcessRecord client = cr.binding.client;
16484                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16485                                TOP_APP, doingAll, now);
16486                        int clientProcState = client.curProcState;
16487                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16488                            // If the other app is cached for any reason, for purposes here
16489                            // we are going to consider it empty.  The specific cached state
16490                            // doesn't propagate except under certain conditions.
16491                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16492                        }
16493                        String adjType = null;
16494                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16495                            // Not doing bind OOM management, so treat
16496                            // this guy more like a started service.
16497                            if (app.hasShownUi && app != mHomeProcess) {
16498                                // If this process has shown some UI, let it immediately
16499                                // go to the LRU list because it may be pretty heavy with
16500                                // UI stuff.  We'll tag it with a label just to help
16501                                // debug and understand what is going on.
16502                                if (adj > clientAdj) {
16503                                    adjType = "cch-bound-ui-services";
16504                                }
16505                                app.cached = false;
16506                                clientAdj = adj;
16507                                clientProcState = procState;
16508                            } else {
16509                                if (now >= (s.lastActivity
16510                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16511                                    // This service has not seen activity within
16512                                    // recent memory, so allow it to drop to the
16513                                    // LRU list if there is no other reason to keep
16514                                    // it around.  We'll also tag it with a label just
16515                                    // to help debug and undertand what is going on.
16516                                    if (adj > clientAdj) {
16517                                        adjType = "cch-bound-services";
16518                                    }
16519                                    clientAdj = adj;
16520                                }
16521                            }
16522                        }
16523                        if (adj > clientAdj) {
16524                            // If this process has recently shown UI, and
16525                            // the process that is binding to it is less
16526                            // important than being visible, then we don't
16527                            // care about the binding as much as we care
16528                            // about letting this process get into the LRU
16529                            // list to be killed and restarted if needed for
16530                            // memory.
16531                            if (app.hasShownUi && app != mHomeProcess
16532                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16533                                adjType = "cch-bound-ui-services";
16534                            } else {
16535                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16536                                        |Context.BIND_IMPORTANT)) != 0) {
16537                                    adj = clientAdj;
16538                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16539                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16540                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16541                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16542                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16543                                    adj = clientAdj;
16544                                } else {
16545                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16546                                        adj = ProcessList.VISIBLE_APP_ADJ;
16547                                    }
16548                                }
16549                                if (!client.cached) {
16550                                    app.cached = false;
16551                                }
16552                                adjType = "service";
16553                            }
16554                        }
16555                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16556                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16557                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16558                            }
16559                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16560                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16561                                    // Special handling of clients who are in the top state.
16562                                    // We *may* want to consider this process to be in the
16563                                    // top state as well, but only if there is not another
16564                                    // reason for it to be running.  Being on the top is a
16565                                    // special state, meaning you are specifically running
16566                                    // for the current top app.  If the process is already
16567                                    // running in the background for some other reason, it
16568                                    // is more important to continue considering it to be
16569                                    // in the background state.
16570                                    mayBeTop = true;
16571                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16572                                } else {
16573                                    // Special handling for above-top states (persistent
16574                                    // processes).  These should not bring the current process
16575                                    // into the top state, since they are not on top.  Instead
16576                                    // give them the best state after that.
16577                                    clientProcState =
16578                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16579                                }
16580                            }
16581                        } else {
16582                            if (clientProcState <
16583                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16584                                clientProcState =
16585                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16586                            }
16587                        }
16588                        if (procState > clientProcState) {
16589                            procState = clientProcState;
16590                        }
16591                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16592                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16593                            app.pendingUiClean = true;
16594                        }
16595                        if (adjType != null) {
16596                            app.adjType = adjType;
16597                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16598                                    .REASON_SERVICE_IN_USE;
16599                            app.adjSource = cr.binding.client;
16600                            app.adjSourceProcState = clientProcState;
16601                            app.adjTarget = s.name;
16602                        }
16603                    }
16604                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16605                        app.treatLikeActivity = true;
16606                    }
16607                    final ActivityRecord a = cr.activity;
16608                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16609                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16610                                (a.visible || a.state == ActivityState.RESUMED
16611                                 || a.state == ActivityState.PAUSING)) {
16612                            adj = ProcessList.FOREGROUND_APP_ADJ;
16613                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16614                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16615                            }
16616                            app.cached = false;
16617                            app.adjType = "service";
16618                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16619                                    .REASON_SERVICE_IN_USE;
16620                            app.adjSource = a;
16621                            app.adjSourceProcState = procState;
16622                            app.adjTarget = s.name;
16623                        }
16624                    }
16625                }
16626            }
16627        }
16628
16629        for (int provi = app.pubProviders.size()-1;
16630                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16631                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16632                        || procState > ActivityManager.PROCESS_STATE_TOP);
16633                provi--) {
16634            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16635            for (int i = cpr.connections.size()-1;
16636                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16637                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16638                            || procState > ActivityManager.PROCESS_STATE_TOP);
16639                    i--) {
16640                ContentProviderConnection conn = cpr.connections.get(i);
16641                ProcessRecord client = conn.client;
16642                if (client == app) {
16643                    // Being our own client is not interesting.
16644                    continue;
16645                }
16646                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16647                int clientProcState = client.curProcState;
16648                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16649                    // If the other app is cached for any reason, for purposes here
16650                    // we are going to consider it empty.
16651                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16652                }
16653                if (adj > clientAdj) {
16654                    if (app.hasShownUi && app != mHomeProcess
16655                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16656                        app.adjType = "cch-ui-provider";
16657                    } else {
16658                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16659                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16660                        app.adjType = "provider";
16661                    }
16662                    app.cached &= client.cached;
16663                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16664                            .REASON_PROVIDER_IN_USE;
16665                    app.adjSource = client;
16666                    app.adjSourceProcState = clientProcState;
16667                    app.adjTarget = cpr.name;
16668                }
16669                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16670                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16671                        // Special handling of clients who are in the top state.
16672                        // We *may* want to consider this process to be in the
16673                        // top state as well, but only if there is not another
16674                        // reason for it to be running.  Being on the top is a
16675                        // special state, meaning you are specifically running
16676                        // for the current top app.  If the process is already
16677                        // running in the background for some other reason, it
16678                        // is more important to continue considering it to be
16679                        // in the background state.
16680                        mayBeTop = true;
16681                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16682                    } else {
16683                        // Special handling for above-top states (persistent
16684                        // processes).  These should not bring the current process
16685                        // into the top state, since they are not on top.  Instead
16686                        // give them the best state after that.
16687                        clientProcState =
16688                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16689                    }
16690                }
16691                if (procState > clientProcState) {
16692                    procState = clientProcState;
16693                }
16694                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16695                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16696                }
16697            }
16698            // If the provider has external (non-framework) process
16699            // dependencies, ensure that its adjustment is at least
16700            // FOREGROUND_APP_ADJ.
16701            if (cpr.hasExternalProcessHandles()) {
16702                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16703                    adj = ProcessList.FOREGROUND_APP_ADJ;
16704                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16705                    app.cached = false;
16706                    app.adjType = "provider";
16707                    app.adjTarget = cpr.name;
16708                }
16709                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16710                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16711                }
16712            }
16713        }
16714
16715        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16716            // A client of one of our services or providers is in the top state.  We
16717            // *may* want to be in the top state, but not if we are already running in
16718            // the background for some other reason.  For the decision here, we are going
16719            // to pick out a few specific states that we want to remain in when a client
16720            // is top (states that tend to be longer-term) and otherwise allow it to go
16721            // to the top state.
16722            switch (procState) {
16723                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16724                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16725                case ActivityManager.PROCESS_STATE_SERVICE:
16726                    // These all are longer-term states, so pull them up to the top
16727                    // of the background states, but not all the way to the top state.
16728                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16729                    break;
16730                default:
16731                    // Otherwise, top is a better choice, so take it.
16732                    procState = ActivityManager.PROCESS_STATE_TOP;
16733                    break;
16734            }
16735        }
16736
16737        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16738            if (app.hasClientActivities) {
16739                // This is a cached process, but with client activities.  Mark it so.
16740                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16741                app.adjType = "cch-client-act";
16742            } else if (app.treatLikeActivity) {
16743                // This is a cached process, but somebody wants us to treat it like it has
16744                // an activity, okay!
16745                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16746                app.adjType = "cch-as-act";
16747            }
16748        }
16749
16750        if (adj == ProcessList.SERVICE_ADJ) {
16751            if (doingAll) {
16752                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16753                mNewNumServiceProcs++;
16754                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16755                if (!app.serviceb) {
16756                    // This service isn't far enough down on the LRU list to
16757                    // normally be a B service, but if we are low on RAM and it
16758                    // is large we want to force it down since we would prefer to
16759                    // keep launcher over it.
16760                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16761                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16762                        app.serviceHighRam = true;
16763                        app.serviceb = true;
16764                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16765                    } else {
16766                        mNewNumAServiceProcs++;
16767                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16768                    }
16769                } else {
16770                    app.serviceHighRam = false;
16771                }
16772            }
16773            if (app.serviceb) {
16774                adj = ProcessList.SERVICE_B_ADJ;
16775            }
16776        }
16777
16778        app.curRawAdj = adj;
16779
16780        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16781        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16782        if (adj > app.maxAdj) {
16783            adj = app.maxAdj;
16784            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16785                schedGroup = Process.THREAD_GROUP_DEFAULT;
16786            }
16787        }
16788
16789        // Do final modification to adj.  Everything we do between here and applying
16790        // the final setAdj must be done in this function, because we will also use
16791        // it when computing the final cached adj later.  Note that we don't need to
16792        // worry about this for max adj above, since max adj will always be used to
16793        // keep it out of the cached vaues.
16794        app.curAdj = app.modifyRawOomAdj(adj);
16795        app.curSchedGroup = schedGroup;
16796        app.curProcState = procState;
16797        app.foregroundActivities = foregroundActivities;
16798
16799        return app.curRawAdj;
16800    }
16801
16802    /**
16803     * Schedule PSS collection of a process.
16804     */
16805    void requestPssLocked(ProcessRecord proc, int procState) {
16806        if (mPendingPssProcesses.contains(proc)) {
16807            return;
16808        }
16809        if (mPendingPssProcesses.size() == 0) {
16810            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16811        }
16812        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16813        proc.pssProcState = procState;
16814        mPendingPssProcesses.add(proc);
16815    }
16816
16817    /**
16818     * Schedule PSS collection of all processes.
16819     */
16820    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16821        if (!always) {
16822            if (now < (mLastFullPssTime +
16823                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16824                return;
16825            }
16826        }
16827        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16828        mLastFullPssTime = now;
16829        mFullPssPending = true;
16830        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16831        mPendingPssProcesses.clear();
16832        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16833            ProcessRecord app = mLruProcesses.get(i);
16834            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16835                app.pssProcState = app.setProcState;
16836                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16837                        isSleeping(), now);
16838                mPendingPssProcesses.add(app);
16839            }
16840        }
16841        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16842    }
16843
16844    /**
16845     * Ask a given process to GC right now.
16846     */
16847    final void performAppGcLocked(ProcessRecord app) {
16848        try {
16849            app.lastRequestedGc = SystemClock.uptimeMillis();
16850            if (app.thread != null) {
16851                if (app.reportLowMemory) {
16852                    app.reportLowMemory = false;
16853                    app.thread.scheduleLowMemory();
16854                } else {
16855                    app.thread.processInBackground();
16856                }
16857            }
16858        } catch (Exception e) {
16859            // whatever.
16860        }
16861    }
16862
16863    /**
16864     * Returns true if things are idle enough to perform GCs.
16865     */
16866    private final boolean canGcNowLocked() {
16867        boolean processingBroadcasts = false;
16868        for (BroadcastQueue q : mBroadcastQueues) {
16869            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16870                processingBroadcasts = true;
16871            }
16872        }
16873        return !processingBroadcasts
16874                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16875    }
16876
16877    /**
16878     * Perform GCs on all processes that are waiting for it, but only
16879     * if things are idle.
16880     */
16881    final void performAppGcsLocked() {
16882        final int N = mProcessesToGc.size();
16883        if (N <= 0) {
16884            return;
16885        }
16886        if (canGcNowLocked()) {
16887            while (mProcessesToGc.size() > 0) {
16888                ProcessRecord proc = mProcessesToGc.remove(0);
16889                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
16890                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
16891                            <= SystemClock.uptimeMillis()) {
16892                        // To avoid spamming the system, we will GC processes one
16893                        // at a time, waiting a few seconds between each.
16894                        performAppGcLocked(proc);
16895                        scheduleAppGcsLocked();
16896                        return;
16897                    } else {
16898                        // It hasn't been long enough since we last GCed this
16899                        // process...  put it in the list to wait for its time.
16900                        addProcessToGcListLocked(proc);
16901                        break;
16902                    }
16903                }
16904            }
16905
16906            scheduleAppGcsLocked();
16907        }
16908    }
16909
16910    /**
16911     * If all looks good, perform GCs on all processes waiting for them.
16912     */
16913    final void performAppGcsIfAppropriateLocked() {
16914        if (canGcNowLocked()) {
16915            performAppGcsLocked();
16916            return;
16917        }
16918        // Still not idle, wait some more.
16919        scheduleAppGcsLocked();
16920    }
16921
16922    /**
16923     * Schedule the execution of all pending app GCs.
16924     */
16925    final void scheduleAppGcsLocked() {
16926        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16927
16928        if (mProcessesToGc.size() > 0) {
16929            // Schedule a GC for the time to the next process.
16930            ProcessRecord proc = mProcessesToGc.get(0);
16931            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16932
16933            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16934            long now = SystemClock.uptimeMillis();
16935            if (when < (now+GC_TIMEOUT)) {
16936                when = now + GC_TIMEOUT;
16937            }
16938            mHandler.sendMessageAtTime(msg, when);
16939        }
16940    }
16941
16942    /**
16943     * Add a process to the array of processes waiting to be GCed.  Keeps the
16944     * list in sorted order by the last GC time.  The process can't already be
16945     * on the list.
16946     */
16947    final void addProcessToGcListLocked(ProcessRecord proc) {
16948        boolean added = false;
16949        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16950            if (mProcessesToGc.get(i).lastRequestedGc <
16951                    proc.lastRequestedGc) {
16952                added = true;
16953                mProcessesToGc.add(i+1, proc);
16954                break;
16955            }
16956        }
16957        if (!added) {
16958            mProcessesToGc.add(0, proc);
16959        }
16960    }
16961
16962    /**
16963     * Set up to ask a process to GC itself.  This will either do it
16964     * immediately, or put it on the list of processes to gc the next
16965     * time things are idle.
16966     */
16967    final void scheduleAppGcLocked(ProcessRecord app) {
16968        long now = SystemClock.uptimeMillis();
16969        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16970            return;
16971        }
16972        if (!mProcessesToGc.contains(app)) {
16973            addProcessToGcListLocked(app);
16974            scheduleAppGcsLocked();
16975        }
16976    }
16977
16978    final void checkExcessivePowerUsageLocked(boolean doKills) {
16979        updateCpuStatsNow();
16980
16981        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16982        boolean doWakeKills = doKills;
16983        boolean doCpuKills = doKills;
16984        if (mLastPowerCheckRealtime == 0) {
16985            doWakeKills = false;
16986        }
16987        if (mLastPowerCheckUptime == 0) {
16988            doCpuKills = false;
16989        }
16990        if (stats.isScreenOn()) {
16991            doWakeKills = false;
16992        }
16993        final long curRealtime = SystemClock.elapsedRealtime();
16994        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16995        final long curUptime = SystemClock.uptimeMillis();
16996        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16997        mLastPowerCheckRealtime = curRealtime;
16998        mLastPowerCheckUptime = curUptime;
16999        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17000            doWakeKills = false;
17001        }
17002        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17003            doCpuKills = false;
17004        }
17005        int i = mLruProcesses.size();
17006        while (i > 0) {
17007            i--;
17008            ProcessRecord app = mLruProcesses.get(i);
17009            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17010                long wtime;
17011                synchronized (stats) {
17012                    wtime = stats.getProcessWakeTime(app.info.uid,
17013                            app.pid, curRealtime);
17014                }
17015                long wtimeUsed = wtime - app.lastWakeTime;
17016                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17017                if (DEBUG_POWER) {
17018                    StringBuilder sb = new StringBuilder(128);
17019                    sb.append("Wake for ");
17020                    app.toShortString(sb);
17021                    sb.append(": over ");
17022                    TimeUtils.formatDuration(realtimeSince, sb);
17023                    sb.append(" used ");
17024                    TimeUtils.formatDuration(wtimeUsed, sb);
17025                    sb.append(" (");
17026                    sb.append((wtimeUsed*100)/realtimeSince);
17027                    sb.append("%)");
17028                    Slog.i(TAG, sb.toString());
17029                    sb.setLength(0);
17030                    sb.append("CPU for ");
17031                    app.toShortString(sb);
17032                    sb.append(": over ");
17033                    TimeUtils.formatDuration(uptimeSince, sb);
17034                    sb.append(" used ");
17035                    TimeUtils.formatDuration(cputimeUsed, sb);
17036                    sb.append(" (");
17037                    sb.append((cputimeUsed*100)/uptimeSince);
17038                    sb.append("%)");
17039                    Slog.i(TAG, sb.toString());
17040                }
17041                // If a process has held a wake lock for more
17042                // than 50% of the time during this period,
17043                // that sounds bad.  Kill!
17044                if (doWakeKills && realtimeSince > 0
17045                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17046                    synchronized (stats) {
17047                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17048                                realtimeSince, wtimeUsed);
17049                    }
17050                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17051                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17052                } else if (doCpuKills && uptimeSince > 0
17053                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17054                    synchronized (stats) {
17055                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17056                                uptimeSince, cputimeUsed);
17057                    }
17058                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17059                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17060                } else {
17061                    app.lastWakeTime = wtime;
17062                    app.lastCpuTime = app.curCpuTime;
17063                }
17064            }
17065        }
17066    }
17067
17068    private final boolean applyOomAdjLocked(ProcessRecord app,
17069            ProcessRecord TOP_APP, boolean doingAll, long now) {
17070        boolean success = true;
17071
17072        if (app.curRawAdj != app.setRawAdj) {
17073            app.setRawAdj = app.curRawAdj;
17074        }
17075
17076        int changes = 0;
17077
17078        if (app.curAdj != app.setAdj) {
17079            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17080            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17081                TAG, "Set " + app.pid + " " + app.processName +
17082                " adj " + app.curAdj + ": " + app.adjType);
17083            app.setAdj = app.curAdj;
17084        }
17085
17086        if (app.setSchedGroup != app.curSchedGroup) {
17087            app.setSchedGroup = app.curSchedGroup;
17088            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17089                    "Setting process group of " + app.processName
17090                    + " to " + app.curSchedGroup);
17091            if (app.waitingToKill != null &&
17092                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17093                app.kill(app.waitingToKill, true);
17094                success = false;
17095            } else {
17096                if (true) {
17097                    long oldId = Binder.clearCallingIdentity();
17098                    try {
17099                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17100                    } catch (Exception e) {
17101                        Slog.w(TAG, "Failed setting process group of " + app.pid
17102                                + " to " + app.curSchedGroup);
17103                        e.printStackTrace();
17104                    } finally {
17105                        Binder.restoreCallingIdentity(oldId);
17106                    }
17107                } else {
17108                    if (app.thread != null) {
17109                        try {
17110                            app.thread.setSchedulingGroup(app.curSchedGroup);
17111                        } catch (RemoteException e) {
17112                        }
17113                    }
17114                }
17115                Process.setSwappiness(app.pid,
17116                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17117            }
17118        }
17119        if (app.repForegroundActivities != app.foregroundActivities) {
17120            app.repForegroundActivities = app.foregroundActivities;
17121            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17122        }
17123        if (app.repProcState != app.curProcState) {
17124            app.repProcState = app.curProcState;
17125            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17126            if (app.thread != null) {
17127                try {
17128                    if (false) {
17129                        //RuntimeException h = new RuntimeException("here");
17130                        Slog.i(TAG, "Sending new process state " + app.repProcState
17131                                + " to " + app /*, h*/);
17132                    }
17133                    app.thread.setProcessState(app.repProcState);
17134                } catch (RemoteException e) {
17135                }
17136            }
17137        }
17138        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17139                app.setProcState)) {
17140            app.lastStateTime = now;
17141            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17142                    isSleeping(), now);
17143            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17144                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17145                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17146                    + (app.nextPssTime-now) + ": " + app);
17147        } else {
17148            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17149                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17150                requestPssLocked(app, app.setProcState);
17151                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17152                        isSleeping(), now);
17153            } else if (false && DEBUG_PSS) {
17154                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17155            }
17156        }
17157        if (app.setProcState != app.curProcState) {
17158            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17159                    "Proc state change of " + app.processName
17160                    + " to " + app.curProcState);
17161            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17162            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17163            if (setImportant && !curImportant) {
17164                // This app is no longer something we consider important enough to allow to
17165                // use arbitrary amounts of battery power.  Note
17166                // its current wake lock time to later know to kill it if
17167                // it is not behaving well.
17168                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17169                synchronized (stats) {
17170                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17171                            app.pid, SystemClock.elapsedRealtime());
17172                }
17173                app.lastCpuTime = app.curCpuTime;
17174
17175            }
17176            app.setProcState = app.curProcState;
17177            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17178                app.notCachedSinceIdle = false;
17179            }
17180            if (!doingAll) {
17181                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17182            } else {
17183                app.procStateChanged = true;
17184            }
17185        }
17186
17187        if (changes != 0) {
17188            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17189            int i = mPendingProcessChanges.size()-1;
17190            ProcessChangeItem item = null;
17191            while (i >= 0) {
17192                item = mPendingProcessChanges.get(i);
17193                if (item.pid == app.pid) {
17194                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17195                    break;
17196                }
17197                i--;
17198            }
17199            if (i < 0) {
17200                // No existing item in pending changes; need a new one.
17201                final int NA = mAvailProcessChanges.size();
17202                if (NA > 0) {
17203                    item = mAvailProcessChanges.remove(NA-1);
17204                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17205                } else {
17206                    item = new ProcessChangeItem();
17207                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17208                }
17209                item.changes = 0;
17210                item.pid = app.pid;
17211                item.uid = app.info.uid;
17212                if (mPendingProcessChanges.size() == 0) {
17213                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17214                            "*** Enqueueing dispatch processes changed!");
17215                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17216                }
17217                mPendingProcessChanges.add(item);
17218            }
17219            item.changes |= changes;
17220            item.processState = app.repProcState;
17221            item.foregroundActivities = app.repForegroundActivities;
17222            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17223                    + Integer.toHexString(System.identityHashCode(item))
17224                    + " " + app.toShortString() + ": changes=" + item.changes
17225                    + " procState=" + item.processState
17226                    + " foreground=" + item.foregroundActivities
17227                    + " type=" + app.adjType + " source=" + app.adjSource
17228                    + " target=" + app.adjTarget);
17229        }
17230
17231        return success;
17232    }
17233
17234    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17235        if (proc.thread != null) {
17236            if (proc.baseProcessTracker != null) {
17237                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17238            }
17239            if (proc.repProcState >= 0) {
17240                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17241                        proc.repProcState);
17242            }
17243        }
17244    }
17245
17246    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17247            ProcessRecord TOP_APP, boolean doingAll, long now) {
17248        if (app.thread == null) {
17249            return false;
17250        }
17251
17252        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17253
17254        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17255    }
17256
17257    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17258            boolean oomAdj) {
17259        if (isForeground != proc.foregroundServices) {
17260            proc.foregroundServices = isForeground;
17261            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17262                    proc.info.uid);
17263            if (isForeground) {
17264                if (curProcs == null) {
17265                    curProcs = new ArrayList<ProcessRecord>();
17266                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17267                }
17268                if (!curProcs.contains(proc)) {
17269                    curProcs.add(proc);
17270                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17271                            proc.info.packageName, proc.info.uid);
17272                }
17273            } else {
17274                if (curProcs != null) {
17275                    if (curProcs.remove(proc)) {
17276                        mBatteryStatsService.noteEvent(
17277                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17278                                proc.info.packageName, proc.info.uid);
17279                        if (curProcs.size() <= 0) {
17280                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17281                        }
17282                    }
17283                }
17284            }
17285            if (oomAdj) {
17286                updateOomAdjLocked();
17287            }
17288        }
17289    }
17290
17291    private final ActivityRecord resumedAppLocked() {
17292        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17293        String pkg;
17294        int uid;
17295        if (act != null) {
17296            pkg = act.packageName;
17297            uid = act.info.applicationInfo.uid;
17298        } else {
17299            pkg = null;
17300            uid = -1;
17301        }
17302        // Has the UID or resumed package name changed?
17303        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17304                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17305            if (mCurResumedPackage != null) {
17306                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17307                        mCurResumedPackage, mCurResumedUid);
17308            }
17309            mCurResumedPackage = pkg;
17310            mCurResumedUid = uid;
17311            if (mCurResumedPackage != null) {
17312                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17313                        mCurResumedPackage, mCurResumedUid);
17314            }
17315        }
17316        return act;
17317    }
17318
17319    final boolean updateOomAdjLocked(ProcessRecord app) {
17320        final ActivityRecord TOP_ACT = resumedAppLocked();
17321        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17322        final boolean wasCached = app.cached;
17323
17324        mAdjSeq++;
17325
17326        // This is the desired cached adjusment we want to tell it to use.
17327        // If our app is currently cached, we know it, and that is it.  Otherwise,
17328        // we don't know it yet, and it needs to now be cached we will then
17329        // need to do a complete oom adj.
17330        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17331                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17332        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17333                SystemClock.uptimeMillis());
17334        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17335            // Changed to/from cached state, so apps after it in the LRU
17336            // list may also be changed.
17337            updateOomAdjLocked();
17338        }
17339        return success;
17340    }
17341
17342    final void updateOomAdjLocked() {
17343        final ActivityRecord TOP_ACT = resumedAppLocked();
17344        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17345        final long now = SystemClock.uptimeMillis();
17346        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17347        final int N = mLruProcesses.size();
17348
17349        if (false) {
17350            RuntimeException e = new RuntimeException();
17351            e.fillInStackTrace();
17352            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17353        }
17354
17355        mAdjSeq++;
17356        mNewNumServiceProcs = 0;
17357        mNewNumAServiceProcs = 0;
17358
17359        final int emptyProcessLimit;
17360        final int cachedProcessLimit;
17361        if (mProcessLimit <= 0) {
17362            emptyProcessLimit = cachedProcessLimit = 0;
17363        } else if (mProcessLimit == 1) {
17364            emptyProcessLimit = 1;
17365            cachedProcessLimit = 0;
17366        } else {
17367            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17368            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17369        }
17370
17371        // Let's determine how many processes we have running vs.
17372        // how many slots we have for background processes; we may want
17373        // to put multiple processes in a slot of there are enough of
17374        // them.
17375        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17376                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17377        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17378        if (numEmptyProcs > cachedProcessLimit) {
17379            // If there are more empty processes than our limit on cached
17380            // processes, then use the cached process limit for the factor.
17381            // This ensures that the really old empty processes get pushed
17382            // down to the bottom, so if we are running low on memory we will
17383            // have a better chance at keeping around more cached processes
17384            // instead of a gazillion empty processes.
17385            numEmptyProcs = cachedProcessLimit;
17386        }
17387        int emptyFactor = numEmptyProcs/numSlots;
17388        if (emptyFactor < 1) emptyFactor = 1;
17389        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17390        if (cachedFactor < 1) cachedFactor = 1;
17391        int stepCached = 0;
17392        int stepEmpty = 0;
17393        int numCached = 0;
17394        int numEmpty = 0;
17395        int numTrimming = 0;
17396
17397        mNumNonCachedProcs = 0;
17398        mNumCachedHiddenProcs = 0;
17399
17400        // First update the OOM adjustment for each of the
17401        // application processes based on their current state.
17402        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17403        int nextCachedAdj = curCachedAdj+1;
17404        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17405        int nextEmptyAdj = curEmptyAdj+2;
17406        for (int i=N-1; i>=0; i--) {
17407            ProcessRecord app = mLruProcesses.get(i);
17408            if (!app.killedByAm && app.thread != null) {
17409                app.procStateChanged = false;
17410                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17411
17412                // If we haven't yet assigned the final cached adj
17413                // to the process, do that now.
17414                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17415                    switch (app.curProcState) {
17416                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17417                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17418                            // This process is a cached process holding activities...
17419                            // assign it the next cached value for that type, and then
17420                            // step that cached level.
17421                            app.curRawAdj = curCachedAdj;
17422                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17423                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17424                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17425                                    + ")");
17426                            if (curCachedAdj != nextCachedAdj) {
17427                                stepCached++;
17428                                if (stepCached >= cachedFactor) {
17429                                    stepCached = 0;
17430                                    curCachedAdj = nextCachedAdj;
17431                                    nextCachedAdj += 2;
17432                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17433                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17434                                    }
17435                                }
17436                            }
17437                            break;
17438                        default:
17439                            // For everything else, assign next empty cached process
17440                            // level and bump that up.  Note that this means that
17441                            // long-running services that have dropped down to the
17442                            // cached level will be treated as empty (since their process
17443                            // state is still as a service), which is what we want.
17444                            app.curRawAdj = curEmptyAdj;
17445                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17446                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17447                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17448                                    + ")");
17449                            if (curEmptyAdj != nextEmptyAdj) {
17450                                stepEmpty++;
17451                                if (stepEmpty >= emptyFactor) {
17452                                    stepEmpty = 0;
17453                                    curEmptyAdj = nextEmptyAdj;
17454                                    nextEmptyAdj += 2;
17455                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17456                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17457                                    }
17458                                }
17459                            }
17460                            break;
17461                    }
17462                }
17463
17464                applyOomAdjLocked(app, TOP_APP, true, now);
17465
17466                // Count the number of process types.
17467                switch (app.curProcState) {
17468                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17469                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17470                        mNumCachedHiddenProcs++;
17471                        numCached++;
17472                        if (numCached > cachedProcessLimit) {
17473                            app.kill("cached #" + numCached, true);
17474                        }
17475                        break;
17476                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17477                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17478                                && app.lastActivityTime < oldTime) {
17479                            app.kill("empty for "
17480                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17481                                    / 1000) + "s", true);
17482                        } else {
17483                            numEmpty++;
17484                            if (numEmpty > emptyProcessLimit) {
17485                                app.kill("empty #" + numEmpty, true);
17486                            }
17487                        }
17488                        break;
17489                    default:
17490                        mNumNonCachedProcs++;
17491                        break;
17492                }
17493
17494                if (app.isolated && app.services.size() <= 0) {
17495                    // If this is an isolated process, and there are no
17496                    // services running in it, then the process is no longer
17497                    // needed.  We agressively kill these because we can by
17498                    // definition not re-use the same process again, and it is
17499                    // good to avoid having whatever code was running in them
17500                    // left sitting around after no longer needed.
17501                    app.kill("isolated not needed", true);
17502                }
17503
17504                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17505                        && !app.killedByAm) {
17506                    numTrimming++;
17507                }
17508            }
17509        }
17510
17511        mNumServiceProcs = mNewNumServiceProcs;
17512
17513        // Now determine the memory trimming level of background processes.
17514        // Unfortunately we need to start at the back of the list to do this
17515        // properly.  We only do this if the number of background apps we
17516        // are managing to keep around is less than half the maximum we desire;
17517        // if we are keeping a good number around, we'll let them use whatever
17518        // memory they want.
17519        final int numCachedAndEmpty = numCached + numEmpty;
17520        int memFactor;
17521        if (numCached <= ProcessList.TRIM_CACHED_APPS
17522                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17523            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17524                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17525            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17526                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17527            } else {
17528                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17529            }
17530        } else {
17531            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17532        }
17533        // We always allow the memory level to go up (better).  We only allow it to go
17534        // down if we are in a state where that is allowed, *and* the total number of processes
17535        // has gone down since last time.
17536        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17537                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17538                + " last=" + mLastNumProcesses);
17539        if (memFactor > mLastMemoryLevel) {
17540            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17541                memFactor = mLastMemoryLevel;
17542                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17543            }
17544        }
17545        mLastMemoryLevel = memFactor;
17546        mLastNumProcesses = mLruProcesses.size();
17547        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17548        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17549        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17550            if (mLowRamStartTime == 0) {
17551                mLowRamStartTime = now;
17552            }
17553            int step = 0;
17554            int fgTrimLevel;
17555            switch (memFactor) {
17556                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17557                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17558                    break;
17559                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17560                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17561                    break;
17562                default:
17563                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17564                    break;
17565            }
17566            int factor = numTrimming/3;
17567            int minFactor = 2;
17568            if (mHomeProcess != null) minFactor++;
17569            if (mPreviousProcess != null) minFactor++;
17570            if (factor < minFactor) factor = minFactor;
17571            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17572            for (int i=N-1; i>=0; i--) {
17573                ProcessRecord app = mLruProcesses.get(i);
17574                if (allChanged || app.procStateChanged) {
17575                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17576                    app.procStateChanged = false;
17577                }
17578                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17579                        && !app.killedByAm) {
17580                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17581                        try {
17582                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17583                                    "Trimming memory of " + app.processName
17584                                    + " to " + curLevel);
17585                            app.thread.scheduleTrimMemory(curLevel);
17586                        } catch (RemoteException e) {
17587                        }
17588                        if (false) {
17589                            // For now we won't do this; our memory trimming seems
17590                            // to be good enough at this point that destroying
17591                            // activities causes more harm than good.
17592                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17593                                    && app != mHomeProcess && app != mPreviousProcess) {
17594                                // Need to do this on its own message because the stack may not
17595                                // be in a consistent state at this point.
17596                                // For these apps we will also finish their activities
17597                                // to help them free memory.
17598                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17599                            }
17600                        }
17601                    }
17602                    app.trimMemoryLevel = curLevel;
17603                    step++;
17604                    if (step >= factor) {
17605                        step = 0;
17606                        switch (curLevel) {
17607                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17608                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17609                                break;
17610                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17611                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17612                                break;
17613                        }
17614                    }
17615                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17616                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17617                            && app.thread != null) {
17618                        try {
17619                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17620                                    "Trimming memory of heavy-weight " + app.processName
17621                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17622                            app.thread.scheduleTrimMemory(
17623                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17624                        } catch (RemoteException e) {
17625                        }
17626                    }
17627                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17628                } else {
17629                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17630                            || app.systemNoUi) && app.pendingUiClean) {
17631                        // If this application is now in the background and it
17632                        // had done UI, then give it the special trim level to
17633                        // have it free UI resources.
17634                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17635                        if (app.trimMemoryLevel < level && app.thread != null) {
17636                            try {
17637                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17638                                        "Trimming memory of bg-ui " + app.processName
17639                                        + " to " + level);
17640                                app.thread.scheduleTrimMemory(level);
17641                            } catch (RemoteException e) {
17642                            }
17643                        }
17644                        app.pendingUiClean = false;
17645                    }
17646                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17647                        try {
17648                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17649                                    "Trimming memory of fg " + app.processName
17650                                    + " to " + fgTrimLevel);
17651                            app.thread.scheduleTrimMemory(fgTrimLevel);
17652                        } catch (RemoteException e) {
17653                        }
17654                    }
17655                    app.trimMemoryLevel = fgTrimLevel;
17656                }
17657            }
17658        } else {
17659            if (mLowRamStartTime != 0) {
17660                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17661                mLowRamStartTime = 0;
17662            }
17663            for (int i=N-1; i>=0; i--) {
17664                ProcessRecord app = mLruProcesses.get(i);
17665                if (allChanged || app.procStateChanged) {
17666                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17667                    app.procStateChanged = false;
17668                }
17669                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17670                        || app.systemNoUi) && app.pendingUiClean) {
17671                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17672                            && app.thread != null) {
17673                        try {
17674                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17675                                    "Trimming memory of ui hidden " + app.processName
17676                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17677                            app.thread.scheduleTrimMemory(
17678                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17679                        } catch (RemoteException e) {
17680                        }
17681                    }
17682                    app.pendingUiClean = false;
17683                }
17684                app.trimMemoryLevel = 0;
17685            }
17686        }
17687
17688        if (mAlwaysFinishActivities) {
17689            // Need to do this on its own message because the stack may not
17690            // be in a consistent state at this point.
17691            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17692        }
17693
17694        if (allChanged) {
17695            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17696        }
17697
17698        if (mProcessStats.shouldWriteNowLocked(now)) {
17699            mHandler.post(new Runnable() {
17700                @Override public void run() {
17701                    synchronized (ActivityManagerService.this) {
17702                        mProcessStats.writeStateAsyncLocked();
17703                    }
17704                }
17705            });
17706        }
17707
17708        if (DEBUG_OOM_ADJ) {
17709            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17710        }
17711    }
17712
17713    final void trimApplications() {
17714        synchronized (this) {
17715            int i;
17716
17717            // First remove any unused application processes whose package
17718            // has been removed.
17719            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17720                final ProcessRecord app = mRemovedProcesses.get(i);
17721                if (app.activities.size() == 0
17722                        && app.curReceiver == null && app.services.size() == 0) {
17723                    Slog.i(
17724                        TAG, "Exiting empty application process "
17725                        + app.processName + " ("
17726                        + (app.thread != null ? app.thread.asBinder() : null)
17727                        + ")\n");
17728                    if (app.pid > 0 && app.pid != MY_PID) {
17729                        app.kill("empty", false);
17730                    } else {
17731                        try {
17732                            app.thread.scheduleExit();
17733                        } catch (Exception e) {
17734                            // Ignore exceptions.
17735                        }
17736                    }
17737                    cleanUpApplicationRecordLocked(app, false, true, -1);
17738                    mRemovedProcesses.remove(i);
17739
17740                    if (app.persistent) {
17741                        addAppLocked(app.info, false, null /* ABI override */);
17742                    }
17743                }
17744            }
17745
17746            // Now update the oom adj for all processes.
17747            updateOomAdjLocked();
17748        }
17749    }
17750
17751    /** This method sends the specified signal to each of the persistent apps */
17752    public void signalPersistentProcesses(int sig) throws RemoteException {
17753        if (sig != Process.SIGNAL_USR1) {
17754            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17755        }
17756
17757        synchronized (this) {
17758            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17759                    != PackageManager.PERMISSION_GRANTED) {
17760                throw new SecurityException("Requires permission "
17761                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17762            }
17763
17764            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17765                ProcessRecord r = mLruProcesses.get(i);
17766                if (r.thread != null && r.persistent) {
17767                    Process.sendSignal(r.pid, sig);
17768                }
17769            }
17770        }
17771    }
17772
17773    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
17774        if (proc == null || proc == mProfileProc) {
17775            proc = mProfileProc;
17776            profileType = mProfileType;
17777            clearProfilerLocked();
17778        }
17779        if (proc == null) {
17780            return;
17781        }
17782        try {
17783            proc.thread.profilerControl(false, null, profileType);
17784        } catch (RemoteException e) {
17785            throw new IllegalStateException("Process disappeared");
17786        }
17787    }
17788
17789    private void clearProfilerLocked() {
17790        if (mProfileFd != null) {
17791            try {
17792                mProfileFd.close();
17793            } catch (IOException e) {
17794            }
17795        }
17796        mProfileApp = null;
17797        mProfileProc = null;
17798        mProfileFile = null;
17799        mProfileType = 0;
17800        mAutoStopProfiler = false;
17801        mSamplingInterval = 0;
17802    }
17803
17804    public boolean profileControl(String process, int userId, boolean start,
17805            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
17806
17807        try {
17808            synchronized (this) {
17809                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17810                // its own permission.
17811                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17812                        != PackageManager.PERMISSION_GRANTED) {
17813                    throw new SecurityException("Requires permission "
17814                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17815                }
17816
17817                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
17818                    throw new IllegalArgumentException("null profile info or fd");
17819                }
17820
17821                ProcessRecord proc = null;
17822                if (process != null) {
17823                    proc = findProcessLocked(process, userId, "profileControl");
17824                }
17825
17826                if (start && (proc == null || proc.thread == null)) {
17827                    throw new IllegalArgumentException("Unknown process: " + process);
17828                }
17829
17830                if (start) {
17831                    stopProfilerLocked(null, 0);
17832                    setProfileApp(proc.info, proc.processName, profilerInfo);
17833                    mProfileProc = proc;
17834                    mProfileType = profileType;
17835                    ParcelFileDescriptor fd = profilerInfo.profileFd;
17836                    try {
17837                        fd = fd.dup();
17838                    } catch (IOException e) {
17839                        fd = null;
17840                    }
17841                    profilerInfo.profileFd = fd;
17842                    proc.thread.profilerControl(start, profilerInfo, profileType);
17843                    fd = null;
17844                    mProfileFd = null;
17845                } else {
17846                    stopProfilerLocked(proc, profileType);
17847                    if (profilerInfo != null && profilerInfo.profileFd != null) {
17848                        try {
17849                            profilerInfo.profileFd.close();
17850                        } catch (IOException e) {
17851                        }
17852                    }
17853                }
17854
17855                return true;
17856            }
17857        } catch (RemoteException e) {
17858            throw new IllegalStateException("Process disappeared");
17859        } finally {
17860            if (profilerInfo != null && profilerInfo.profileFd != null) {
17861                try {
17862                    profilerInfo.profileFd.close();
17863                } catch (IOException e) {
17864                }
17865            }
17866        }
17867    }
17868
17869    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17870        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17871                userId, true, ALLOW_FULL_ONLY, callName, null);
17872        ProcessRecord proc = null;
17873        try {
17874            int pid = Integer.parseInt(process);
17875            synchronized (mPidsSelfLocked) {
17876                proc = mPidsSelfLocked.get(pid);
17877            }
17878        } catch (NumberFormatException e) {
17879        }
17880
17881        if (proc == null) {
17882            ArrayMap<String, SparseArray<ProcessRecord>> all
17883                    = mProcessNames.getMap();
17884            SparseArray<ProcessRecord> procs = all.get(process);
17885            if (procs != null && procs.size() > 0) {
17886                proc = procs.valueAt(0);
17887                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17888                    for (int i=1; i<procs.size(); i++) {
17889                        ProcessRecord thisProc = procs.valueAt(i);
17890                        if (thisProc.userId == userId) {
17891                            proc = thisProc;
17892                            break;
17893                        }
17894                    }
17895                }
17896            }
17897        }
17898
17899        return proc;
17900    }
17901
17902    public boolean dumpHeap(String process, int userId, boolean managed,
17903            String path, ParcelFileDescriptor fd) throws RemoteException {
17904
17905        try {
17906            synchronized (this) {
17907                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17908                // its own permission (same as profileControl).
17909                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17910                        != PackageManager.PERMISSION_GRANTED) {
17911                    throw new SecurityException("Requires permission "
17912                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17913                }
17914
17915                if (fd == null) {
17916                    throw new IllegalArgumentException("null fd");
17917                }
17918
17919                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17920                if (proc == null || proc.thread == null) {
17921                    throw new IllegalArgumentException("Unknown process: " + process);
17922                }
17923
17924                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17925                if (!isDebuggable) {
17926                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17927                        throw new SecurityException("Process not debuggable: " + proc);
17928                    }
17929                }
17930
17931                proc.thread.dumpHeap(managed, path, fd);
17932                fd = null;
17933                return true;
17934            }
17935        } catch (RemoteException e) {
17936            throw new IllegalStateException("Process disappeared");
17937        } finally {
17938            if (fd != null) {
17939                try {
17940                    fd.close();
17941                } catch (IOException e) {
17942                }
17943            }
17944        }
17945    }
17946
17947    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17948    public void monitor() {
17949        synchronized (this) { }
17950    }
17951
17952    void onCoreSettingsChange(Bundle settings) {
17953        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17954            ProcessRecord processRecord = mLruProcesses.get(i);
17955            try {
17956                if (processRecord.thread != null) {
17957                    processRecord.thread.setCoreSettings(settings);
17958                }
17959            } catch (RemoteException re) {
17960                /* ignore */
17961            }
17962        }
17963    }
17964
17965    // Multi-user methods
17966
17967    /**
17968     * Start user, if its not already running, but don't bring it to foreground.
17969     */
17970    @Override
17971    public boolean startUserInBackground(final int userId) {
17972        return startUser(userId, /* foreground */ false);
17973    }
17974
17975    /**
17976     * Start user, if its not already running, and bring it to foreground.
17977     */
17978    boolean startUserInForeground(final int userId, Dialog dlg) {
17979        boolean result = startUser(userId, /* foreground */ true);
17980        dlg.dismiss();
17981        return result;
17982    }
17983
17984    /**
17985     * Refreshes the list of users related to the current user when either a
17986     * user switch happens or when a new related user is started in the
17987     * background.
17988     */
17989    private void updateCurrentProfileIdsLocked() {
17990        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17991                mCurrentUserId, false /* enabledOnly */);
17992        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17993        for (int i = 0; i < currentProfileIds.length; i++) {
17994            currentProfileIds[i] = profiles.get(i).id;
17995        }
17996        mCurrentProfileIds = currentProfileIds;
17997
17998        synchronized (mUserProfileGroupIdsSelfLocked) {
17999            mUserProfileGroupIdsSelfLocked.clear();
18000            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18001            for (int i = 0; i < users.size(); i++) {
18002                UserInfo user = users.get(i);
18003                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18004                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18005                }
18006            }
18007        }
18008    }
18009
18010    private Set getProfileIdsLocked(int userId) {
18011        Set userIds = new HashSet<Integer>();
18012        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18013                userId, false /* enabledOnly */);
18014        for (UserInfo user : profiles) {
18015            userIds.add(Integer.valueOf(user.id));
18016        }
18017        return userIds;
18018    }
18019
18020    @Override
18021    public boolean switchUser(final int userId) {
18022        String userName;
18023        synchronized (this) {
18024            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18025            if (userInfo == null) {
18026                Slog.w(TAG, "No user info for user #" + userId);
18027                return false;
18028            }
18029            if (userInfo.isManagedProfile()) {
18030                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18031                return false;
18032            }
18033            userName = userInfo.name;
18034            mTargetUserId = userId;
18035        }
18036        mHandler.removeMessages(START_USER_SWITCH_MSG);
18037        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18038        return true;
18039    }
18040
18041    private void showUserSwitchDialog(int userId, String userName) {
18042        // The dialog will show and then initiate the user switch by calling startUserInForeground
18043        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18044                true /* above system */);
18045        d.show();
18046    }
18047
18048    private boolean startUser(final int userId, final boolean foreground) {
18049        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18050                != PackageManager.PERMISSION_GRANTED) {
18051            String msg = "Permission Denial: switchUser() from pid="
18052                    + Binder.getCallingPid()
18053                    + ", uid=" + Binder.getCallingUid()
18054                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18055            Slog.w(TAG, msg);
18056            throw new SecurityException(msg);
18057        }
18058
18059        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18060
18061        final long ident = Binder.clearCallingIdentity();
18062        try {
18063            synchronized (this) {
18064                final int oldUserId = mCurrentUserId;
18065                if (oldUserId == userId) {
18066                    return true;
18067                }
18068
18069                mStackSupervisor.setLockTaskModeLocked(null, false);
18070
18071                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18072                if (userInfo == null) {
18073                    Slog.w(TAG, "No user info for user #" + userId);
18074                    return false;
18075                }
18076                if (foreground && userInfo.isManagedProfile()) {
18077                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18078                    return false;
18079                }
18080
18081                if (foreground) {
18082                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18083                            R.anim.screen_user_enter);
18084                }
18085
18086                boolean needStart = false;
18087
18088                // If the user we are switching to is not currently started, then
18089                // we need to start it now.
18090                if (mStartedUsers.get(userId) == null) {
18091                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18092                    updateStartedUserArrayLocked();
18093                    needStart = true;
18094                }
18095
18096                final Integer userIdInt = Integer.valueOf(userId);
18097                mUserLru.remove(userIdInt);
18098                mUserLru.add(userIdInt);
18099
18100                if (foreground) {
18101                    mCurrentUserId = userId;
18102                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18103                    updateCurrentProfileIdsLocked();
18104                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18105                    // Once the internal notion of the active user has switched, we lock the device
18106                    // with the option to show the user switcher on the keyguard.
18107                    mWindowManager.lockNow(null);
18108                } else {
18109                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18110                    updateCurrentProfileIdsLocked();
18111                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18112                    mUserLru.remove(currentUserIdInt);
18113                    mUserLru.add(currentUserIdInt);
18114                }
18115
18116                final UserStartedState uss = mStartedUsers.get(userId);
18117
18118                // Make sure user is in the started state.  If it is currently
18119                // stopping, we need to knock that off.
18120                if (uss.mState == UserStartedState.STATE_STOPPING) {
18121                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18122                    // so we can just fairly silently bring the user back from
18123                    // the almost-dead.
18124                    uss.mState = UserStartedState.STATE_RUNNING;
18125                    updateStartedUserArrayLocked();
18126                    needStart = true;
18127                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18128                    // This means ACTION_SHUTDOWN has been sent, so we will
18129                    // need to treat this as a new boot of the user.
18130                    uss.mState = UserStartedState.STATE_BOOTING;
18131                    updateStartedUserArrayLocked();
18132                    needStart = true;
18133                }
18134
18135                if (uss.mState == UserStartedState.STATE_BOOTING) {
18136                    // Booting up a new user, need to tell system services about it.
18137                    // Note that this is on the same handler as scheduling of broadcasts,
18138                    // which is important because it needs to go first.
18139                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18140                }
18141
18142                if (foreground) {
18143                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18144                            oldUserId));
18145                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18146                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18147                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18148                            oldUserId, userId, uss));
18149                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18150                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18151                }
18152
18153                if (needStart) {
18154                    // Send USER_STARTED broadcast
18155                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18156                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18157                            | Intent.FLAG_RECEIVER_FOREGROUND);
18158                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18159                    broadcastIntentLocked(null, null, intent,
18160                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18161                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18162                }
18163
18164                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18165                    if (userId != UserHandle.USER_OWNER) {
18166                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18167                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18168                        broadcastIntentLocked(null, null, intent, null,
18169                                new IIntentReceiver.Stub() {
18170                                    public void performReceive(Intent intent, int resultCode,
18171                                            String data, Bundle extras, boolean ordered,
18172                                            boolean sticky, int sendingUser) {
18173                                        onUserInitialized(uss, foreground, oldUserId, userId);
18174                                    }
18175                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18176                                true, false, MY_PID, Process.SYSTEM_UID,
18177                                userId);
18178                        uss.initializing = true;
18179                    } else {
18180                        getUserManagerLocked().makeInitialized(userInfo.id);
18181                    }
18182                }
18183
18184                if (foreground) {
18185                    if (!uss.initializing) {
18186                        moveUserToForeground(uss, oldUserId, userId);
18187                    }
18188                } else {
18189                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18190                }
18191
18192                if (needStart) {
18193                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18194                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18195                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18196                    broadcastIntentLocked(null, null, intent,
18197                            null, new IIntentReceiver.Stub() {
18198                                @Override
18199                                public void performReceive(Intent intent, int resultCode, String data,
18200                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18201                                        throws RemoteException {
18202                                }
18203                            }, 0, null, null,
18204                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18205                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18206                }
18207            }
18208        } finally {
18209            Binder.restoreCallingIdentity(ident);
18210        }
18211
18212        return true;
18213    }
18214
18215    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18216        long ident = Binder.clearCallingIdentity();
18217        try {
18218            Intent intent;
18219            if (oldUserId >= 0) {
18220                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18221                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18222                int count = profiles.size();
18223                for (int i = 0; i < count; i++) {
18224                    int profileUserId = profiles.get(i).id;
18225                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18226                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18227                            | Intent.FLAG_RECEIVER_FOREGROUND);
18228                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18229                    broadcastIntentLocked(null, null, intent,
18230                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18231                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18232                }
18233            }
18234            if (newUserId >= 0) {
18235                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18236                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18237                int count = profiles.size();
18238                for (int i = 0; i < count; i++) {
18239                    int profileUserId = profiles.get(i).id;
18240                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18241                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18242                            | Intent.FLAG_RECEIVER_FOREGROUND);
18243                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18244                    broadcastIntentLocked(null, null, intent,
18245                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18246                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18247                }
18248                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18249                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18250                        | Intent.FLAG_RECEIVER_FOREGROUND);
18251                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18252                broadcastIntentLocked(null, null, intent,
18253                        null, null, 0, null, null,
18254                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18255                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18256            }
18257        } finally {
18258            Binder.restoreCallingIdentity(ident);
18259        }
18260    }
18261
18262    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18263            final int newUserId) {
18264        final int N = mUserSwitchObservers.beginBroadcast();
18265        if (N > 0) {
18266            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18267                int mCount = 0;
18268                @Override
18269                public void sendResult(Bundle data) throws RemoteException {
18270                    synchronized (ActivityManagerService.this) {
18271                        if (mCurUserSwitchCallback == this) {
18272                            mCount++;
18273                            if (mCount == N) {
18274                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18275                            }
18276                        }
18277                    }
18278                }
18279            };
18280            synchronized (this) {
18281                uss.switching = true;
18282                mCurUserSwitchCallback = callback;
18283            }
18284            for (int i=0; i<N; i++) {
18285                try {
18286                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18287                            newUserId, callback);
18288                } catch (RemoteException e) {
18289                }
18290            }
18291        } else {
18292            synchronized (this) {
18293                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18294            }
18295        }
18296        mUserSwitchObservers.finishBroadcast();
18297    }
18298
18299    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18300        synchronized (this) {
18301            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18302            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18303        }
18304    }
18305
18306    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18307        mCurUserSwitchCallback = null;
18308        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18309        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18310                oldUserId, newUserId, uss));
18311    }
18312
18313    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18314        synchronized (this) {
18315            if (foreground) {
18316                moveUserToForeground(uss, oldUserId, newUserId);
18317            }
18318        }
18319
18320        completeSwitchAndInitalize(uss, newUserId, true, false);
18321    }
18322
18323    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18324        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18325        if (homeInFront) {
18326            startHomeActivityLocked(newUserId);
18327        } else {
18328            mStackSupervisor.resumeTopActivitiesLocked();
18329        }
18330        EventLogTags.writeAmSwitchUser(newUserId);
18331        getUserManagerLocked().userForeground(newUserId);
18332        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18333    }
18334
18335    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18336        completeSwitchAndInitalize(uss, newUserId, false, true);
18337    }
18338
18339    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18340            boolean clearInitializing, boolean clearSwitching) {
18341        boolean unfrozen = false;
18342        synchronized (this) {
18343            if (clearInitializing) {
18344                uss.initializing = false;
18345                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18346            }
18347            if (clearSwitching) {
18348                uss.switching = false;
18349            }
18350            if (!uss.switching && !uss.initializing) {
18351                mWindowManager.stopFreezingScreen();
18352                unfrozen = true;
18353            }
18354        }
18355        if (unfrozen) {
18356            final int N = mUserSwitchObservers.beginBroadcast();
18357            for (int i=0; i<N; i++) {
18358                try {
18359                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18360                } catch (RemoteException e) {
18361                }
18362            }
18363            mUserSwitchObservers.finishBroadcast();
18364        }
18365    }
18366
18367    void scheduleStartProfilesLocked() {
18368        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18369            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18370                    DateUtils.SECOND_IN_MILLIS);
18371        }
18372    }
18373
18374    void startProfilesLocked() {
18375        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18376        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18377                mCurrentUserId, false /* enabledOnly */);
18378        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18379        for (UserInfo user : profiles) {
18380            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18381                    && user.id != mCurrentUserId) {
18382                toStart.add(user);
18383            }
18384        }
18385        final int n = toStart.size();
18386        int i = 0;
18387        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18388            startUserInBackground(toStart.get(i).id);
18389        }
18390        if (i < n) {
18391            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18392        }
18393    }
18394
18395    void finishUserBoot(UserStartedState uss) {
18396        synchronized (this) {
18397            if (uss.mState == UserStartedState.STATE_BOOTING
18398                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18399                uss.mState = UserStartedState.STATE_RUNNING;
18400                final int userId = uss.mHandle.getIdentifier();
18401                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18402                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18403                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18404                broadcastIntentLocked(null, null, intent,
18405                        null, null, 0, null, null,
18406                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18407                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18408            }
18409        }
18410    }
18411
18412    void finishUserSwitch(UserStartedState uss) {
18413        synchronized (this) {
18414            finishUserBoot(uss);
18415
18416            startProfilesLocked();
18417
18418            int num = mUserLru.size();
18419            int i = 0;
18420            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18421                Integer oldUserId = mUserLru.get(i);
18422                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18423                if (oldUss == null) {
18424                    // Shouldn't happen, but be sane if it does.
18425                    mUserLru.remove(i);
18426                    num--;
18427                    continue;
18428                }
18429                if (oldUss.mState == UserStartedState.STATE_STOPPING
18430                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18431                    // This user is already stopping, doesn't count.
18432                    num--;
18433                    i++;
18434                    continue;
18435                }
18436                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18437                    // Owner and current can't be stopped, but count as running.
18438                    i++;
18439                    continue;
18440                }
18441                // This is a user to be stopped.
18442                stopUserLocked(oldUserId, null);
18443                num--;
18444                i++;
18445            }
18446        }
18447    }
18448
18449    @Override
18450    public int stopUser(final int userId, final IStopUserCallback callback) {
18451        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18452                != PackageManager.PERMISSION_GRANTED) {
18453            String msg = "Permission Denial: switchUser() from pid="
18454                    + Binder.getCallingPid()
18455                    + ", uid=" + Binder.getCallingUid()
18456                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18457            Slog.w(TAG, msg);
18458            throw new SecurityException(msg);
18459        }
18460        if (userId <= 0) {
18461            throw new IllegalArgumentException("Can't stop primary user " + userId);
18462        }
18463        synchronized (this) {
18464            return stopUserLocked(userId, callback);
18465        }
18466    }
18467
18468    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18469        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18470        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18471            return ActivityManager.USER_OP_IS_CURRENT;
18472        }
18473
18474        final UserStartedState uss = mStartedUsers.get(userId);
18475        if (uss == null) {
18476            // User is not started, nothing to do...  but we do need to
18477            // callback if requested.
18478            if (callback != null) {
18479                mHandler.post(new Runnable() {
18480                    @Override
18481                    public void run() {
18482                        try {
18483                            callback.userStopped(userId);
18484                        } catch (RemoteException e) {
18485                        }
18486                    }
18487                });
18488            }
18489            return ActivityManager.USER_OP_SUCCESS;
18490        }
18491
18492        if (callback != null) {
18493            uss.mStopCallbacks.add(callback);
18494        }
18495
18496        if (uss.mState != UserStartedState.STATE_STOPPING
18497                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18498            uss.mState = UserStartedState.STATE_STOPPING;
18499            updateStartedUserArrayLocked();
18500
18501            long ident = Binder.clearCallingIdentity();
18502            try {
18503                // We are going to broadcast ACTION_USER_STOPPING and then
18504                // once that is done send a final ACTION_SHUTDOWN and then
18505                // stop the user.
18506                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18507                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18508                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18509                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18510                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18511                // This is the result receiver for the final shutdown broadcast.
18512                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18513                    @Override
18514                    public void performReceive(Intent intent, int resultCode, String data,
18515                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18516                        finishUserStop(uss);
18517                    }
18518                };
18519                // This is the result receiver for the initial stopping broadcast.
18520                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18521                    @Override
18522                    public void performReceive(Intent intent, int resultCode, String data,
18523                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18524                        // On to the next.
18525                        synchronized (ActivityManagerService.this) {
18526                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18527                                // Whoops, we are being started back up.  Abort, abort!
18528                                return;
18529                            }
18530                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18531                        }
18532                        mBatteryStatsService.noteEvent(
18533                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18534                                Integer.toString(userId), userId);
18535                        mSystemServiceManager.stopUser(userId);
18536                        broadcastIntentLocked(null, null, shutdownIntent,
18537                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18538                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18539                    }
18540                };
18541                // Kick things off.
18542                broadcastIntentLocked(null, null, stoppingIntent,
18543                        null, stoppingReceiver, 0, null, null,
18544                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18545                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18546            } finally {
18547                Binder.restoreCallingIdentity(ident);
18548            }
18549        }
18550
18551        return ActivityManager.USER_OP_SUCCESS;
18552    }
18553
18554    void finishUserStop(UserStartedState uss) {
18555        final int userId = uss.mHandle.getIdentifier();
18556        boolean stopped;
18557        ArrayList<IStopUserCallback> callbacks;
18558        synchronized (this) {
18559            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18560            if (mStartedUsers.get(userId) != uss) {
18561                stopped = false;
18562            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18563                stopped = false;
18564            } else {
18565                stopped = true;
18566                // User can no longer run.
18567                mStartedUsers.remove(userId);
18568                mUserLru.remove(Integer.valueOf(userId));
18569                updateStartedUserArrayLocked();
18570
18571                // Clean up all state and processes associated with the user.
18572                // Kill all the processes for the user.
18573                forceStopUserLocked(userId, "finish user");
18574            }
18575
18576            // Explicitly remove the old information in mRecentTasks.
18577            removeRecentTasksForUserLocked(userId);
18578        }
18579
18580        for (int i=0; i<callbacks.size(); i++) {
18581            try {
18582                if (stopped) callbacks.get(i).userStopped(userId);
18583                else callbacks.get(i).userStopAborted(userId);
18584            } catch (RemoteException e) {
18585            }
18586        }
18587
18588        if (stopped) {
18589            mSystemServiceManager.cleanupUser(userId);
18590            synchronized (this) {
18591                mStackSupervisor.removeUserLocked(userId);
18592            }
18593        }
18594    }
18595
18596    @Override
18597    public UserInfo getCurrentUser() {
18598        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18599                != PackageManager.PERMISSION_GRANTED) && (
18600                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18601                != PackageManager.PERMISSION_GRANTED)) {
18602            String msg = "Permission Denial: getCurrentUser() from pid="
18603                    + Binder.getCallingPid()
18604                    + ", uid=" + Binder.getCallingUid()
18605                    + " requires " + INTERACT_ACROSS_USERS;
18606            Slog.w(TAG, msg);
18607            throw new SecurityException(msg);
18608        }
18609        synchronized (this) {
18610            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18611            return getUserManagerLocked().getUserInfo(userId);
18612        }
18613    }
18614
18615    int getCurrentUserIdLocked() {
18616        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18617    }
18618
18619    @Override
18620    public boolean isUserRunning(int userId, boolean orStopped) {
18621        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18622                != PackageManager.PERMISSION_GRANTED) {
18623            String msg = "Permission Denial: isUserRunning() from pid="
18624                    + Binder.getCallingPid()
18625                    + ", uid=" + Binder.getCallingUid()
18626                    + " requires " + INTERACT_ACROSS_USERS;
18627            Slog.w(TAG, msg);
18628            throw new SecurityException(msg);
18629        }
18630        synchronized (this) {
18631            return isUserRunningLocked(userId, orStopped);
18632        }
18633    }
18634
18635    boolean isUserRunningLocked(int userId, boolean orStopped) {
18636        UserStartedState state = mStartedUsers.get(userId);
18637        if (state == null) {
18638            return false;
18639        }
18640        if (orStopped) {
18641            return true;
18642        }
18643        return state.mState != UserStartedState.STATE_STOPPING
18644                && state.mState != UserStartedState.STATE_SHUTDOWN;
18645    }
18646
18647    @Override
18648    public int[] getRunningUserIds() {
18649        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18650                != PackageManager.PERMISSION_GRANTED) {
18651            String msg = "Permission Denial: isUserRunning() from pid="
18652                    + Binder.getCallingPid()
18653                    + ", uid=" + Binder.getCallingUid()
18654                    + " requires " + INTERACT_ACROSS_USERS;
18655            Slog.w(TAG, msg);
18656            throw new SecurityException(msg);
18657        }
18658        synchronized (this) {
18659            return mStartedUserArray;
18660        }
18661    }
18662
18663    private void updateStartedUserArrayLocked() {
18664        int num = 0;
18665        for (int i=0; i<mStartedUsers.size();  i++) {
18666            UserStartedState uss = mStartedUsers.valueAt(i);
18667            // This list does not include stopping users.
18668            if (uss.mState != UserStartedState.STATE_STOPPING
18669                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18670                num++;
18671            }
18672        }
18673        mStartedUserArray = new int[num];
18674        num = 0;
18675        for (int i=0; i<mStartedUsers.size();  i++) {
18676            UserStartedState uss = mStartedUsers.valueAt(i);
18677            if (uss.mState != UserStartedState.STATE_STOPPING
18678                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18679                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18680                num++;
18681            }
18682        }
18683    }
18684
18685    @Override
18686    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18687        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18688                != PackageManager.PERMISSION_GRANTED) {
18689            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18690                    + Binder.getCallingPid()
18691                    + ", uid=" + Binder.getCallingUid()
18692                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18693            Slog.w(TAG, msg);
18694            throw new SecurityException(msg);
18695        }
18696
18697        mUserSwitchObservers.register(observer);
18698    }
18699
18700    @Override
18701    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18702        mUserSwitchObservers.unregister(observer);
18703    }
18704
18705    private boolean userExists(int userId) {
18706        if (userId == 0) {
18707            return true;
18708        }
18709        UserManagerService ums = getUserManagerLocked();
18710        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18711    }
18712
18713    int[] getUsersLocked() {
18714        UserManagerService ums = getUserManagerLocked();
18715        return ums != null ? ums.getUserIds() : new int[] { 0 };
18716    }
18717
18718    UserManagerService getUserManagerLocked() {
18719        if (mUserManager == null) {
18720            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
18721            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
18722        }
18723        return mUserManager;
18724    }
18725
18726    private int applyUserId(int uid, int userId) {
18727        return UserHandle.getUid(userId, uid);
18728    }
18729
18730    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18731        if (info == null) return null;
18732        ApplicationInfo newInfo = new ApplicationInfo(info);
18733        newInfo.uid = applyUserId(info.uid, userId);
18734        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18735                + info.packageName;
18736        return newInfo;
18737    }
18738
18739    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18740        if (aInfo == null
18741                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18742            return aInfo;
18743        }
18744
18745        ActivityInfo info = new ActivityInfo(aInfo);
18746        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18747        return info;
18748    }
18749
18750    private final class LocalService extends ActivityManagerInternal {
18751        @Override
18752        public void goingToSleep() {
18753            ActivityManagerService.this.goingToSleep();
18754        }
18755
18756        @Override
18757        public void wakingUp() {
18758            ActivityManagerService.this.wakingUp();
18759        }
18760
18761        @Override
18762        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18763                String processName, String abiOverride, int uid, Runnable crashHandler) {
18764            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18765                    processName, abiOverride, uid, crashHandler);
18766        }
18767    }
18768
18769    /**
18770     * An implementation of IAppTask, that allows an app to manage its own tasks via
18771     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18772     * only the process that calls getAppTasks() can call the AppTask methods.
18773     */
18774    class AppTaskImpl extends IAppTask.Stub {
18775        private int mTaskId;
18776        private int mCallingUid;
18777
18778        public AppTaskImpl(int taskId, int callingUid) {
18779            mTaskId = taskId;
18780            mCallingUid = callingUid;
18781        }
18782
18783        private void checkCaller() {
18784            if (mCallingUid != Binder.getCallingUid()) {
18785                throw new SecurityException("Caller " + mCallingUid
18786                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18787            }
18788        }
18789
18790        @Override
18791        public void finishAndRemoveTask() {
18792            checkCaller();
18793
18794            synchronized (ActivityManagerService.this) {
18795                long origId = Binder.clearCallingIdentity();
18796                try {
18797                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18798                    if (tr == null) {
18799                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18800                    }
18801                    // Only kill the process if we are not a new document
18802                    int flags = tr.getBaseIntent().getFlags();
18803                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
18804                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
18805                    removeTaskByIdLocked(mTaskId,
18806                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
18807                } finally {
18808                    Binder.restoreCallingIdentity(origId);
18809                }
18810            }
18811        }
18812
18813        @Override
18814        public ActivityManager.RecentTaskInfo getTaskInfo() {
18815            checkCaller();
18816
18817            synchronized (ActivityManagerService.this) {
18818                long origId = Binder.clearCallingIdentity();
18819                try {
18820                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18821                    if (tr == null) {
18822                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18823                    }
18824                    return createRecentTaskInfoFromTaskRecord(tr);
18825                } finally {
18826                    Binder.restoreCallingIdentity(origId);
18827                }
18828            }
18829        }
18830
18831        @Override
18832        public void moveToFront() {
18833            checkCaller();
18834
18835            final TaskRecord tr;
18836            synchronized (ActivityManagerService.this) {
18837                tr = recentTaskForIdLocked(mTaskId);
18838                if (tr == null) {
18839                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18840                }
18841                if (tr.getRootActivity() != null) {
18842                    long origId = Binder.clearCallingIdentity();
18843                    try {
18844                        moveTaskToFrontLocked(tr.taskId, 0, null);
18845                        return;
18846                    } finally {
18847                        Binder.restoreCallingIdentity(origId);
18848                    }
18849                }
18850            }
18851
18852            startActivityFromRecentsInner(tr.taskId, null);
18853        }
18854
18855        @Override
18856        public int startActivity(IBinder whoThread, String callingPackage,
18857                Intent intent, String resolvedType, Bundle options) {
18858            checkCaller();
18859
18860            int callingUser = UserHandle.getCallingUserId();
18861            TaskRecord tr;
18862            IApplicationThread appThread;
18863            synchronized (ActivityManagerService.this) {
18864                tr = recentTaskForIdLocked(mTaskId);
18865                if (tr == null) {
18866                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18867                }
18868                appThread = ApplicationThreadNative.asInterface(whoThread);
18869                if (appThread == null) {
18870                    throw new IllegalArgumentException("Bad app thread " + appThread);
18871                }
18872            }
18873            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
18874                    resolvedType, null, null, null, null, 0, 0, null, null,
18875                    null, options, callingUser, null, tr);
18876        }
18877
18878        @Override
18879        public void setExcludeFromRecents(boolean exclude) {
18880            checkCaller();
18881
18882            synchronized (ActivityManagerService.this) {
18883                long origId = Binder.clearCallingIdentity();
18884                try {
18885                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18886                    if (tr == null) {
18887                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18888                    }
18889                    Intent intent = tr.getBaseIntent();
18890                    if (exclude) {
18891                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18892                    } else {
18893                        intent.setFlags(intent.getFlags()
18894                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18895                    }
18896                } finally {
18897                    Binder.restoreCallingIdentity(origId);
18898                }
18899            }
18900        }
18901    }
18902}
18903