ActivityManagerService.java revision 255dd04271088590fedc46c8e22b2fd4ab142d39
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.IActivityContainer;
37import android.app.IActivityContainerCallback;
38import android.app.IAppTask;
39import android.app.admin.DevicePolicyManager;
40import android.app.usage.UsageEvents;
41import android.app.usage.UsageStatsManagerInternal;
42import android.appwidget.AppWidgetManager;
43import android.graphics.Rect;
44import android.os.BatteryStats;
45import android.os.PersistableBundle;
46import android.service.voice.IVoiceInteractionSession;
47import android.util.ArrayMap;
48import android.util.ArraySet;
49import android.util.SparseIntArray;
50
51import com.android.internal.R;
52import com.android.internal.annotations.GuardedBy;
53import com.android.internal.app.IAppOpsService;
54import com.android.internal.app.IVoiceInteractor;
55import com.android.internal.app.ProcessMap;
56import com.android.internal.app.ProcessStats;
57import com.android.internal.content.PackageMonitor;
58import com.android.internal.os.BackgroundThread;
59import com.android.internal.os.BatteryStatsImpl;
60import com.android.internal.os.ProcessCpuTracker;
61import com.android.internal.os.TransferPipe;
62import com.android.internal.os.Zygote;
63import com.android.internal.util.FastPrintWriter;
64import com.android.internal.util.FastXmlSerializer;
65import com.android.internal.util.MemInfoReader;
66import com.android.internal.util.Preconditions;
67import com.android.server.AppOpsService;
68import com.android.server.AttributeCache;
69import com.android.server.IntentResolver;
70import com.android.server.LocalServices;
71import com.android.server.ServiceThread;
72import com.android.server.SystemService;
73import com.android.server.SystemServiceManager;
74import com.android.server.Watchdog;
75import com.android.server.am.ActivityStack.ActivityState;
76import com.android.server.firewall.IntentFirewall;
77import com.android.server.pm.UserManagerService;
78import com.android.server.wm.AppTransition;
79import com.android.server.wm.WindowManagerService;
80import com.google.android.collect.Lists;
81import com.google.android.collect.Maps;
82
83import libcore.io.IoUtils;
84
85import org.xmlpull.v1.XmlPullParser;
86import org.xmlpull.v1.XmlPullParserException;
87import org.xmlpull.v1.XmlSerializer;
88
89import android.app.Activity;
90import android.app.ActivityManager;
91import android.app.ActivityManager.RunningTaskInfo;
92import android.app.ActivityManager.StackInfo;
93import android.app.ActivityManagerInternal;
94import android.app.ActivityManagerNative;
95import android.app.ActivityOptions;
96import android.app.ActivityThread;
97import android.app.AlertDialog;
98import android.app.AppGlobals;
99import android.app.ApplicationErrorReport;
100import android.app.Dialog;
101import android.app.IActivityController;
102import android.app.IApplicationThread;
103import android.app.IInstrumentationWatcher;
104import android.app.INotificationManager;
105import android.app.IProcessObserver;
106import android.app.IServiceConnection;
107import android.app.IStopUserCallback;
108import android.app.IUiAutomationConnection;
109import android.app.IUserSwitchObserver;
110import android.app.Instrumentation;
111import android.app.Notification;
112import android.app.NotificationManager;
113import android.app.PendingIntent;
114import android.app.backup.IBackupManager;
115import android.content.ActivityNotFoundException;
116import android.content.BroadcastReceiver;
117import android.content.ClipData;
118import android.content.ComponentCallbacks2;
119import android.content.ComponentName;
120import android.content.ContentProvider;
121import android.content.ContentResolver;
122import android.content.Context;
123import android.content.DialogInterface;
124import android.content.IContentProvider;
125import android.content.IIntentReceiver;
126import android.content.IIntentSender;
127import android.content.Intent;
128import android.content.IntentFilter;
129import android.content.IntentSender;
130import android.content.pm.ActivityInfo;
131import android.content.pm.ApplicationInfo;
132import android.content.pm.ConfigurationInfo;
133import android.content.pm.IPackageDataObserver;
134import android.content.pm.IPackageManager;
135import android.content.pm.InstrumentationInfo;
136import android.content.pm.PackageInfo;
137import android.content.pm.PackageManager;
138import android.content.pm.ParceledListSlice;
139import android.content.pm.UserInfo;
140import android.content.pm.PackageManager.NameNotFoundException;
141import android.content.pm.PathPermission;
142import android.content.pm.ProviderInfo;
143import android.content.pm.ResolveInfo;
144import android.content.pm.ServiceInfo;
145import android.content.res.CompatibilityInfo;
146import android.content.res.Configuration;
147import android.net.Proxy;
148import android.net.ProxyInfo;
149import android.net.Uri;
150import android.os.Binder;
151import android.os.Build;
152import android.os.Bundle;
153import android.os.Debug;
154import android.os.DropBoxManager;
155import android.os.Environment;
156import android.os.FactoryTest;
157import android.os.FileObserver;
158import android.os.FileUtils;
159import android.os.Handler;
160import android.os.IBinder;
161import android.os.IPermissionController;
162import android.os.IRemoteCallback;
163import android.os.IUserManager;
164import android.os.Looper;
165import android.os.Message;
166import android.os.Parcel;
167import android.os.ParcelFileDescriptor;
168import android.os.Process;
169import android.os.RemoteCallbackList;
170import android.os.RemoteException;
171import android.os.SELinux;
172import android.os.ServiceManager;
173import android.os.StrictMode;
174import android.os.SystemClock;
175import android.os.SystemProperties;
176import android.os.UpdateLock;
177import android.os.UserHandle;
178import android.provider.Settings;
179import android.text.format.DateUtils;
180import android.text.format.Time;
181import android.util.AtomicFile;
182import android.util.EventLog;
183import android.util.Log;
184import android.util.Pair;
185import android.util.PrintWriterPrinter;
186import android.util.Slog;
187import android.util.SparseArray;
188import android.util.TimeUtils;
189import android.util.Xml;
190import android.view.Gravity;
191import android.view.LayoutInflater;
192import android.view.View;
193import android.view.WindowManager;
194
195import java.io.BufferedInputStream;
196import java.io.BufferedOutputStream;
197import java.io.DataInputStream;
198import java.io.DataOutputStream;
199import java.io.File;
200import java.io.FileDescriptor;
201import java.io.FileInputStream;
202import java.io.FileNotFoundException;
203import java.io.FileOutputStream;
204import java.io.IOException;
205import java.io.InputStreamReader;
206import java.io.PrintWriter;
207import java.io.StringWriter;
208import java.lang.ref.WeakReference;
209import java.util.ArrayList;
210import java.util.Arrays;
211import java.util.Collections;
212import java.util.Comparator;
213import java.util.HashMap;
214import java.util.HashSet;
215import java.util.Iterator;
216import java.util.List;
217import java.util.Locale;
218import java.util.Map;
219import java.util.Set;
220import java.util.concurrent.atomic.AtomicBoolean;
221import java.util.concurrent.atomic.AtomicLong;
222
223public final class ActivityManagerService extends ActivityManagerNative
224        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
225
226    private static final String USER_DATA_DIR = "/data/user/";
227    // File that stores last updated system version and called preboot receivers
228    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
229
230    static final String TAG = "ActivityManager";
231    static final String TAG_MU = "ActivityManagerServiceMU";
232    static final boolean DEBUG = false;
233    static final boolean localLOGV = DEBUG;
234    static final boolean DEBUG_BACKUP = localLOGV || false;
235    static final boolean DEBUG_BROADCAST = localLOGV || false;
236    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
237    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
238    static final boolean DEBUG_CLEANUP = localLOGV || false;
239    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
240    static final boolean DEBUG_FOCUS = false;
241    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
242    static final boolean DEBUG_MU = localLOGV || false;
243    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
244    static final boolean DEBUG_LRU = localLOGV || false;
245    static final boolean DEBUG_PAUSE = localLOGV || false;
246    static final boolean DEBUG_POWER = localLOGV || false;
247    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
248    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
249    static final boolean DEBUG_PROCESSES = localLOGV || false;
250    static final boolean DEBUG_PROVIDER = localLOGV || false;
251    static final boolean DEBUG_RESULTS = localLOGV || false;
252    static final boolean DEBUG_SERVICE = localLOGV || false;
253    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
254    static final boolean DEBUG_STACK = localLOGV || false;
255    static final boolean DEBUG_SWITCH = localLOGV || false;
256    static final boolean DEBUG_TASKS = localLOGV || false;
257    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
258    static final boolean DEBUG_TRANSITION = localLOGV || false;
259    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
260    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
261    static final boolean DEBUG_VISBILITY = localLOGV || false;
262    static final boolean DEBUG_PSS = localLOGV || false;
263    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
264    static final boolean VALIDATE_TOKENS = false;
265    static final boolean SHOW_ACTIVITY_START_TIME = true;
266
267    // Control over CPU and battery monitoring.
268    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
269    static final boolean MONITOR_CPU_USAGE = true;
270    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
271    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
272    static final boolean MONITOR_THREAD_CPU_USAGE = false;
273
274    // The flags that are set for all calls we make to the package manager.
275    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
276
277    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
278
279    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
280
281    // Maximum number of recent tasks that we can remember.
282    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 100 : 200;
283
284    // Maximum number recent bitmaps to keep in memory.
285    static final int MAX_RECENT_BITMAPS = 5;
286
287    // Amount of time after a call to stopAppSwitches() during which we will
288    // prevent further untrusted switches from happening.
289    static final long APP_SWITCH_DELAY_TIME = 5*1000;
290
291    // How long we wait for a launched process to attach to the activity manager
292    // before we decide it's never going to come up for real.
293    static final int PROC_START_TIMEOUT = 10*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, when the process was
297    // started with a wrapper for instrumentation (such as Valgrind) because it
298    // could take much longer than usual.
299    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
300
301    // How long to wait after going idle before forcing apps to GC.
302    static final int GC_TIMEOUT = 5*1000;
303
304    // The minimum amount of time between successive GC requests for a process.
305    static final int GC_MIN_INTERVAL = 60*1000;
306
307    // The minimum amount of time between successive PSS requests for a process.
308    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
309
310    // The minimum amount of time between successive PSS requests for a process
311    // when the request is due to the memory state being lowered.
312    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
313
314    // The rate at which we check for apps using excessive power -- 15 mins.
315    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
316
317    // The minimum sample duration we will allow before deciding we have
318    // enough data on wake locks to start killing things.
319    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
320
321    // The minimum sample duration we will allow before deciding we have
322    // enough data on CPU usage to start killing things.
323    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
324
325    // How long we allow a receiver to run before giving up on it.
326    static final int BROADCAST_FG_TIMEOUT = 10*1000;
327    static final int BROADCAST_BG_TIMEOUT = 60*1000;
328
329    // How long we wait until we timeout on key dispatching.
330    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
331
332    // How long we wait until we timeout on key dispatching during instrumentation.
333    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
334
335    // Amount of time we wait for observers to handle a user switch before
336    // giving up on them and unfreezing the screen.
337    static final int USER_SWITCH_TIMEOUT = 2*1000;
338
339    // Maximum number of users we allow to be running at a time.
340    static final int MAX_RUNNING_USERS = 3;
341
342    // How long to wait in getAssistContextExtras for the activity and foreground services
343    // to respond with the result.
344    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
345
346    // Maximum number of persisted Uri grants a package is allowed
347    static final int MAX_PERSISTED_URI_GRANTS = 128;
348
349    static final int MY_PID = Process.myPid();
350
351    static final String[] EMPTY_STRING_ARRAY = new String[0];
352
353    // How many bytes to write into the dropbox log before truncating
354    static final int DROPBOX_MAX_SIZE = 256 * 1024;
355
356    // Access modes for handleIncomingUser.
357    static final int ALLOW_NON_FULL = 0;
358    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
359    static final int ALLOW_FULL_ONLY = 2;
360
361    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
362
363    /** All system services */
364    SystemServiceManager mSystemServiceManager;
365
366    /** Run all ActivityStacks through this */
367    ActivityStackSupervisor mStackSupervisor;
368
369    public IntentFirewall mIntentFirewall;
370
371    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
372    // default actuion automatically.  Important for devices without direct input
373    // devices.
374    private boolean mShowDialogs = true;
375
376    BroadcastQueue mFgBroadcastQueue;
377    BroadcastQueue mBgBroadcastQueue;
378    // Convenient for easy iteration over the queues. Foreground is first
379    // so that dispatch of foreground broadcasts gets precedence.
380    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
381
382    BroadcastQueue broadcastQueueForIntent(Intent intent) {
383        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
384        if (DEBUG_BACKGROUND_BROADCAST) {
385            Slog.i(TAG, "Broadcast intent " + intent + " on "
386                    + (isFg ? "foreground" : "background")
387                    + " queue");
388        }
389        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
390    }
391
392    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
393        for (BroadcastQueue queue : mBroadcastQueues) {
394            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
395            if (r != null) {
396                return r;
397            }
398        }
399        return null;
400    }
401
402    /**
403     * Activity we have told the window manager to have key focus.
404     */
405    ActivityRecord mFocusedActivity = null;
406
407    /**
408     * List of intents that were used to start the most recent tasks.
409     */
410    ArrayList<TaskRecord> mRecentTasks;
411    ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>();
412
413    public class PendingAssistExtras extends Binder implements Runnable {
414        public final ActivityRecord activity;
415        public boolean haveResult = false;
416        public Bundle result = null;
417        public PendingAssistExtras(ActivityRecord _activity) {
418            activity = _activity;
419        }
420        @Override
421        public void run() {
422            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
423            synchronized (this) {
424                haveResult = true;
425                notifyAll();
426            }
427        }
428    }
429
430    final ArrayList<PendingAssistExtras> mPendingAssistExtras
431            = new ArrayList<PendingAssistExtras>();
432
433    /**
434     * Process management.
435     */
436    final ProcessList mProcessList = new ProcessList();
437
438    /**
439     * All of the applications we currently have running organized by name.
440     * The keys are strings of the application package name (as
441     * returned by the package manager), and the keys are ApplicationRecord
442     * objects.
443     */
444    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
445
446    /**
447     * Tracking long-term execution of processes to look for abuse and other
448     * bad app behavior.
449     */
450    final ProcessStatsService mProcessStats;
451
452    /**
453     * The currently running isolated processes.
454     */
455    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
456
457    /**
458     * Counter for assigning isolated process uids, to avoid frequently reusing the
459     * same ones.
460     */
461    int mNextIsolatedProcessUid = 0;
462
463    /**
464     * The currently running heavy-weight process, if any.
465     */
466    ProcessRecord mHeavyWeightProcess = null;
467
468    /**
469     * The last time that various processes have crashed.
470     */
471    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
472
473    /**
474     * Information about a process that is currently marked as bad.
475     */
476    static final class BadProcessInfo {
477        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
478            this.time = time;
479            this.shortMsg = shortMsg;
480            this.longMsg = longMsg;
481            this.stack = stack;
482        }
483
484        final long time;
485        final String shortMsg;
486        final String longMsg;
487        final String stack;
488    }
489
490    /**
491     * Set of applications that we consider to be bad, and will reject
492     * incoming broadcasts from (which the user has no control over).
493     * Processes are added to this set when they have crashed twice within
494     * a minimum amount of time; they are removed from it when they are
495     * later restarted (hopefully due to some user action).  The value is the
496     * time it was added to the list.
497     */
498    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
499
500    /**
501     * All of the processes we currently have running organized by pid.
502     * The keys are the pid running the application.
503     *
504     * <p>NOTE: This object is protected by its own lock, NOT the global
505     * activity manager lock!
506     */
507    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
508
509    /**
510     * All of the processes that have been forced to be foreground.  The key
511     * is the pid of the caller who requested it (we hold a death
512     * link on it).
513     */
514    abstract class ForegroundToken implements IBinder.DeathRecipient {
515        int pid;
516        IBinder token;
517    }
518    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
519
520    /**
521     * List of records for processes that someone had tried to start before the
522     * system was ready.  We don't start them at that point, but ensure they
523     * are started by the time booting is complete.
524     */
525    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
526
527    /**
528     * List of persistent applications that are in the process
529     * of being started.
530     */
531    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
532
533    /**
534     * Processes that are being forcibly torn down.
535     */
536    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
537
538    /**
539     * List of running applications, sorted by recent usage.
540     * The first entry in the list is the least recently used.
541     */
542    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
543
544    /**
545     * Where in mLruProcesses that the processes hosting activities start.
546     */
547    int mLruProcessActivityStart = 0;
548
549    /**
550     * Where in mLruProcesses that the processes hosting services start.
551     * This is after (lower index) than mLruProcessesActivityStart.
552     */
553    int mLruProcessServiceStart = 0;
554
555    /**
556     * List of processes that should gc as soon as things are idle.
557     */
558    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
559
560    /**
561     * Processes we want to collect PSS data from.
562     */
563    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
564
565    /**
566     * Last time we requested PSS data of all processes.
567     */
568    long mLastFullPssTime = SystemClock.uptimeMillis();
569
570    /**
571     * If set, the next time we collect PSS data we should do a full collection
572     * with data from native processes and the kernel.
573     */
574    boolean mFullPssPending = false;
575
576    /**
577     * This is the process holding what we currently consider to be
578     * the "home" activity.
579     */
580    ProcessRecord mHomeProcess;
581
582    /**
583     * This is the process holding the activity the user last visited that
584     * is in a different process from the one they are currently in.
585     */
586    ProcessRecord mPreviousProcess;
587
588    /**
589     * The time at which the previous process was last visible.
590     */
591    long mPreviousProcessVisibleTime;
592
593    /**
594     * Which uses have been started, so are allowed to run code.
595     */
596    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
597
598    /**
599     * LRU list of history of current users.  Most recently current is at the end.
600     */
601    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
602
603    /**
604     * Constant array of the users that are currently started.
605     */
606    int[] mStartedUserArray = new int[] { 0 };
607
608    /**
609     * Registered observers of the user switching mechanics.
610     */
611    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
612            = new RemoteCallbackList<IUserSwitchObserver>();
613
614    /**
615     * Currently active user switch.
616     */
617    Object mCurUserSwitchCallback;
618
619    /**
620     * Packages that the user has asked to have run in screen size
621     * compatibility mode instead of filling the screen.
622     */
623    final CompatModePackages mCompatModePackages;
624
625    /**
626     * Set of IntentSenderRecord objects that are currently active.
627     */
628    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
629            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
630
631    /**
632     * Fingerprints (hashCode()) of stack traces that we've
633     * already logged DropBox entries for.  Guarded by itself.  If
634     * something (rogue user app) forces this over
635     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
636     */
637    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
638    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
639
640    /**
641     * Strict Mode background batched logging state.
642     *
643     * The string buffer is guarded by itself, and its lock is also
644     * used to determine if another batched write is already
645     * in-flight.
646     */
647    private final StringBuilder mStrictModeBuffer = new StringBuilder();
648
649    /**
650     * Keeps track of all IIntentReceivers that have been registered for
651     * broadcasts.  Hash keys are the receiver IBinder, hash value is
652     * a ReceiverList.
653     */
654    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
655            new HashMap<IBinder, ReceiverList>();
656
657    /**
658     * Resolver for broadcast intents to registered receivers.
659     * Holds BroadcastFilter (subclass of IntentFilter).
660     */
661    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
662            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
663        @Override
664        protected boolean allowFilterResult(
665                BroadcastFilter filter, List<BroadcastFilter> dest) {
666            IBinder target = filter.receiverList.receiver.asBinder();
667            for (int i=dest.size()-1; i>=0; i--) {
668                if (dest.get(i).receiverList.receiver.asBinder() == target) {
669                    return false;
670                }
671            }
672            return true;
673        }
674
675        @Override
676        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
677            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
678                    || userId == filter.owningUserId) {
679                return super.newResult(filter, match, userId);
680            }
681            return null;
682        }
683
684        @Override
685        protected BroadcastFilter[] newArray(int size) {
686            return new BroadcastFilter[size];
687        }
688
689        @Override
690        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
691            return packageName.equals(filter.packageName);
692        }
693    };
694
695    /**
696     * State of all active sticky broadcasts per user.  Keys are the action of the
697     * sticky Intent, values are an ArrayList of all broadcasted intents with
698     * that action (which should usually be one).  The SparseArray is keyed
699     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
700     * for stickies that are sent to all users.
701     */
702    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
703            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
704
705    final ActiveServices mServices;
706
707    /**
708     * Backup/restore process management
709     */
710    String mBackupAppName = null;
711    BackupRecord mBackupTarget = null;
712
713    final ProviderMap mProviderMap;
714
715    /**
716     * List of content providers who have clients waiting for them.  The
717     * application is currently being launched and the provider will be
718     * removed from this list once it is published.
719     */
720    final ArrayList<ContentProviderRecord> mLaunchingProviders
721            = new ArrayList<ContentProviderRecord>();
722
723    /**
724     * File storing persisted {@link #mGrantedUriPermissions}.
725     */
726    private final AtomicFile mGrantFile;
727
728    /** XML constants used in {@link #mGrantFile} */
729    private static final String TAG_URI_GRANTS = "uri-grants";
730    private static final String TAG_URI_GRANT = "uri-grant";
731    private static final String ATTR_USER_HANDLE = "userHandle";
732    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
733    private static final String ATTR_TARGET_USER_ID = "targetUserId";
734    private static final String ATTR_SOURCE_PKG = "sourcePkg";
735    private static final String ATTR_TARGET_PKG = "targetPkg";
736    private static final String ATTR_URI = "uri";
737    private static final String ATTR_MODE_FLAGS = "modeFlags";
738    private static final String ATTR_CREATED_TIME = "createdTime";
739    private static final String ATTR_PREFIX = "prefix";
740
741    /**
742     * Global set of specific {@link Uri} permissions that have been granted.
743     * This optimized lookup structure maps from {@link UriPermission#targetUid}
744     * to {@link UriPermission#uri} to {@link UriPermission}.
745     */
746    @GuardedBy("this")
747    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
748            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
749
750    public static class GrantUri {
751        public final int sourceUserId;
752        public final Uri uri;
753        public boolean prefix;
754
755        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
756            this.sourceUserId = sourceUserId;
757            this.uri = uri;
758            this.prefix = prefix;
759        }
760
761        @Override
762        public int hashCode() {
763            return toString().hashCode();
764        }
765
766        @Override
767        public boolean equals(Object o) {
768            if (o instanceof GrantUri) {
769                GrantUri other = (GrantUri) o;
770                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
771                        && prefix == other.prefix;
772            }
773            return false;
774        }
775
776        @Override
777        public String toString() {
778            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
779            if (prefix) result += " [prefix]";
780            return result;
781        }
782
783        public String toSafeString() {
784            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
785            if (prefix) result += " [prefix]";
786            return result;
787        }
788
789        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
790            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
791                    ContentProvider.getUriWithoutUserId(uri), false);
792        }
793    }
794
795    CoreSettingsObserver mCoreSettingsObserver;
796
797    /**
798     * Thread-local storage used to carry caller permissions over through
799     * indirect content-provider access.
800     */
801    private class Identity {
802        public int pid;
803        public int uid;
804
805        Identity(int _pid, int _uid) {
806            pid = _pid;
807            uid = _uid;
808        }
809    }
810
811    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
812
813    /**
814     * All information we have collected about the runtime performance of
815     * any user id that can impact battery performance.
816     */
817    final BatteryStatsService mBatteryStatsService;
818
819    /**
820     * Information about component usage
821     */
822    UsageStatsManagerInternal mUsageStatsService;
823
824    /**
825     * Information about and control over application operations
826     */
827    final AppOpsService mAppOpsService;
828
829    /**
830     * Save recent tasks information across reboots.
831     */
832    final TaskPersister mTaskPersister;
833
834    /**
835     * Current configuration information.  HistoryRecord objects are given
836     * a reference to this object to indicate which configuration they are
837     * currently running in, so this object must be kept immutable.
838     */
839    Configuration mConfiguration = new Configuration();
840
841    /**
842     * Current sequencing integer of the configuration, for skipping old
843     * configurations.
844     */
845    int mConfigurationSeq = 0;
846
847    /**
848     * Hardware-reported OpenGLES version.
849     */
850    final int GL_ES_VERSION;
851
852    /**
853     * List of initialization arguments to pass to all processes when binding applications to them.
854     * For example, references to the commonly used services.
855     */
856    HashMap<String, IBinder> mAppBindArgs;
857
858    /**
859     * Temporary to avoid allocations.  Protected by main lock.
860     */
861    final StringBuilder mStringBuilder = new StringBuilder(256);
862
863    /**
864     * Used to control how we initialize the service.
865     */
866    ComponentName mTopComponent;
867    String mTopAction = Intent.ACTION_MAIN;
868    String mTopData;
869    boolean mProcessesReady = false;
870    boolean mSystemReady = false;
871    boolean mBooting = false;
872    boolean mWaitingUpdate = false;
873    boolean mDidUpdate = false;
874    boolean mOnBattery = false;
875    boolean mLaunchWarningShown = false;
876
877    Context mContext;
878
879    int mFactoryTest;
880
881    boolean mCheckedForSetup;
882
883    /**
884     * The time at which we will allow normal application switches again,
885     * after a call to {@link #stopAppSwitches()}.
886     */
887    long mAppSwitchesAllowedTime;
888
889    /**
890     * This is set to true after the first switch after mAppSwitchesAllowedTime
891     * is set; any switches after that will clear the time.
892     */
893    boolean mDidAppSwitch;
894
895    /**
896     * Last time (in realtime) at which we checked for power usage.
897     */
898    long mLastPowerCheckRealtime;
899
900    /**
901     * Last time (in uptime) at which we checked for power usage.
902     */
903    long mLastPowerCheckUptime;
904
905    /**
906     * Set while we are wanting to sleep, to prevent any
907     * activities from being started/resumed.
908     */
909    private boolean mSleeping = false;
910
911    /**
912     * Set while we are running a voice interaction.  This overrides
913     * sleeping while it is active.
914     */
915    private boolean mRunningVoice = false;
916
917    /**
918     * State of external calls telling us if the device is asleep.
919     */
920    private boolean mWentToSleep = false;
921
922    /**
923     * State of external call telling us if the lock screen is shown.
924     */
925    private boolean mLockScreenShown = false;
926
927    /**
928     * Set if we are shutting down the system, similar to sleeping.
929     */
930    boolean mShuttingDown = false;
931
932    /**
933     * Current sequence id for oom_adj computation traversal.
934     */
935    int mAdjSeq = 0;
936
937    /**
938     * Current sequence id for process LRU updating.
939     */
940    int mLruSeq = 0;
941
942    /**
943     * Keep track of the non-cached/empty process we last found, to help
944     * determine how to distribute cached/empty processes next time.
945     */
946    int mNumNonCachedProcs = 0;
947
948    /**
949     * Keep track of the number of cached hidden procs, to balance oom adj
950     * distribution between those and empty procs.
951     */
952    int mNumCachedHiddenProcs = 0;
953
954    /**
955     * Keep track of the number of service processes we last found, to
956     * determine on the next iteration which should be B services.
957     */
958    int mNumServiceProcs = 0;
959    int mNewNumAServiceProcs = 0;
960    int mNewNumServiceProcs = 0;
961
962    /**
963     * Allow the current computed overall memory level of the system to go down?
964     * This is set to false when we are killing processes for reasons other than
965     * memory management, so that the now smaller process list will not be taken as
966     * an indication that memory is tighter.
967     */
968    boolean mAllowLowerMemLevel = false;
969
970    /**
971     * The last computed memory level, for holding when we are in a state that
972     * processes are going away for other reasons.
973     */
974    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
975
976    /**
977     * The last total number of process we have, to determine if changes actually look
978     * like a shrinking number of process due to lower RAM.
979     */
980    int mLastNumProcesses;
981
982    /**
983     * The uptime of the last time we performed idle maintenance.
984     */
985    long mLastIdleTime = SystemClock.uptimeMillis();
986
987    /**
988     * Total time spent with RAM that has been added in the past since the last idle time.
989     */
990    long mLowRamTimeSinceLastIdle = 0;
991
992    /**
993     * If RAM is currently low, when that horrible situation started.
994     */
995    long mLowRamStartTime = 0;
996
997    /**
998     * For reporting to battery stats the current top application.
999     */
1000    private String mCurResumedPackage = null;
1001    private int mCurResumedUid = -1;
1002
1003    /**
1004     * For reporting to battery stats the apps currently running foreground
1005     * service.  The ProcessMap is package/uid tuples; each of these contain
1006     * an array of the currently foreground processes.
1007     */
1008    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1009            = new ProcessMap<ArrayList<ProcessRecord>>();
1010
1011    /**
1012     * This is set if we had to do a delayed dexopt of an app before launching
1013     * it, to increase the ANR timeouts in that case.
1014     */
1015    boolean mDidDexOpt;
1016
1017    /**
1018     * Set if the systemServer made a call to enterSafeMode.
1019     */
1020    boolean mSafeMode;
1021
1022    String mDebugApp = null;
1023    boolean mWaitForDebugger = false;
1024    boolean mDebugTransient = false;
1025    String mOrigDebugApp = null;
1026    boolean mOrigWaitForDebugger = false;
1027    boolean mAlwaysFinishActivities = false;
1028    IActivityController mController = null;
1029    String mProfileApp = null;
1030    ProcessRecord mProfileProc = null;
1031    String mProfileFile;
1032    ParcelFileDescriptor mProfileFd;
1033    int mProfileType = 0;
1034    boolean mAutoStopProfiler = false;
1035    String mOpenGlTraceApp = null;
1036
1037    static class ProcessChangeItem {
1038        static final int CHANGE_ACTIVITIES = 1<<0;
1039        static final int CHANGE_PROCESS_STATE = 1<<1;
1040        int changes;
1041        int uid;
1042        int pid;
1043        int processState;
1044        boolean foregroundActivities;
1045    }
1046
1047    final RemoteCallbackList<IProcessObserver> mProcessObservers
1048            = new RemoteCallbackList<IProcessObserver>();
1049    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1050
1051    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1052            = new ArrayList<ProcessChangeItem>();
1053    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1054            = new ArrayList<ProcessChangeItem>();
1055
1056    /**
1057     * Runtime CPU use collection thread.  This object's lock is used to
1058     * protect all related state.
1059     */
1060    final Thread mProcessCpuThread;
1061
1062    /**
1063     * Used to collect process stats when showing not responding dialog.
1064     * Protected by mProcessCpuThread.
1065     */
1066    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1067            MONITOR_THREAD_CPU_USAGE);
1068    final AtomicLong mLastCpuTime = new AtomicLong(0);
1069    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1070
1071    long mLastWriteTime = 0;
1072
1073    /**
1074     * Used to retain an update lock when the foreground activity is in
1075     * immersive mode.
1076     */
1077    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1078
1079    /**
1080     * Set to true after the system has finished booting.
1081     */
1082    boolean mBooted = false;
1083
1084    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1085    int mProcessLimitOverride = -1;
1086
1087    WindowManagerService mWindowManager;
1088
1089    final ActivityThread mSystemThread;
1090
1091    int mCurrentUserId = 0;
1092    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1093
1094    /**
1095     * Mapping from each known user ID to the profile group ID it is associated with.
1096     */
1097    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1098
1099    private UserManagerService mUserManager;
1100
1101    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1102        final ProcessRecord mApp;
1103        final int mPid;
1104        final IApplicationThread mAppThread;
1105
1106        AppDeathRecipient(ProcessRecord app, int pid,
1107                IApplicationThread thread) {
1108            if (localLOGV) Slog.v(
1109                TAG, "New death recipient " + this
1110                + " for thread " + thread.asBinder());
1111            mApp = app;
1112            mPid = pid;
1113            mAppThread = thread;
1114        }
1115
1116        @Override
1117        public void binderDied() {
1118            if (localLOGV) Slog.v(
1119                TAG, "Death received in " + this
1120                + " for thread " + mAppThread.asBinder());
1121            synchronized(ActivityManagerService.this) {
1122                appDiedLocked(mApp, mPid, mAppThread);
1123            }
1124        }
1125    }
1126
1127    static final int SHOW_ERROR_MSG = 1;
1128    static final int SHOW_NOT_RESPONDING_MSG = 2;
1129    static final int SHOW_FACTORY_ERROR_MSG = 3;
1130    static final int UPDATE_CONFIGURATION_MSG = 4;
1131    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1132    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1133    static final int SERVICE_TIMEOUT_MSG = 12;
1134    static final int UPDATE_TIME_ZONE = 13;
1135    static final int SHOW_UID_ERROR_MSG = 14;
1136    static final int IM_FEELING_LUCKY_MSG = 15;
1137    static final int PROC_START_TIMEOUT_MSG = 20;
1138    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1139    static final int KILL_APPLICATION_MSG = 22;
1140    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1141    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1142    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1143    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1144    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1145    static final int CLEAR_DNS_CACHE_MSG = 28;
1146    static final int UPDATE_HTTP_PROXY_MSG = 29;
1147    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1148    static final int DISPATCH_PROCESSES_CHANGED = 31;
1149    static final int DISPATCH_PROCESS_DIED = 32;
1150    static final int REPORT_MEM_USAGE_MSG = 33;
1151    static final int REPORT_USER_SWITCH_MSG = 34;
1152    static final int CONTINUE_USER_SWITCH_MSG = 35;
1153    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1154    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1155    static final int PERSIST_URI_GRANTS_MSG = 38;
1156    static final int REQUEST_ALL_PSS_MSG = 39;
1157    static final int START_PROFILES_MSG = 40;
1158    static final int UPDATE_TIME = 41;
1159    static final int SYSTEM_USER_START_MSG = 42;
1160    static final int SYSTEM_USER_CURRENT_MSG = 43;
1161    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1162    static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45;
1163
1164    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1165    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1166    static final int FIRST_COMPAT_MODE_MSG = 300;
1167    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1168
1169    AlertDialog mUidAlert;
1170    CompatModeDialog mCompatModeDialog;
1171    long mLastMemUsageReportTime = 0;
1172
1173    private LockToAppRequestDialog mLockToAppRequest;
1174
1175    /**
1176     * Flag whether the current user is a "monkey", i.e. whether
1177     * the UI is driven by a UI automation tool.
1178     */
1179    private boolean mUserIsMonkey;
1180
1181    /** Flag whether the device has a recents UI */
1182    final boolean mHasRecents;
1183
1184    final ServiceThread mHandlerThread;
1185    final MainHandler mHandler;
1186
1187    final class MainHandler extends Handler {
1188        public MainHandler(Looper looper) {
1189            super(looper, null, true);
1190        }
1191
1192        @Override
1193        public void handleMessage(Message msg) {
1194            switch (msg.what) {
1195            case SHOW_ERROR_MSG: {
1196                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1197                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1198                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1199                synchronized (ActivityManagerService.this) {
1200                    ProcessRecord proc = (ProcessRecord)data.get("app");
1201                    AppErrorResult res = (AppErrorResult) data.get("result");
1202                    if (proc != null && proc.crashDialog != null) {
1203                        Slog.e(TAG, "App already has crash dialog: " + proc);
1204                        if (res != null) {
1205                            res.set(0);
1206                        }
1207                        return;
1208                    }
1209                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1210                            >= Process.FIRST_APPLICATION_UID
1211                            && proc.pid != MY_PID);
1212                    for (int userId : mCurrentProfileIds) {
1213                        isBackground &= (proc.userId != userId);
1214                    }
1215                    if (isBackground && !showBackground) {
1216                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1217                        if (res != null) {
1218                            res.set(0);
1219                        }
1220                        return;
1221                    }
1222                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1223                        Dialog d = new AppErrorDialog(mContext,
1224                                ActivityManagerService.this, res, proc);
1225                        d.show();
1226                        proc.crashDialog = d;
1227                    } else {
1228                        // The device is asleep, so just pretend that the user
1229                        // saw a crash dialog and hit "force quit".
1230                        if (res != null) {
1231                            res.set(0);
1232                        }
1233                    }
1234                }
1235
1236                ensureBootCompleted();
1237            } break;
1238            case SHOW_NOT_RESPONDING_MSG: {
1239                synchronized (ActivityManagerService.this) {
1240                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1241                    ProcessRecord proc = (ProcessRecord)data.get("app");
1242                    if (proc != null && proc.anrDialog != null) {
1243                        Slog.e(TAG, "App already has anr dialog: " + proc);
1244                        return;
1245                    }
1246
1247                    Intent intent = new Intent("android.intent.action.ANR");
1248                    if (!mProcessesReady) {
1249                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1250                                | Intent.FLAG_RECEIVER_FOREGROUND);
1251                    }
1252                    broadcastIntentLocked(null, null, intent,
1253                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1254                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1255
1256                    if (mShowDialogs) {
1257                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1258                                mContext, proc, (ActivityRecord)data.get("activity"),
1259                                msg.arg1 != 0);
1260                        d.show();
1261                        proc.anrDialog = d;
1262                    } else {
1263                        // Just kill the app if there is no dialog to be shown.
1264                        killAppAtUsersRequest(proc, null);
1265                    }
1266                }
1267
1268                ensureBootCompleted();
1269            } break;
1270            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1271                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1272                synchronized (ActivityManagerService.this) {
1273                    ProcessRecord proc = (ProcessRecord) data.get("app");
1274                    if (proc == null) {
1275                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1276                        break;
1277                    }
1278                    if (proc.crashDialog != null) {
1279                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1280                        return;
1281                    }
1282                    AppErrorResult res = (AppErrorResult) data.get("result");
1283                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1284                        Dialog d = new StrictModeViolationDialog(mContext,
1285                                ActivityManagerService.this, res, proc);
1286                        d.show();
1287                        proc.crashDialog = d;
1288                    } else {
1289                        // The device is asleep, so just pretend that the user
1290                        // saw a crash dialog and hit "force quit".
1291                        res.set(0);
1292                    }
1293                }
1294                ensureBootCompleted();
1295            } break;
1296            case SHOW_FACTORY_ERROR_MSG: {
1297                Dialog d = new FactoryErrorDialog(
1298                    mContext, msg.getData().getCharSequence("msg"));
1299                d.show();
1300                ensureBootCompleted();
1301            } break;
1302            case UPDATE_CONFIGURATION_MSG: {
1303                final ContentResolver resolver = mContext.getContentResolver();
1304                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1305            } break;
1306            case GC_BACKGROUND_PROCESSES_MSG: {
1307                synchronized (ActivityManagerService.this) {
1308                    performAppGcsIfAppropriateLocked();
1309                }
1310            } break;
1311            case WAIT_FOR_DEBUGGER_MSG: {
1312                synchronized (ActivityManagerService.this) {
1313                    ProcessRecord app = (ProcessRecord)msg.obj;
1314                    if (msg.arg1 != 0) {
1315                        if (!app.waitedForDebugger) {
1316                            Dialog d = new AppWaitingForDebuggerDialog(
1317                                    ActivityManagerService.this,
1318                                    mContext, app);
1319                            app.waitDialog = d;
1320                            app.waitedForDebugger = true;
1321                            d.show();
1322                        }
1323                    } else {
1324                        if (app.waitDialog != null) {
1325                            app.waitDialog.dismiss();
1326                            app.waitDialog = null;
1327                        }
1328                    }
1329                }
1330            } break;
1331            case SERVICE_TIMEOUT_MSG: {
1332                if (mDidDexOpt) {
1333                    mDidDexOpt = false;
1334                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1335                    nmsg.obj = msg.obj;
1336                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1337                    return;
1338                }
1339                mServices.serviceTimeout((ProcessRecord)msg.obj);
1340            } break;
1341            case UPDATE_TIME_ZONE: {
1342                synchronized (ActivityManagerService.this) {
1343                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1344                        ProcessRecord r = mLruProcesses.get(i);
1345                        if (r.thread != null) {
1346                            try {
1347                                r.thread.updateTimeZone();
1348                            } catch (RemoteException ex) {
1349                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1350                            }
1351                        }
1352                    }
1353                }
1354            } break;
1355            case CLEAR_DNS_CACHE_MSG: {
1356                synchronized (ActivityManagerService.this) {
1357                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1358                        ProcessRecord r = mLruProcesses.get(i);
1359                        if (r.thread != null) {
1360                            try {
1361                                r.thread.clearDnsCache();
1362                            } catch (RemoteException ex) {
1363                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1364                            }
1365                        }
1366                    }
1367                }
1368            } break;
1369            case UPDATE_HTTP_PROXY_MSG: {
1370                ProxyInfo proxy = (ProxyInfo)msg.obj;
1371                String host = "";
1372                String port = "";
1373                String exclList = "";
1374                Uri pacFileUrl = Uri.EMPTY;
1375                if (proxy != null) {
1376                    host = proxy.getHost();
1377                    port = Integer.toString(proxy.getPort());
1378                    exclList = proxy.getExclusionListAsString();
1379                    pacFileUrl = proxy.getPacFileUrl();
1380                }
1381                synchronized (ActivityManagerService.this) {
1382                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1383                        ProcessRecord r = mLruProcesses.get(i);
1384                        if (r.thread != null) {
1385                            try {
1386                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1387                            } catch (RemoteException ex) {
1388                                Slog.w(TAG, "Failed to update http proxy for: " +
1389                                        r.info.processName);
1390                            }
1391                        }
1392                    }
1393                }
1394            } break;
1395            case SHOW_UID_ERROR_MSG: {
1396                String title = "System UIDs Inconsistent";
1397                String text = "UIDs on the system are inconsistent, you need to wipe your"
1398                        + " data partition or your device will be unstable.";
1399                Log.e(TAG, title + ": " + text);
1400                if (mShowDialogs) {
1401                    // XXX This is a temporary dialog, no need to localize.
1402                    AlertDialog d = new BaseErrorDialog(mContext);
1403                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1404                    d.setCancelable(false);
1405                    d.setTitle(title);
1406                    d.setMessage(text);
1407                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1408                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1409                    mUidAlert = d;
1410                    d.show();
1411                }
1412            } break;
1413            case IM_FEELING_LUCKY_MSG: {
1414                if (mUidAlert != null) {
1415                    mUidAlert.dismiss();
1416                    mUidAlert = null;
1417                }
1418            } break;
1419            case PROC_START_TIMEOUT_MSG: {
1420                if (mDidDexOpt) {
1421                    mDidDexOpt = false;
1422                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1423                    nmsg.obj = msg.obj;
1424                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1425                    return;
1426                }
1427                ProcessRecord app = (ProcessRecord)msg.obj;
1428                synchronized (ActivityManagerService.this) {
1429                    processStartTimedOutLocked(app);
1430                }
1431            } break;
1432            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1433                synchronized (ActivityManagerService.this) {
1434                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1435                }
1436            } break;
1437            case KILL_APPLICATION_MSG: {
1438                synchronized (ActivityManagerService.this) {
1439                    int appid = msg.arg1;
1440                    boolean restart = (msg.arg2 == 1);
1441                    Bundle bundle = (Bundle)msg.obj;
1442                    String pkg = bundle.getString("pkg");
1443                    String reason = bundle.getString("reason");
1444                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1445                            false, UserHandle.USER_ALL, reason);
1446                }
1447            } break;
1448            case FINALIZE_PENDING_INTENT_MSG: {
1449                ((PendingIntentRecord)msg.obj).completeFinalize();
1450            } break;
1451            case POST_HEAVY_NOTIFICATION_MSG: {
1452                INotificationManager inm = NotificationManager.getService();
1453                if (inm == null) {
1454                    return;
1455                }
1456
1457                ActivityRecord root = (ActivityRecord)msg.obj;
1458                ProcessRecord process = root.app;
1459                if (process == null) {
1460                    return;
1461                }
1462
1463                try {
1464                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1465                    String text = mContext.getString(R.string.heavy_weight_notification,
1466                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1467                    Notification notification = new Notification();
1468                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1469                    notification.when = 0;
1470                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1471                    notification.tickerText = text;
1472                    notification.defaults = 0; // please be quiet
1473                    notification.sound = null;
1474                    notification.vibrate = null;
1475                    notification.color = mContext.getResources().getColor(
1476                            com.android.internal.R.color.system_notification_accent_color);
1477                    notification.setLatestEventInfo(context, text,
1478                            mContext.getText(R.string.heavy_weight_notification_detail),
1479                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1480                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1481                                    new UserHandle(root.userId)));
1482
1483                    try {
1484                        int[] outId = new int[1];
1485                        inm.enqueueNotificationWithTag("android", "android", null,
1486                                R.string.heavy_weight_notification,
1487                                notification, outId, root.userId);
1488                    } catch (RuntimeException e) {
1489                        Slog.w(ActivityManagerService.TAG,
1490                                "Error showing notification for heavy-weight app", e);
1491                    } catch (RemoteException e) {
1492                    }
1493                } catch (NameNotFoundException e) {
1494                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1495                }
1496            } break;
1497            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1498                INotificationManager inm = NotificationManager.getService();
1499                if (inm == null) {
1500                    return;
1501                }
1502                try {
1503                    inm.cancelNotificationWithTag("android", null,
1504                            R.string.heavy_weight_notification,  msg.arg1);
1505                } catch (RuntimeException e) {
1506                    Slog.w(ActivityManagerService.TAG,
1507                            "Error canceling notification for service", e);
1508                } catch (RemoteException e) {
1509                }
1510            } break;
1511            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1512                synchronized (ActivityManagerService.this) {
1513                    checkExcessivePowerUsageLocked(true);
1514                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1515                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1516                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1517                }
1518            } break;
1519            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1520                synchronized (ActivityManagerService.this) {
1521                    ActivityRecord ar = (ActivityRecord)msg.obj;
1522                    if (mCompatModeDialog != null) {
1523                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1524                                ar.info.applicationInfo.packageName)) {
1525                            return;
1526                        }
1527                        mCompatModeDialog.dismiss();
1528                        mCompatModeDialog = null;
1529                    }
1530                    if (ar != null && false) {
1531                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1532                                ar.packageName)) {
1533                            int mode = mCompatModePackages.computeCompatModeLocked(
1534                                    ar.info.applicationInfo);
1535                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1536                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1537                                mCompatModeDialog = new CompatModeDialog(
1538                                        ActivityManagerService.this, mContext,
1539                                        ar.info.applicationInfo);
1540                                mCompatModeDialog.show();
1541                            }
1542                        }
1543                    }
1544                }
1545                break;
1546            }
1547            case DISPATCH_PROCESSES_CHANGED: {
1548                dispatchProcessesChanged();
1549                break;
1550            }
1551            case DISPATCH_PROCESS_DIED: {
1552                final int pid = msg.arg1;
1553                final int uid = msg.arg2;
1554                dispatchProcessDied(pid, uid);
1555                break;
1556            }
1557            case REPORT_MEM_USAGE_MSG: {
1558                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1559                Thread thread = new Thread() {
1560                    @Override public void run() {
1561                        final SparseArray<ProcessMemInfo> infoMap
1562                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1563                        for (int i=0, N=memInfos.size(); i<N; i++) {
1564                            ProcessMemInfo mi = memInfos.get(i);
1565                            infoMap.put(mi.pid, mi);
1566                        }
1567                        updateCpuStatsNow();
1568                        synchronized (mProcessCpuThread) {
1569                            final int N = mProcessCpuTracker.countStats();
1570                            for (int i=0; i<N; i++) {
1571                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1572                                if (st.vsize > 0) {
1573                                    long pss = Debug.getPss(st.pid, null);
1574                                    if (pss > 0) {
1575                                        if (infoMap.indexOfKey(st.pid) < 0) {
1576                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1577                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1578                                            mi.pss = pss;
1579                                            memInfos.add(mi);
1580                                        }
1581                                    }
1582                                }
1583                            }
1584                        }
1585
1586                        long totalPss = 0;
1587                        for (int i=0, N=memInfos.size(); i<N; i++) {
1588                            ProcessMemInfo mi = memInfos.get(i);
1589                            if (mi.pss == 0) {
1590                                mi.pss = Debug.getPss(mi.pid, null);
1591                            }
1592                            totalPss += mi.pss;
1593                        }
1594                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1595                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1596                                if (lhs.oomAdj != rhs.oomAdj) {
1597                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1598                                }
1599                                if (lhs.pss != rhs.pss) {
1600                                    return lhs.pss < rhs.pss ? 1 : -1;
1601                                }
1602                                return 0;
1603                            }
1604                        });
1605
1606                        StringBuilder tag = new StringBuilder(128);
1607                        StringBuilder stack = new StringBuilder(128);
1608                        tag.append("Low on memory -- ");
1609                        appendMemBucket(tag, totalPss, "total", false);
1610                        appendMemBucket(stack, totalPss, "total", true);
1611
1612                        StringBuilder logBuilder = new StringBuilder(1024);
1613                        logBuilder.append("Low on memory:\n");
1614
1615                        boolean firstLine = true;
1616                        int lastOomAdj = Integer.MIN_VALUE;
1617                        for (int i=0, N=memInfos.size(); i<N; i++) {
1618                            ProcessMemInfo mi = memInfos.get(i);
1619
1620                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1621                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1622                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1623                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1624                                if (lastOomAdj != mi.oomAdj) {
1625                                    lastOomAdj = mi.oomAdj;
1626                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1627                                        tag.append(" / ");
1628                                    }
1629                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1630                                        if (firstLine) {
1631                                            stack.append(":");
1632                                            firstLine = false;
1633                                        }
1634                                        stack.append("\n\t at ");
1635                                    } else {
1636                                        stack.append("$");
1637                                    }
1638                                } else {
1639                                    tag.append(" ");
1640                                    stack.append("$");
1641                                }
1642                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1643                                    appendMemBucket(tag, mi.pss, mi.name, false);
1644                                }
1645                                appendMemBucket(stack, mi.pss, mi.name, true);
1646                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1647                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1648                                    stack.append("(");
1649                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1650                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1651                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1652                                            stack.append(":");
1653                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1654                                        }
1655                                    }
1656                                    stack.append(")");
1657                                }
1658                            }
1659
1660                            logBuilder.append("  ");
1661                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1662                            logBuilder.append(' ');
1663                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1664                            logBuilder.append(' ');
1665                            ProcessList.appendRamKb(logBuilder, mi.pss);
1666                            logBuilder.append(" kB: ");
1667                            logBuilder.append(mi.name);
1668                            logBuilder.append(" (");
1669                            logBuilder.append(mi.pid);
1670                            logBuilder.append(") ");
1671                            logBuilder.append(mi.adjType);
1672                            logBuilder.append('\n');
1673                            if (mi.adjReason != null) {
1674                                logBuilder.append("                      ");
1675                                logBuilder.append(mi.adjReason);
1676                                logBuilder.append('\n');
1677                            }
1678                        }
1679
1680                        logBuilder.append("           ");
1681                        ProcessList.appendRamKb(logBuilder, totalPss);
1682                        logBuilder.append(" kB: TOTAL\n");
1683
1684                        long[] infos = new long[Debug.MEMINFO_COUNT];
1685                        Debug.getMemInfo(infos);
1686                        logBuilder.append("  MemInfo: ");
1687                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1688                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1689                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1690                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1691                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1692                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1693                            logBuilder.append("  ZRAM: ");
1694                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1695                            logBuilder.append(" kB RAM, ");
1696                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1697                            logBuilder.append(" kB swap total, ");
1698                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1699                            logBuilder.append(" kB swap free\n");
1700                        }
1701                        Slog.i(TAG, logBuilder.toString());
1702
1703                        StringBuilder dropBuilder = new StringBuilder(1024);
1704                        /*
1705                        StringWriter oomSw = new StringWriter();
1706                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1707                        StringWriter catSw = new StringWriter();
1708                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1709                        String[] emptyArgs = new String[] { };
1710                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1711                        oomPw.flush();
1712                        String oomString = oomSw.toString();
1713                        */
1714                        dropBuilder.append(stack);
1715                        dropBuilder.append('\n');
1716                        dropBuilder.append('\n');
1717                        dropBuilder.append(logBuilder);
1718                        dropBuilder.append('\n');
1719                        /*
1720                        dropBuilder.append(oomString);
1721                        dropBuilder.append('\n');
1722                        */
1723                        StringWriter catSw = new StringWriter();
1724                        synchronized (ActivityManagerService.this) {
1725                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1726                            String[] emptyArgs = new String[] { };
1727                            catPw.println();
1728                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1729                            catPw.println();
1730                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1731                                    false, false, null);
1732                            catPw.println();
1733                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1734                            catPw.flush();
1735                        }
1736                        dropBuilder.append(catSw.toString());
1737                        addErrorToDropBox("lowmem", null, "system_server", null,
1738                                null, tag.toString(), dropBuilder.toString(), null, null);
1739                        //Slog.i(TAG, "Sent to dropbox:");
1740                        //Slog.i(TAG, dropBuilder.toString());
1741                        synchronized (ActivityManagerService.this) {
1742                            long now = SystemClock.uptimeMillis();
1743                            if (mLastMemUsageReportTime < now) {
1744                                mLastMemUsageReportTime = now;
1745                            }
1746                        }
1747                    }
1748                };
1749                thread.start();
1750                break;
1751            }
1752            case REPORT_USER_SWITCH_MSG: {
1753                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1754                break;
1755            }
1756            case CONTINUE_USER_SWITCH_MSG: {
1757                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1758                break;
1759            }
1760            case USER_SWITCH_TIMEOUT_MSG: {
1761                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1762                break;
1763            }
1764            case IMMERSIVE_MODE_LOCK_MSG: {
1765                final boolean nextState = (msg.arg1 != 0);
1766                if (mUpdateLock.isHeld() != nextState) {
1767                    if (DEBUG_IMMERSIVE) {
1768                        final ActivityRecord r = (ActivityRecord) msg.obj;
1769                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1770                    }
1771                    if (nextState) {
1772                        mUpdateLock.acquire();
1773                    } else {
1774                        mUpdateLock.release();
1775                    }
1776                }
1777                break;
1778            }
1779            case PERSIST_URI_GRANTS_MSG: {
1780                writeGrantedUriPermissions();
1781                break;
1782            }
1783            case REQUEST_ALL_PSS_MSG: {
1784                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1785                break;
1786            }
1787            case START_PROFILES_MSG: {
1788                synchronized (ActivityManagerService.this) {
1789                    startProfilesLocked();
1790                }
1791                break;
1792            }
1793            case UPDATE_TIME: {
1794                synchronized (ActivityManagerService.this) {
1795                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1796                        ProcessRecord r = mLruProcesses.get(i);
1797                        if (r.thread != null) {
1798                            try {
1799                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1800                            } catch (RemoteException ex) {
1801                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1802                            }
1803                        }
1804                    }
1805                }
1806                break;
1807            }
1808            case SYSTEM_USER_START_MSG: {
1809                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1810                        Integer.toString(msg.arg1), msg.arg1);
1811                mSystemServiceManager.startUser(msg.arg1);
1812                break;
1813            }
1814            case SYSTEM_USER_CURRENT_MSG: {
1815                mBatteryStatsService.noteEvent(
1816                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1817                        Integer.toString(msg.arg2), msg.arg2);
1818                mBatteryStatsService.noteEvent(
1819                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1820                        Integer.toString(msg.arg1), msg.arg1);
1821                mSystemServiceManager.switchUser(msg.arg1);
1822                break;
1823            }
1824            case ENTER_ANIMATION_COMPLETE_MSG: {
1825                synchronized (ActivityManagerService.this) {
1826                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1827                    if (r != null && r.app != null && r.app.thread != null) {
1828                        try {
1829                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1830                        } catch (RemoteException e) {
1831                        }
1832                    }
1833                }
1834                break;
1835            }
1836            case ENABLE_SCREEN_AFTER_BOOT_MSG: {
1837                enableScreenAfterBoot();
1838                break;
1839            }
1840            }
1841        }
1842    };
1843
1844    static final int COLLECT_PSS_BG_MSG = 1;
1845
1846    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1847        @Override
1848        public void handleMessage(Message msg) {
1849            switch (msg.what) {
1850            case COLLECT_PSS_BG_MSG: {
1851                long start = SystemClock.uptimeMillis();
1852                MemInfoReader memInfo = null;
1853                synchronized (ActivityManagerService.this) {
1854                    if (mFullPssPending) {
1855                        mFullPssPending = false;
1856                        memInfo = new MemInfoReader();
1857                    }
1858                }
1859                if (memInfo != null) {
1860                    updateCpuStatsNow();
1861                    long nativeTotalPss = 0;
1862                    synchronized (mProcessCpuThread) {
1863                        final int N = mProcessCpuTracker.countStats();
1864                        for (int j=0; j<N; j++) {
1865                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1866                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1867                                // This is definitely an application process; skip it.
1868                                continue;
1869                            }
1870                            synchronized (mPidsSelfLocked) {
1871                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1872                                    // This is one of our own processes; skip it.
1873                                    continue;
1874                                }
1875                            }
1876                            nativeTotalPss += Debug.getPss(st.pid, null);
1877                        }
1878                    }
1879                    memInfo.readMemInfo();
1880                    synchronized (this) {
1881                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1882                                + (SystemClock.uptimeMillis()-start) + "ms");
1883                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1884                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1885                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1886                                        +memInfo.getSlabSizeKb(),
1887                                nativeTotalPss);
1888                    }
1889                }
1890
1891                int i=0, num=0;
1892                long[] tmp = new long[1];
1893                do {
1894                    ProcessRecord proc;
1895                    int procState;
1896                    int pid;
1897                    synchronized (ActivityManagerService.this) {
1898                        if (i >= mPendingPssProcesses.size()) {
1899                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1900                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1901                            mPendingPssProcesses.clear();
1902                            return;
1903                        }
1904                        proc = mPendingPssProcesses.get(i);
1905                        procState = proc.pssProcState;
1906                        if (proc.thread != null && procState == proc.setProcState) {
1907                            pid = proc.pid;
1908                        } else {
1909                            proc = null;
1910                            pid = 0;
1911                        }
1912                        i++;
1913                    }
1914                    if (proc != null) {
1915                        long pss = Debug.getPss(pid, tmp);
1916                        synchronized (ActivityManagerService.this) {
1917                            if (proc.thread != null && proc.setProcState == procState
1918                                    && proc.pid == pid) {
1919                                num++;
1920                                proc.lastPssTime = SystemClock.uptimeMillis();
1921                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1922                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1923                                        + ": " + pss + " lastPss=" + proc.lastPss
1924                                        + " state=" + ProcessList.makeProcStateString(procState));
1925                                if (proc.initialIdlePss == 0) {
1926                                    proc.initialIdlePss = pss;
1927                                }
1928                                proc.lastPss = pss;
1929                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1930                                    proc.lastCachedPss = pss;
1931                                }
1932                            }
1933                        }
1934                    }
1935                } while (true);
1936            }
1937            }
1938        }
1939    };
1940
1941    /**
1942     * Monitor for package changes and update our internal state.
1943     */
1944    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1945        @Override
1946        public void onPackageRemoved(String packageName, int uid) {
1947            // Remove all tasks with activities in the specified package from the list of recent tasks
1948            synchronized (ActivityManagerService.this) {
1949                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1950                    TaskRecord tr = mRecentTasks.get(i);
1951                    ComponentName cn = tr.intent.getComponent();
1952                    if (cn != null && cn.getPackageName().equals(packageName)) {
1953                        // If the package name matches, remove the task and kill the process
1954                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1955                    }
1956                }
1957            }
1958        }
1959
1960        @Override
1961        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1962            onPackageModified(packageName);
1963            return true;
1964        }
1965
1966        @Override
1967        public void onPackageModified(String packageName) {
1968            final PackageManager pm = mContext.getPackageManager();
1969            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1970                    new ArrayList<Pair<Intent, Integer>>();
1971            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1972            // Copy the list of recent tasks so that we don't hold onto the lock on
1973            // ActivityManagerService for long periods while checking if components exist.
1974            synchronized (ActivityManagerService.this) {
1975                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1976                    TaskRecord tr = mRecentTasks.get(i);
1977                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1978                }
1979            }
1980            // Check the recent tasks and filter out all tasks with components that no longer exist.
1981            Intent tmpI = new Intent();
1982            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1983                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1984                ComponentName cn = p.first.getComponent();
1985                if (cn != null && cn.getPackageName().equals(packageName)) {
1986                    try {
1987                        // Add the task to the list to remove if the component no longer exists
1988                        tmpI.setComponent(cn);
1989                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1990                            tasksToRemove.add(p.second);
1991                        }
1992                    } catch (Exception e) {}
1993                }
1994            }
1995            // Prune all the tasks with removed components from the list of recent tasks
1996            synchronized (ActivityManagerService.this) {
1997                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1998                    // Remove the task but don't kill the process (since other components in that
1999                    // package may still be running and in the background)
2000                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
2001                }
2002            }
2003        }
2004
2005        @Override
2006        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2007            // Force stop the specified packages
2008            if (packages != null) {
2009                for (String pkg : packages) {
2010                    synchronized (ActivityManagerService.this) {
2011                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2012                                "finished booting")) {
2013                            return true;
2014                        }
2015                    }
2016                }
2017            }
2018            return false;
2019        }
2020    };
2021
2022    public void setSystemProcess() {
2023        try {
2024            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2025            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2026            ServiceManager.addService("meminfo", new MemBinder(this));
2027            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2028            ServiceManager.addService("dbinfo", new DbBinder(this));
2029            if (MONITOR_CPU_USAGE) {
2030                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2031            }
2032            ServiceManager.addService("permission", new PermissionController(this));
2033
2034            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2035                    "android", STOCK_PM_FLAGS);
2036            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2037
2038            synchronized (this) {
2039                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2040                app.persistent = true;
2041                app.pid = MY_PID;
2042                app.maxAdj = ProcessList.SYSTEM_ADJ;
2043                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2044                mProcessNames.put(app.processName, app.uid, app);
2045                synchronized (mPidsSelfLocked) {
2046                    mPidsSelfLocked.put(app.pid, app);
2047                }
2048                updateLruProcessLocked(app, false, null);
2049                updateOomAdjLocked();
2050            }
2051        } catch (PackageManager.NameNotFoundException e) {
2052            throw new RuntimeException(
2053                    "Unable to find android system package", e);
2054        }
2055    }
2056
2057    public void setWindowManager(WindowManagerService wm) {
2058        mWindowManager = wm;
2059        mStackSupervisor.setWindowManager(wm);
2060    }
2061
2062    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2063        mUsageStatsService = usageStatsManager;
2064    }
2065
2066    public void startObservingNativeCrashes() {
2067        final NativeCrashListener ncl = new NativeCrashListener(this);
2068        ncl.start();
2069    }
2070
2071    public IAppOpsService getAppOpsService() {
2072        return mAppOpsService;
2073    }
2074
2075    static class MemBinder extends Binder {
2076        ActivityManagerService mActivityManagerService;
2077        MemBinder(ActivityManagerService activityManagerService) {
2078            mActivityManagerService = activityManagerService;
2079        }
2080
2081        @Override
2082        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2083            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2084                    != PackageManager.PERMISSION_GRANTED) {
2085                pw.println("Permission Denial: can't dump meminfo from from pid="
2086                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2087                        + " without permission " + android.Manifest.permission.DUMP);
2088                return;
2089            }
2090
2091            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2092        }
2093    }
2094
2095    static class GraphicsBinder extends Binder {
2096        ActivityManagerService mActivityManagerService;
2097        GraphicsBinder(ActivityManagerService activityManagerService) {
2098            mActivityManagerService = activityManagerService;
2099        }
2100
2101        @Override
2102        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2103            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2104                    != PackageManager.PERMISSION_GRANTED) {
2105                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2106                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2107                        + " without permission " + android.Manifest.permission.DUMP);
2108                return;
2109            }
2110
2111            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2112        }
2113    }
2114
2115    static class DbBinder extends Binder {
2116        ActivityManagerService mActivityManagerService;
2117        DbBinder(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 dbinfo from from pid="
2126                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2127                        + " without permission " + android.Manifest.permission.DUMP);
2128                return;
2129            }
2130
2131            mActivityManagerService.dumpDbInfo(fd, pw, args);
2132        }
2133    }
2134
2135    static class CpuBinder extends Binder {
2136        ActivityManagerService mActivityManagerService;
2137        CpuBinder(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 cpuinfo from from pid="
2146                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2147                        + " without permission " + android.Manifest.permission.DUMP);
2148                return;
2149            }
2150
2151            synchronized (mActivityManagerService.mProcessCpuThread) {
2152                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2153                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2154                        SystemClock.uptimeMillis()));
2155            }
2156        }
2157    }
2158
2159    public static final class Lifecycle extends SystemService {
2160        private final ActivityManagerService mService;
2161
2162        public Lifecycle(Context context) {
2163            super(context);
2164            mService = new ActivityManagerService(context);
2165        }
2166
2167        @Override
2168        public void onStart() {
2169            mService.start();
2170        }
2171
2172        public ActivityManagerService getService() {
2173            return mService;
2174        }
2175    }
2176
2177    // Note: This method is invoked on the main thread but may need to attach various
2178    // handlers to other threads.  So take care to be explicit about the looper.
2179    public ActivityManagerService(Context systemContext) {
2180        mContext = systemContext;
2181        mFactoryTest = FactoryTest.getMode();
2182        mSystemThread = ActivityThread.currentActivityThread();
2183
2184        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2185
2186        mHandlerThread = new ServiceThread(TAG,
2187                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2188        mHandlerThread.start();
2189        mHandler = new MainHandler(mHandlerThread.getLooper());
2190
2191        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2192                "foreground", BROADCAST_FG_TIMEOUT, false);
2193        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2194                "background", BROADCAST_BG_TIMEOUT, true);
2195        mBroadcastQueues[0] = mFgBroadcastQueue;
2196        mBroadcastQueues[1] = mBgBroadcastQueue;
2197
2198        mServices = new ActiveServices(this);
2199        mProviderMap = new ProviderMap(this);
2200
2201        // TODO: Move creation of battery stats service outside of activity manager service.
2202        File dataDir = Environment.getDataDirectory();
2203        File systemDir = new File(dataDir, "system");
2204        systemDir.mkdirs();
2205        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2206        mBatteryStatsService.getActiveStatistics().readLocked();
2207        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2208        mOnBattery = DEBUG_POWER ? true
2209                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2210        mBatteryStatsService.getActiveStatistics().setCallback(this);
2211
2212        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2213
2214        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2215
2216        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2217
2218        // User 0 is the first and only user that runs at boot.
2219        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2220        mUserLru.add(Integer.valueOf(0));
2221        updateStartedUserArrayLocked();
2222
2223        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2224            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2225
2226        mConfiguration.setToDefaults();
2227        mConfiguration.setLocale(Locale.getDefault());
2228
2229        mConfigurationSeq = mConfiguration.seq = 1;
2230        mProcessCpuTracker.init();
2231
2232        mHasRecents = mContext.getResources().getBoolean(
2233                com.android.internal.R.bool.config_hasRecents);
2234
2235        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2236        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2237        mStackSupervisor = new ActivityStackSupervisor(this);
2238        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2239
2240        mProcessCpuThread = new Thread("CpuTracker") {
2241            @Override
2242            public void run() {
2243                while (true) {
2244                    try {
2245                        try {
2246                            synchronized(this) {
2247                                final long now = SystemClock.uptimeMillis();
2248                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2249                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2250                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2251                                //        + ", write delay=" + nextWriteDelay);
2252                                if (nextWriteDelay < nextCpuDelay) {
2253                                    nextCpuDelay = nextWriteDelay;
2254                                }
2255                                if (nextCpuDelay > 0) {
2256                                    mProcessCpuMutexFree.set(true);
2257                                    this.wait(nextCpuDelay);
2258                                }
2259                            }
2260                        } catch (InterruptedException e) {
2261                        }
2262                        updateCpuStatsNow();
2263                    } catch (Exception e) {
2264                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2265                    }
2266                }
2267            }
2268        };
2269
2270        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2271
2272        Watchdog.getInstance().addMonitor(this);
2273        Watchdog.getInstance().addThread(mHandler);
2274    }
2275
2276    public void setSystemServiceManager(SystemServiceManager mgr) {
2277        mSystemServiceManager = mgr;
2278    }
2279
2280    private void start() {
2281        Process.removeAllProcessGroups();
2282        mProcessCpuThread.start();
2283
2284        mBatteryStatsService.publish(mContext);
2285        mAppOpsService.publish(mContext);
2286        Slog.d("AppOps", "AppOpsService published");
2287        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2288    }
2289
2290    public void initPowerManagement() {
2291        mStackSupervisor.initPowerManagement();
2292        mBatteryStatsService.initPowerManagement();
2293    }
2294
2295    @Override
2296    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2297            throws RemoteException {
2298        if (code == SYSPROPS_TRANSACTION) {
2299            // We need to tell all apps about the system property change.
2300            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2301            synchronized(this) {
2302                final int NP = mProcessNames.getMap().size();
2303                for (int ip=0; ip<NP; ip++) {
2304                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2305                    final int NA = apps.size();
2306                    for (int ia=0; ia<NA; ia++) {
2307                        ProcessRecord app = apps.valueAt(ia);
2308                        if (app.thread != null) {
2309                            procs.add(app.thread.asBinder());
2310                        }
2311                    }
2312                }
2313            }
2314
2315            int N = procs.size();
2316            for (int i=0; i<N; i++) {
2317                Parcel data2 = Parcel.obtain();
2318                try {
2319                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2320                } catch (RemoteException e) {
2321                }
2322                data2.recycle();
2323            }
2324        }
2325        try {
2326            return super.onTransact(code, data, reply, flags);
2327        } catch (RuntimeException e) {
2328            // The activity manager only throws security exceptions, so let's
2329            // log all others.
2330            if (!(e instanceof SecurityException)) {
2331                Slog.wtf(TAG, "Activity Manager Crash", e);
2332            }
2333            throw e;
2334        }
2335    }
2336
2337    void updateCpuStats() {
2338        final long now = SystemClock.uptimeMillis();
2339        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2340            return;
2341        }
2342        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2343            synchronized (mProcessCpuThread) {
2344                mProcessCpuThread.notify();
2345            }
2346        }
2347    }
2348
2349    void updateCpuStatsNow() {
2350        synchronized (mProcessCpuThread) {
2351            mProcessCpuMutexFree.set(false);
2352            final long now = SystemClock.uptimeMillis();
2353            boolean haveNewCpuStats = false;
2354
2355            if (MONITOR_CPU_USAGE &&
2356                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2357                mLastCpuTime.set(now);
2358                haveNewCpuStats = true;
2359                mProcessCpuTracker.update();
2360                //Slog.i(TAG, mProcessCpu.printCurrentState());
2361                //Slog.i(TAG, "Total CPU usage: "
2362                //        + mProcessCpu.getTotalCpuPercent() + "%");
2363
2364                // Slog the cpu usage if the property is set.
2365                if ("true".equals(SystemProperties.get("events.cpu"))) {
2366                    int user = mProcessCpuTracker.getLastUserTime();
2367                    int system = mProcessCpuTracker.getLastSystemTime();
2368                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2369                    int irq = mProcessCpuTracker.getLastIrqTime();
2370                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2371                    int idle = mProcessCpuTracker.getLastIdleTime();
2372
2373                    int total = user + system + iowait + irq + softIrq + idle;
2374                    if (total == 0) total = 1;
2375
2376                    EventLog.writeEvent(EventLogTags.CPU,
2377                            ((user+system+iowait+irq+softIrq) * 100) / total,
2378                            (user * 100) / total,
2379                            (system * 100) / total,
2380                            (iowait * 100) / total,
2381                            (irq * 100) / total,
2382                            (softIrq * 100) / total);
2383                }
2384            }
2385
2386            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2387            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2388            synchronized(bstats) {
2389                synchronized(mPidsSelfLocked) {
2390                    if (haveNewCpuStats) {
2391                        if (mOnBattery) {
2392                            int perc = bstats.startAddingCpuLocked();
2393                            int totalUTime = 0;
2394                            int totalSTime = 0;
2395                            final int N = mProcessCpuTracker.countStats();
2396                            for (int i=0; i<N; i++) {
2397                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2398                                if (!st.working) {
2399                                    continue;
2400                                }
2401                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2402                                int otherUTime = (st.rel_utime*perc)/100;
2403                                int otherSTime = (st.rel_stime*perc)/100;
2404                                totalUTime += otherUTime;
2405                                totalSTime += otherSTime;
2406                                if (pr != null) {
2407                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2408                                    if (ps == null || !ps.isActive()) {
2409                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2410                                                pr.info.uid, pr.processName);
2411                                    }
2412                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2413                                            st.rel_stime-otherSTime);
2414                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2415                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2416                                } else {
2417                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2418                                    if (ps == null || !ps.isActive()) {
2419                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2420                                                bstats.mapUid(st.uid), st.name);
2421                                    }
2422                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2423                                            st.rel_stime-otherSTime);
2424                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2425                                }
2426                            }
2427                            bstats.finishAddingCpuLocked(perc, totalUTime,
2428                                    totalSTime, cpuSpeedTimes);
2429                        }
2430                    }
2431                }
2432
2433                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2434                    mLastWriteTime = now;
2435                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2436                }
2437            }
2438        }
2439    }
2440
2441    @Override
2442    public void batteryNeedsCpuUpdate() {
2443        updateCpuStatsNow();
2444    }
2445
2446    @Override
2447    public void batteryPowerChanged(boolean onBattery) {
2448        // When plugging in, update the CPU stats first before changing
2449        // the plug state.
2450        updateCpuStatsNow();
2451        synchronized (this) {
2452            synchronized(mPidsSelfLocked) {
2453                mOnBattery = DEBUG_POWER ? true : onBattery;
2454            }
2455        }
2456    }
2457
2458    /**
2459     * Initialize the application bind args. These are passed to each
2460     * process when the bindApplication() IPC is sent to the process. They're
2461     * lazily setup to make sure the services are running when they're asked for.
2462     */
2463    private HashMap<String, IBinder> getCommonServicesLocked() {
2464        if (mAppBindArgs == null) {
2465            mAppBindArgs = new HashMap<String, IBinder>();
2466
2467            // Setup the application init args
2468            mAppBindArgs.put("package", ServiceManager.getService("package"));
2469            mAppBindArgs.put("window", ServiceManager.getService("window"));
2470            mAppBindArgs.put(Context.ALARM_SERVICE,
2471                    ServiceManager.getService(Context.ALARM_SERVICE));
2472        }
2473        return mAppBindArgs;
2474    }
2475
2476    final void setFocusedActivityLocked(ActivityRecord r) {
2477        if (mFocusedActivity != r) {
2478            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2479            mFocusedActivity = r;
2480            if (r.task != null && r.task.voiceInteractor != null) {
2481                startRunningVoiceLocked();
2482            } else {
2483                finishRunningVoiceLocked();
2484            }
2485            mStackSupervisor.setFocusedStack(r);
2486            if (r != null) {
2487                mWindowManager.setFocusedApp(r.appToken, true);
2488            }
2489            applyUpdateLockStateLocked(r);
2490        }
2491    }
2492
2493    final void clearFocusedActivity(ActivityRecord r) {
2494        if (mFocusedActivity == r) {
2495            mFocusedActivity = null;
2496        }
2497    }
2498
2499    @Override
2500    public void setFocusedStack(int stackId) {
2501        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2502        synchronized (ActivityManagerService.this) {
2503            ActivityStack stack = mStackSupervisor.getStack(stackId);
2504            if (stack != null) {
2505                ActivityRecord r = stack.topRunningActivityLocked(null);
2506                if (r != null) {
2507                    setFocusedActivityLocked(r);
2508                }
2509            }
2510        }
2511    }
2512
2513    @Override
2514    public void notifyActivityDrawn(IBinder token) {
2515        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2516        synchronized (this) {
2517            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2518            if (r != null) {
2519                r.task.stack.notifyActivityDrawnLocked(r);
2520            }
2521        }
2522    }
2523
2524    final void applyUpdateLockStateLocked(ActivityRecord r) {
2525        // Modifications to the UpdateLock state are done on our handler, outside
2526        // the activity manager's locks.  The new state is determined based on the
2527        // state *now* of the relevant activity record.  The object is passed to
2528        // the handler solely for logging detail, not to be consulted/modified.
2529        final boolean nextState = r != null && r.immersive;
2530        mHandler.sendMessage(
2531                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2532    }
2533
2534    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2535        Message msg = Message.obtain();
2536        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2537        msg.obj = r.task.askedCompatMode ? null : r;
2538        mHandler.sendMessage(msg);
2539    }
2540
2541    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2542            String what, Object obj, ProcessRecord srcApp) {
2543        app.lastActivityTime = now;
2544
2545        if (app.activities.size() > 0) {
2546            // Don't want to touch dependent processes that are hosting activities.
2547            return index;
2548        }
2549
2550        int lrui = mLruProcesses.lastIndexOf(app);
2551        if (lrui < 0) {
2552            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2553                    + what + " " + obj + " from " + srcApp);
2554            return index;
2555        }
2556
2557        if (lrui >= index) {
2558            // Don't want to cause this to move dependent processes *back* in the
2559            // list as if they were less frequently used.
2560            return index;
2561        }
2562
2563        if (lrui >= mLruProcessActivityStart) {
2564            // Don't want to touch dependent processes that are hosting activities.
2565            return index;
2566        }
2567
2568        mLruProcesses.remove(lrui);
2569        if (index > 0) {
2570            index--;
2571        }
2572        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2573                + " in LRU list: " + app);
2574        mLruProcesses.add(index, app);
2575        return index;
2576    }
2577
2578    final void removeLruProcessLocked(ProcessRecord app) {
2579        int lrui = mLruProcesses.lastIndexOf(app);
2580        if (lrui >= 0) {
2581            if (lrui <= mLruProcessActivityStart) {
2582                mLruProcessActivityStart--;
2583            }
2584            if (lrui <= mLruProcessServiceStart) {
2585                mLruProcessServiceStart--;
2586            }
2587            mLruProcesses.remove(lrui);
2588        }
2589    }
2590
2591    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2592            ProcessRecord client) {
2593        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2594                || app.treatLikeActivity;
2595        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2596        if (!activityChange && hasActivity) {
2597            // The process has activities, so we are only allowing activity-based adjustments
2598            // to move it.  It should be kept in the front of the list with other
2599            // processes that have activities, and we don't want those to change their
2600            // order except due to activity operations.
2601            return;
2602        }
2603
2604        mLruSeq++;
2605        final long now = SystemClock.uptimeMillis();
2606        app.lastActivityTime = now;
2607
2608        // First a quick reject: if the app is already at the position we will
2609        // put it, then there is nothing to do.
2610        if (hasActivity) {
2611            final int N = mLruProcesses.size();
2612            if (N > 0 && mLruProcesses.get(N-1) == app) {
2613                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2614                return;
2615            }
2616        } else {
2617            if (mLruProcessServiceStart > 0
2618                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2619                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2620                return;
2621            }
2622        }
2623
2624        int lrui = mLruProcesses.lastIndexOf(app);
2625
2626        if (app.persistent && lrui >= 0) {
2627            // We don't care about the position of persistent processes, as long as
2628            // they are in the list.
2629            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2630            return;
2631        }
2632
2633        /* In progress: compute new position first, so we can avoid doing work
2634           if the process is not actually going to move.  Not yet working.
2635        int addIndex;
2636        int nextIndex;
2637        boolean inActivity = false, inService = false;
2638        if (hasActivity) {
2639            // Process has activities, put it at the very tipsy-top.
2640            addIndex = mLruProcesses.size();
2641            nextIndex = mLruProcessServiceStart;
2642            inActivity = true;
2643        } else if (hasService) {
2644            // Process has services, put it at the top of the service list.
2645            addIndex = mLruProcessActivityStart;
2646            nextIndex = mLruProcessServiceStart;
2647            inActivity = true;
2648            inService = true;
2649        } else  {
2650            // Process not otherwise of interest, it goes to the top of the non-service area.
2651            addIndex = mLruProcessServiceStart;
2652            if (client != null) {
2653                int clientIndex = mLruProcesses.lastIndexOf(client);
2654                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2655                        + app);
2656                if (clientIndex >= 0 && addIndex > clientIndex) {
2657                    addIndex = clientIndex;
2658                }
2659            }
2660            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2661        }
2662
2663        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2664                + mLruProcessActivityStart + "): " + app);
2665        */
2666
2667        if (lrui >= 0) {
2668            if (lrui < mLruProcessActivityStart) {
2669                mLruProcessActivityStart--;
2670            }
2671            if (lrui < mLruProcessServiceStart) {
2672                mLruProcessServiceStart--;
2673            }
2674            /*
2675            if (addIndex > lrui) {
2676                addIndex--;
2677            }
2678            if (nextIndex > lrui) {
2679                nextIndex--;
2680            }
2681            */
2682            mLruProcesses.remove(lrui);
2683        }
2684
2685        /*
2686        mLruProcesses.add(addIndex, app);
2687        if (inActivity) {
2688            mLruProcessActivityStart++;
2689        }
2690        if (inService) {
2691            mLruProcessActivityStart++;
2692        }
2693        */
2694
2695        int nextIndex;
2696        if (hasActivity) {
2697            final int N = mLruProcesses.size();
2698            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2699                // Process doesn't have activities, but has clients with
2700                // activities...  move it up, but one below the top (the top
2701                // should always have a real activity).
2702                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2703                mLruProcesses.add(N-1, app);
2704                // To keep it from spamming the LRU list (by making a bunch of clients),
2705                // we will push down any other entries owned by the app.
2706                final int uid = app.info.uid;
2707                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2708                    ProcessRecord subProc = mLruProcesses.get(i);
2709                    if (subProc.info.uid == uid) {
2710                        // We want to push this one down the list.  If the process after
2711                        // it is for the same uid, however, don't do so, because we don't
2712                        // want them internally to be re-ordered.
2713                        if (mLruProcesses.get(i-1).info.uid != uid) {
2714                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2715                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2716                            ProcessRecord tmp = mLruProcesses.get(i);
2717                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2718                            mLruProcesses.set(i-1, tmp);
2719                            i--;
2720                        }
2721                    } else {
2722                        // A gap, we can stop here.
2723                        break;
2724                    }
2725                }
2726            } else {
2727                // Process has activities, put it at the very tipsy-top.
2728                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2729                mLruProcesses.add(app);
2730            }
2731            nextIndex = mLruProcessServiceStart;
2732        } else if (hasService) {
2733            // Process has services, put it at the top of the service list.
2734            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2735            mLruProcesses.add(mLruProcessActivityStart, app);
2736            nextIndex = mLruProcessServiceStart;
2737            mLruProcessActivityStart++;
2738        } else  {
2739            // Process not otherwise of interest, it goes to the top of the non-service area.
2740            int index = mLruProcessServiceStart;
2741            if (client != null) {
2742                // If there is a client, don't allow the process to be moved up higher
2743                // in the list than that client.
2744                int clientIndex = mLruProcesses.lastIndexOf(client);
2745                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2746                        + " when updating " + app);
2747                if (clientIndex <= lrui) {
2748                    // Don't allow the client index restriction to push it down farther in the
2749                    // list than it already is.
2750                    clientIndex = lrui;
2751                }
2752                if (clientIndex >= 0 && index > clientIndex) {
2753                    index = clientIndex;
2754                }
2755            }
2756            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2757            mLruProcesses.add(index, app);
2758            nextIndex = index-1;
2759            mLruProcessActivityStart++;
2760            mLruProcessServiceStart++;
2761        }
2762
2763        // If the app is currently using a content provider or service,
2764        // bump those processes as well.
2765        for (int j=app.connections.size()-1; j>=0; j--) {
2766            ConnectionRecord cr = app.connections.valueAt(j);
2767            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2768                    && cr.binding.service.app != null
2769                    && cr.binding.service.app.lruSeq != mLruSeq
2770                    && !cr.binding.service.app.persistent) {
2771                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2772                        "service connection", cr, app);
2773            }
2774        }
2775        for (int j=app.conProviders.size()-1; j>=0; j--) {
2776            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2777            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2778                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2779                        "provider reference", cpr, app);
2780            }
2781        }
2782    }
2783
2784    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2785        if (uid == Process.SYSTEM_UID) {
2786            // The system gets to run in any process.  If there are multiple
2787            // processes with the same uid, just pick the first (this
2788            // should never happen).
2789            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2790            if (procs == null) return null;
2791            final int N = procs.size();
2792            for (int i = 0; i < N; i++) {
2793                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2794            }
2795        }
2796        ProcessRecord proc = mProcessNames.get(processName, uid);
2797        if (false && proc != null && !keepIfLarge
2798                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2799                && proc.lastCachedPss >= 4000) {
2800            // Turn this condition on to cause killing to happen regularly, for testing.
2801            if (proc.baseProcessTracker != null) {
2802                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2803            }
2804            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2805                    + "k from cached");
2806        } else if (proc != null && !keepIfLarge
2807                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2808                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2809            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2810            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2811                if (proc.baseProcessTracker != null) {
2812                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2813                }
2814                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2815                        + "k from cached");
2816            }
2817        }
2818        return proc;
2819    }
2820
2821    void ensurePackageDexOpt(String packageName) {
2822        IPackageManager pm = AppGlobals.getPackageManager();
2823        try {
2824            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2825                mDidDexOpt = true;
2826            }
2827        } catch (RemoteException e) {
2828        }
2829    }
2830
2831    boolean isNextTransitionForward() {
2832        int transit = mWindowManager.getPendingAppTransition();
2833        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2834                || transit == AppTransition.TRANSIT_TASK_OPEN
2835                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2836    }
2837
2838    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2839            String processName, String abiOverride, int uid, Runnable crashHandler) {
2840        synchronized(this) {
2841            ApplicationInfo info = new ApplicationInfo();
2842            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2843            // For isolated processes, the former contains the parent's uid and the latter the
2844            // actual uid of the isolated process.
2845            // In the special case introduced by this method (which is, starting an isolated
2846            // process directly from the SystemServer without an actual parent app process) the
2847            // closest thing to a parent's uid is SYSTEM_UID.
2848            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2849            // the |isolated| logic in the ProcessRecord constructor.
2850            info.uid = Process.SYSTEM_UID;
2851            info.processName = processName;
2852            info.className = entryPoint;
2853            info.packageName = "android";
2854            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2855                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2856                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2857                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2858                    crashHandler);
2859            return proc != null ? proc.pid : 0;
2860        }
2861    }
2862
2863    final ProcessRecord startProcessLocked(String processName,
2864            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2865            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2866            boolean isolated, boolean keepIfLarge) {
2867        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2868                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2869                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2870                null /* crashHandler */);
2871    }
2872
2873    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2874            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2875            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2876            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2877        ProcessRecord app;
2878        if (!isolated) {
2879            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2880        } else {
2881            // If this is an isolated process, it can't re-use an existing process.
2882            app = null;
2883        }
2884        // We don't have to do anything more if:
2885        // (1) There is an existing application record; and
2886        // (2) The caller doesn't think it is dead, OR there is no thread
2887        //     object attached to it so we know it couldn't have crashed; and
2888        // (3) There is a pid assigned to it, so it is either starting or
2889        //     already running.
2890        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2891                + " app=" + app + " knownToBeDead=" + knownToBeDead
2892                + " thread=" + (app != null ? app.thread : null)
2893                + " pid=" + (app != null ? app.pid : -1));
2894        if (app != null && app.pid > 0) {
2895            if (!knownToBeDead || app.thread == null) {
2896                // We already have the app running, or are waiting for it to
2897                // come up (we have a pid but not yet its thread), so keep it.
2898                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2899                // If this is a new package in the process, add the package to the list
2900                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2901                return app;
2902            }
2903
2904            // An application record is attached to a previous process,
2905            // clean it up now.
2906            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2907            Process.killProcessGroup(app.info.uid, app.pid);
2908            handleAppDiedLocked(app, true, true);
2909        }
2910
2911        String hostingNameStr = hostingName != null
2912                ? hostingName.flattenToShortString() : null;
2913
2914        if (!isolated) {
2915            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2916                // If we are in the background, then check to see if this process
2917                // is bad.  If so, we will just silently fail.
2918                if (mBadProcesses.get(info.processName, info.uid) != null) {
2919                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2920                            + "/" + info.processName);
2921                    return null;
2922                }
2923            } else {
2924                // When the user is explicitly starting a process, then clear its
2925                // crash count so that we won't make it bad until they see at
2926                // least one crash dialog again, and make the process good again
2927                // if it had been bad.
2928                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2929                        + "/" + info.processName);
2930                mProcessCrashTimes.remove(info.processName, info.uid);
2931                if (mBadProcesses.get(info.processName, info.uid) != null) {
2932                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2933                            UserHandle.getUserId(info.uid), info.uid,
2934                            info.processName);
2935                    mBadProcesses.remove(info.processName, info.uid);
2936                    if (app != null) {
2937                        app.bad = false;
2938                    }
2939                }
2940            }
2941        }
2942
2943        if (app == null) {
2944            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2945            app.crashHandler = crashHandler;
2946            if (app == null) {
2947                Slog.w(TAG, "Failed making new process record for "
2948                        + processName + "/" + info.uid + " isolated=" + isolated);
2949                return null;
2950            }
2951            mProcessNames.put(processName, app.uid, app);
2952            if (isolated) {
2953                mIsolatedProcesses.put(app.uid, app);
2954            }
2955        } else {
2956            // If this is a new package in the process, add the package to the list
2957            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2958        }
2959
2960        // If the system is not ready yet, then hold off on starting this
2961        // process until it is.
2962        if (!mProcessesReady
2963                && !isAllowedWhileBooting(info)
2964                && !allowWhileBooting) {
2965            if (!mProcessesOnHold.contains(app)) {
2966                mProcessesOnHold.add(app);
2967            }
2968            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2969            return app;
2970        }
2971
2972        startProcessLocked(
2973                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2974        return (app.pid != 0) ? app : null;
2975    }
2976
2977    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2978        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2979    }
2980
2981    private final void startProcessLocked(ProcessRecord app,
2982            String hostingType, String hostingNameStr) {
2983        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2984                null /* entryPoint */, null /* entryPointArgs */);
2985    }
2986
2987    private final void startProcessLocked(ProcessRecord app, String hostingType,
2988            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2989        if (app.pid > 0 && app.pid != MY_PID) {
2990            synchronized (mPidsSelfLocked) {
2991                mPidsSelfLocked.remove(app.pid);
2992                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2993            }
2994            app.setPid(0);
2995        }
2996
2997        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2998                "startProcessLocked removing on hold: " + app);
2999        mProcessesOnHold.remove(app);
3000
3001        updateCpuStats();
3002
3003        try {
3004            int uid = app.uid;
3005
3006            int[] gids = null;
3007            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3008            if (!app.isolated) {
3009                int[] permGids = null;
3010                try {
3011                    final PackageManager pm = mContext.getPackageManager();
3012                    permGids = pm.getPackageGids(app.info.packageName);
3013
3014                    if (Environment.isExternalStorageEmulated()) {
3015                        if (pm.checkPermission(
3016                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3017                                app.info.packageName) == PERMISSION_GRANTED) {
3018                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3019                        } else {
3020                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3021                        }
3022                    }
3023                } catch (PackageManager.NameNotFoundException e) {
3024                    Slog.w(TAG, "Unable to retrieve gids", e);
3025                }
3026
3027                /*
3028                 * Add shared application and profile GIDs so applications can share some
3029                 * resources like shared libraries and access user-wide resources
3030                 */
3031                if (permGids == null) {
3032                    gids = new int[2];
3033                } else {
3034                    gids = new int[permGids.length + 2];
3035                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3036                }
3037                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3038                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3039            }
3040            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3041                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3042                        && mTopComponent != null
3043                        && app.processName.equals(mTopComponent.getPackageName())) {
3044                    uid = 0;
3045                }
3046                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3047                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3048                    uid = 0;
3049                }
3050            }
3051            int debugFlags = 0;
3052            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3053                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3054                // Also turn on CheckJNI for debuggable apps. It's quite
3055                // awkward to turn on otherwise.
3056                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3057            }
3058            // Run the app in safe mode if its manifest requests so or the
3059            // system is booted in safe mode.
3060            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3061                mSafeMode == true) {
3062                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3063            }
3064            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3065                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3066            }
3067            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3068                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3069            }
3070            if ("1".equals(SystemProperties.get("debug.assert"))) {
3071                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3072            }
3073
3074            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3075            if (requiredAbi == null) {
3076                requiredAbi = Build.SUPPORTED_ABIS[0];
3077            }
3078
3079            // Start the process.  It will either succeed and return a result containing
3080            // the PID of the new process, or else throw a RuntimeException.
3081            boolean isActivityProcess = (entryPoint == null);
3082            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3083            Process.ProcessStartResult startResult = Process.start(entryPoint,
3084                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3085                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, entryPointArgs);
3086
3087            if (app.isolated) {
3088                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3089            }
3090            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3091
3092            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3093                    UserHandle.getUserId(uid), startResult.pid, uid,
3094                    app.processName, hostingType,
3095                    hostingNameStr != null ? hostingNameStr : "");
3096
3097            if (app.persistent) {
3098                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3099            }
3100
3101            StringBuilder buf = mStringBuilder;
3102            buf.setLength(0);
3103            buf.append("Start proc ");
3104            buf.append(app.processName);
3105            if (!isActivityProcess) {
3106                buf.append(" [");
3107                buf.append(entryPoint);
3108                buf.append("]");
3109            }
3110            buf.append(" for ");
3111            buf.append(hostingType);
3112            if (hostingNameStr != null) {
3113                buf.append(" ");
3114                buf.append(hostingNameStr);
3115            }
3116            buf.append(": pid=");
3117            buf.append(startResult.pid);
3118            buf.append(" uid=");
3119            buf.append(uid);
3120            buf.append(" gids={");
3121            if (gids != null) {
3122                for (int gi=0; gi<gids.length; gi++) {
3123                    if (gi != 0) buf.append(", ");
3124                    buf.append(gids[gi]);
3125
3126                }
3127            }
3128            buf.append("}");
3129            if (requiredAbi != null) {
3130                buf.append(" abi=");
3131                buf.append(requiredAbi);
3132            }
3133            Slog.i(TAG, buf.toString());
3134            app.setPid(startResult.pid);
3135            app.usingWrapper = startResult.usingWrapper;
3136            app.removed = false;
3137            app.killedByAm = false;
3138            synchronized (mPidsSelfLocked) {
3139                this.mPidsSelfLocked.put(startResult.pid, app);
3140                if (isActivityProcess) {
3141                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3142                    msg.obj = app;
3143                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3144                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3145                }
3146            }
3147        } catch (RuntimeException e) {
3148            // XXX do better error recovery.
3149            app.setPid(0);
3150            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3151            if (app.isolated) {
3152                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3153            }
3154            Slog.e(TAG, "Failure starting process " + app.processName, e);
3155        }
3156    }
3157
3158    void updateUsageStats(ActivityRecord component, boolean resumed) {
3159        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3160        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3161        if (resumed) {
3162            if (mUsageStatsService != null) {
3163                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3164                        System.currentTimeMillis(),
3165                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3166            }
3167            synchronized (stats) {
3168                stats.noteActivityResumedLocked(component.app.uid);
3169            }
3170        } else {
3171            if (mUsageStatsService != null) {
3172                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3173                        System.currentTimeMillis(),
3174                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3175            }
3176            synchronized (stats) {
3177                stats.noteActivityPausedLocked(component.app.uid);
3178            }
3179        }
3180    }
3181
3182    Intent getHomeIntent() {
3183        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3184        intent.setComponent(mTopComponent);
3185        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3186            intent.addCategory(Intent.CATEGORY_HOME);
3187        }
3188        return intent;
3189    }
3190
3191    boolean startHomeActivityLocked(int userId) {
3192        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3193                && mTopAction == null) {
3194            // We are running in factory test mode, but unable to find
3195            // the factory test app, so just sit around displaying the
3196            // error message and don't try to start anything.
3197            return false;
3198        }
3199        Intent intent = getHomeIntent();
3200        ActivityInfo aInfo =
3201            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3202        if (aInfo != null) {
3203            intent.setComponent(new ComponentName(
3204                    aInfo.applicationInfo.packageName, aInfo.name));
3205            // Don't do this if the home app is currently being
3206            // instrumented.
3207            aInfo = new ActivityInfo(aInfo);
3208            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3209            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3210                    aInfo.applicationInfo.uid, true);
3211            if (app == null || app.instrumentationClass == null) {
3212                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3213                mStackSupervisor.startHomeActivity(intent, aInfo);
3214            }
3215        }
3216
3217        return true;
3218    }
3219
3220    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3221        ActivityInfo ai = null;
3222        ComponentName comp = intent.getComponent();
3223        try {
3224            if (comp != null) {
3225                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3226            } else {
3227                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3228                        intent,
3229                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3230                            flags, userId);
3231
3232                if (info != null) {
3233                    ai = info.activityInfo;
3234                }
3235            }
3236        } catch (RemoteException e) {
3237            // ignore
3238        }
3239
3240        return ai;
3241    }
3242
3243    /**
3244     * Starts the "new version setup screen" if appropriate.
3245     */
3246    void startSetupActivityLocked() {
3247        // Only do this once per boot.
3248        if (mCheckedForSetup) {
3249            return;
3250        }
3251
3252        // We will show this screen if the current one is a different
3253        // version than the last one shown, and we are not running in
3254        // low-level factory test mode.
3255        final ContentResolver resolver = mContext.getContentResolver();
3256        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3257                Settings.Global.getInt(resolver,
3258                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3259            mCheckedForSetup = true;
3260
3261            // See if we should be showing the platform update setup UI.
3262            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3263            List<ResolveInfo> ris = mContext.getPackageManager()
3264                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3265
3266            // We don't allow third party apps to replace this.
3267            ResolveInfo ri = null;
3268            for (int i=0; ris != null && i<ris.size(); i++) {
3269                if ((ris.get(i).activityInfo.applicationInfo.flags
3270                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3271                    ri = ris.get(i);
3272                    break;
3273                }
3274            }
3275
3276            if (ri != null) {
3277                String vers = ri.activityInfo.metaData != null
3278                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3279                        : null;
3280                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3281                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3282                            Intent.METADATA_SETUP_VERSION);
3283                }
3284                String lastVers = Settings.Secure.getString(
3285                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3286                if (vers != null && !vers.equals(lastVers)) {
3287                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3288                    intent.setComponent(new ComponentName(
3289                            ri.activityInfo.packageName, ri.activityInfo.name));
3290                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3291                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3292                }
3293            }
3294        }
3295    }
3296
3297    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3298        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3299    }
3300
3301    void enforceNotIsolatedCaller(String caller) {
3302        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3303            throw new SecurityException("Isolated process not allowed to call " + caller);
3304        }
3305    }
3306
3307    @Override
3308    public int getFrontActivityScreenCompatMode() {
3309        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3310        synchronized (this) {
3311            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3312        }
3313    }
3314
3315    @Override
3316    public void setFrontActivityScreenCompatMode(int mode) {
3317        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3318                "setFrontActivityScreenCompatMode");
3319        synchronized (this) {
3320            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3321        }
3322    }
3323
3324    @Override
3325    public int getPackageScreenCompatMode(String packageName) {
3326        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3327        synchronized (this) {
3328            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3329        }
3330    }
3331
3332    @Override
3333    public void setPackageScreenCompatMode(String packageName, int mode) {
3334        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3335                "setPackageScreenCompatMode");
3336        synchronized (this) {
3337            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3338        }
3339    }
3340
3341    @Override
3342    public boolean getPackageAskScreenCompat(String packageName) {
3343        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3344        synchronized (this) {
3345            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3346        }
3347    }
3348
3349    @Override
3350    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3351        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3352                "setPackageAskScreenCompat");
3353        synchronized (this) {
3354            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3355        }
3356    }
3357
3358    private void dispatchProcessesChanged() {
3359        int N;
3360        synchronized (this) {
3361            N = mPendingProcessChanges.size();
3362            if (mActiveProcessChanges.length < N) {
3363                mActiveProcessChanges = new ProcessChangeItem[N];
3364            }
3365            mPendingProcessChanges.toArray(mActiveProcessChanges);
3366            mAvailProcessChanges.addAll(mPendingProcessChanges);
3367            mPendingProcessChanges.clear();
3368            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3369        }
3370
3371        int i = mProcessObservers.beginBroadcast();
3372        while (i > 0) {
3373            i--;
3374            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3375            if (observer != null) {
3376                try {
3377                    for (int j=0; j<N; j++) {
3378                        ProcessChangeItem item = mActiveProcessChanges[j];
3379                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3380                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3381                                    + item.pid + " uid=" + item.uid + ": "
3382                                    + item.foregroundActivities);
3383                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3384                                    item.foregroundActivities);
3385                        }
3386                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3387                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3388                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3389                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3390                        }
3391                    }
3392                } catch (RemoteException e) {
3393                }
3394            }
3395        }
3396        mProcessObservers.finishBroadcast();
3397    }
3398
3399    private void dispatchProcessDied(int pid, int uid) {
3400        int i = mProcessObservers.beginBroadcast();
3401        while (i > 0) {
3402            i--;
3403            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3404            if (observer != null) {
3405                try {
3406                    observer.onProcessDied(pid, uid);
3407                } catch (RemoteException e) {
3408                }
3409            }
3410        }
3411        mProcessObservers.finishBroadcast();
3412    }
3413
3414    @Override
3415    public final int startActivity(IApplicationThread caller, String callingPackage,
3416            Intent intent, String resolvedType, IBinder resultTo,
3417            String resultWho, int requestCode, int startFlags,
3418            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3419        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3420                resultWho, requestCode,
3421                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3422    }
3423
3424    @Override
3425    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3426            Intent intent, String resolvedType, IBinder resultTo,
3427            String resultWho, int requestCode, int startFlags,
3428            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3429        enforceNotIsolatedCaller("startActivity");
3430        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3431                false, ALLOW_FULL_ONLY, "startActivity", null);
3432        // TODO: Switch to user app stacks here.
3433        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3434                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3435                null, null, options, userId, null);
3436    }
3437
3438    @Override
3439    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3440            Intent intent, String resolvedType, IBinder resultTo,
3441            String resultWho, int requestCode, int startFlags,
3442            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3443
3444        // This is very dangerous -- it allows you to perform a start activity (including
3445        // permission grants) as any app that may launch one of your own activities.  So
3446        // we will only allow this to be done from activities that are part of the core framework,
3447        // and then only when they are running as the system.
3448        final ActivityRecord sourceRecord;
3449        final int targetUid;
3450        final String targetPackage;
3451        synchronized (this) {
3452            if (resultTo == null) {
3453                throw new SecurityException("Must be called from an activity");
3454            }
3455            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3456            if (sourceRecord == null) {
3457                throw new SecurityException("Called with bad activity token: " + resultTo);
3458            }
3459            if (!sourceRecord.info.packageName.equals("android")) {
3460                throw new SecurityException(
3461                        "Must be called from an activity that is declared in the android package");
3462            }
3463            if (sourceRecord.app == null) {
3464                throw new SecurityException("Called without a process attached to activity");
3465            }
3466            if (sourceRecord.app.uid != Process.SYSTEM_UID) {
3467                // This is still okay, as long as this activity is running under the
3468                // uid of the original calling activity.
3469                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3470                    throw new SecurityException(
3471                            "Calling activity in uid " + sourceRecord.app.uid
3472                                    + " must be system uid or original calling uid "
3473                                    + sourceRecord.launchedFromUid);
3474                }
3475            }
3476            targetUid = sourceRecord.launchedFromUid;
3477            targetPackage = sourceRecord.launchedFromPackage;
3478        }
3479
3480        // TODO: Switch to user app stacks here.
3481        try {
3482            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3483                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3484                    null, null, null, null, options, UserHandle.getUserId(targetUid), null);
3485            return ret;
3486        } catch (SecurityException e) {
3487            // XXX need to figure out how to propagate to original app.
3488            // A SecurityException here is generally actually a fault of the original
3489            // calling activity (such as a fairly granting permissions), so propagate it
3490            // back to them.
3491            /*
3492            StringBuilder msg = new StringBuilder();
3493            msg.append("While launching");
3494            msg.append(intent.toString());
3495            msg.append(": ");
3496            msg.append(e.getMessage());
3497            */
3498            throw e;
3499        }
3500    }
3501
3502    @Override
3503    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3504            Intent intent, String resolvedType, IBinder resultTo,
3505            String resultWho, int requestCode, int startFlags, String profileFile,
3506            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3507        enforceNotIsolatedCaller("startActivityAndWait");
3508        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3509                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3510        WaitResult res = new WaitResult();
3511        // TODO: Switch to user app stacks here.
3512        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3513                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3514                res, null, options, userId, null);
3515        return res;
3516    }
3517
3518    @Override
3519    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3520            Intent intent, String resolvedType, IBinder resultTo,
3521            String resultWho, int requestCode, int startFlags, Configuration config,
3522            Bundle options, int userId) {
3523        enforceNotIsolatedCaller("startActivityWithConfig");
3524        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3525                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3526        // TODO: Switch to user app stacks here.
3527        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3528                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3529                null, null, null, config, options, userId, null);
3530        return ret;
3531    }
3532
3533    @Override
3534    public int startActivityIntentSender(IApplicationThread caller,
3535            IntentSender intent, Intent fillInIntent, String resolvedType,
3536            IBinder resultTo, String resultWho, int requestCode,
3537            int flagsMask, int flagsValues, Bundle options) {
3538        enforceNotIsolatedCaller("startActivityIntentSender");
3539        // Refuse possible leaked file descriptors
3540        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3541            throw new IllegalArgumentException("File descriptors passed in Intent");
3542        }
3543
3544        IIntentSender sender = intent.getTarget();
3545        if (!(sender instanceof PendingIntentRecord)) {
3546            throw new IllegalArgumentException("Bad PendingIntent object");
3547        }
3548
3549        PendingIntentRecord pir = (PendingIntentRecord)sender;
3550
3551        synchronized (this) {
3552            // If this is coming from the currently resumed activity, it is
3553            // effectively saying that app switches are allowed at this point.
3554            final ActivityStack stack = getFocusedStack();
3555            if (stack.mResumedActivity != null &&
3556                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3557                mAppSwitchesAllowedTime = 0;
3558            }
3559        }
3560        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3561                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3562        return ret;
3563    }
3564
3565    @Override
3566    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3567            Intent intent, String resolvedType, IVoiceInteractionSession session,
3568            IVoiceInteractor interactor, int startFlags, String profileFile,
3569            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3570        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3571                != PackageManager.PERMISSION_GRANTED) {
3572            String msg = "Permission Denial: startVoiceActivity() from pid="
3573                    + Binder.getCallingPid()
3574                    + ", uid=" + Binder.getCallingUid()
3575                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3576            Slog.w(TAG, msg);
3577            throw new SecurityException(msg);
3578        }
3579        if (session == null || interactor == null) {
3580            throw new NullPointerException("null session or interactor");
3581        }
3582        userId = handleIncomingUser(callingPid, callingUid, userId,
3583                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3584        // TODO: Switch to user app stacks here.
3585        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3586                resolvedType, session, interactor, null, null, 0, startFlags,
3587                profileFile, profileFd, null, null, options, userId, null);
3588    }
3589
3590    @Override
3591    public boolean startNextMatchingActivity(IBinder callingActivity,
3592            Intent intent, Bundle options) {
3593        // Refuse possible leaked file descriptors
3594        if (intent != null && intent.hasFileDescriptors() == true) {
3595            throw new IllegalArgumentException("File descriptors passed in Intent");
3596        }
3597
3598        synchronized (this) {
3599            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3600            if (r == null) {
3601                ActivityOptions.abort(options);
3602                return false;
3603            }
3604            if (r.app == null || r.app.thread == null) {
3605                // The caller is not running...  d'oh!
3606                ActivityOptions.abort(options);
3607                return false;
3608            }
3609            intent = new Intent(intent);
3610            // The caller is not allowed to change the data.
3611            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3612            // And we are resetting to find the next component...
3613            intent.setComponent(null);
3614
3615            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3616
3617            ActivityInfo aInfo = null;
3618            try {
3619                List<ResolveInfo> resolves =
3620                    AppGlobals.getPackageManager().queryIntentActivities(
3621                            intent, r.resolvedType,
3622                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3623                            UserHandle.getCallingUserId());
3624
3625                // Look for the original activity in the list...
3626                final int N = resolves != null ? resolves.size() : 0;
3627                for (int i=0; i<N; i++) {
3628                    ResolveInfo rInfo = resolves.get(i);
3629                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3630                            && rInfo.activityInfo.name.equals(r.info.name)) {
3631                        // We found the current one...  the next matching is
3632                        // after it.
3633                        i++;
3634                        if (i<N) {
3635                            aInfo = resolves.get(i).activityInfo;
3636                        }
3637                        if (debug) {
3638                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3639                                    + "/" + r.info.name);
3640                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3641                                    + "/" + aInfo.name);
3642                        }
3643                        break;
3644                    }
3645                }
3646            } catch (RemoteException e) {
3647            }
3648
3649            if (aInfo == null) {
3650                // Nobody who is next!
3651                ActivityOptions.abort(options);
3652                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3653                return false;
3654            }
3655
3656            intent.setComponent(new ComponentName(
3657                    aInfo.applicationInfo.packageName, aInfo.name));
3658            intent.setFlags(intent.getFlags()&~(
3659                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3660                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3661                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3662                    Intent.FLAG_ACTIVITY_NEW_TASK));
3663
3664            // Okay now we need to start the new activity, replacing the
3665            // currently running activity.  This is a little tricky because
3666            // we want to start the new one as if the current one is finished,
3667            // but not finish the current one first so that there is no flicker.
3668            // And thus...
3669            final boolean wasFinishing = r.finishing;
3670            r.finishing = true;
3671
3672            // Propagate reply information over to the new activity.
3673            final ActivityRecord resultTo = r.resultTo;
3674            final String resultWho = r.resultWho;
3675            final int requestCode = r.requestCode;
3676            r.resultTo = null;
3677            if (resultTo != null) {
3678                resultTo.removeResultsLocked(r, resultWho, requestCode);
3679            }
3680
3681            final long origId = Binder.clearCallingIdentity();
3682            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3683                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3684                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3685                    options, false, null, null);
3686            Binder.restoreCallingIdentity(origId);
3687
3688            r.finishing = wasFinishing;
3689            if (res != ActivityManager.START_SUCCESS) {
3690                return false;
3691            }
3692            return true;
3693        }
3694    }
3695
3696    @Override
3697    public final int startActivityFromRecents(int taskId, Bundle options) {
3698        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3699            String msg = "Permission Denial: startActivityFromRecents called without " +
3700                    START_TASKS_FROM_RECENTS;
3701            Slog.w(TAG, msg);
3702            throw new SecurityException(msg);
3703        }
3704        final int callingUid;
3705        final String callingPackage;
3706        final Intent intent;
3707        final int userId;
3708        synchronized (this) {
3709            final TaskRecord task = recentTaskForIdLocked(taskId);
3710            if (task == null) {
3711                throw new ActivityNotFoundException("Task " + taskId + " not found.");
3712            }
3713            callingUid = task.mCallingUid;
3714            callingPackage = task.mCallingPackage;
3715            intent = task.intent;
3716            userId = task.userId;
3717        }
3718        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3719                options, userId, null);
3720    }
3721
3722    final int startActivityInPackage(int uid, String callingPackage,
3723            Intent intent, String resolvedType, IBinder resultTo,
3724            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3725                    IActivityContainer container) {
3726
3727        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3728                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3729
3730        // TODO: Switch to user app stacks here.
3731        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3732                null, null, resultTo, resultWho, requestCode, startFlags,
3733                null, null, null, null, options, userId, container);
3734        return ret;
3735    }
3736
3737    @Override
3738    public final int startActivities(IApplicationThread caller, String callingPackage,
3739            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3740            int userId) {
3741        enforceNotIsolatedCaller("startActivities");
3742        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3743                false, ALLOW_FULL_ONLY, "startActivity", null);
3744        // TODO: Switch to user app stacks here.
3745        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3746                resolvedTypes, resultTo, options, userId);
3747        return ret;
3748    }
3749
3750    final int startActivitiesInPackage(int uid, String callingPackage,
3751            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3752            Bundle options, int userId) {
3753
3754        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3755                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3756        // TODO: Switch to user app stacks here.
3757        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3758                resultTo, options, userId);
3759        return ret;
3760    }
3761
3762    //explicitly remove thd old information in mRecentTasks when removing existing user.
3763    private void removeRecentTasksForUserLocked(int userId) {
3764        if(userId <= 0) {
3765            Slog.i(TAG, "Can't remove recent task on user " + userId);
3766            return;
3767        }
3768
3769        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3770            TaskRecord tr = mRecentTasks.get(i);
3771            if (tr.userId == userId) {
3772                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3773                        + " when finishing user" + userId);
3774                tr.disposeThumbnail();
3775                mRecentTasks.remove(i);
3776            }
3777        }
3778
3779        // Remove tasks from persistent storage.
3780        mTaskPersister.wakeup(null, true);
3781    }
3782
3783    final void addRecentTaskLocked(TaskRecord task) {
3784        int N = mRecentTasks.size();
3785        // Quick case: check if the top-most recent task is the same.
3786        if (N > 0 && mRecentTasks.get(0) == task) {
3787            return;
3788        }
3789        // Another quick case: never add voice sessions.
3790        if (task.voiceSession != null) {
3791            return;
3792        }
3793        // Remove any existing entries that are the same kind of task.
3794        final Intent intent = task.intent;
3795        final boolean document = intent != null && intent.isDocument();
3796        final ComponentName comp = intent.getComponent();
3797
3798        int maxRecents = task.maxRecents - 1;
3799        for (int i=0; i<N; i++) {
3800            final TaskRecord tr = mRecentTasks.get(i);
3801            if (task != tr) {
3802                if (task.userId != tr.userId) {
3803                    continue;
3804                }
3805                if (i > MAX_RECENT_BITMAPS) {
3806                    tr.freeLastThumbnail();
3807                }
3808                final Intent trIntent = tr.intent;
3809                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3810                    (intent == null || !intent.filterEquals(trIntent))) {
3811                    continue;
3812                }
3813                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3814                if (document && trIsDocument) {
3815                    // These are the same document activity (not necessarily the same doc).
3816                    if (maxRecents > 0) {
3817                        --maxRecents;
3818                        continue;
3819                    }
3820                    // Hit the maximum number of documents for this task. Fall through
3821                    // and remove this document from recents.
3822                } else if (document || trIsDocument) {
3823                    // Only one of these is a document. Not the droid we're looking for.
3824                    continue;
3825                }
3826            }
3827
3828            // Either task and tr are the same or, their affinities match or their intents match
3829            // and neither of them is a document, or they are documents using the same activity
3830            // and their maxRecents has been reached.
3831            tr.disposeThumbnail();
3832            mRecentTasks.remove(i);
3833            if (task != tr) {
3834                tr.closeRecentsChain();
3835            }
3836            i--;
3837            N--;
3838            if (task.intent == null) {
3839                // If the new recent task we are adding is not fully
3840                // specified, then replace it with the existing recent task.
3841                task = tr;
3842            }
3843            notifyTaskPersisterLocked(tr, false);
3844        }
3845        if (N >= MAX_RECENT_TASKS) {
3846            final TaskRecord tr = mRecentTasks.remove(N - 1);
3847            tr.disposeThumbnail();
3848            tr.closeRecentsChain();
3849        }
3850        mRecentTasks.add(0, task);
3851    }
3852
3853    @Override
3854    public void reportActivityFullyDrawn(IBinder token) {
3855        synchronized (this) {
3856            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3857            if (r == null) {
3858                return;
3859            }
3860            r.reportFullyDrawnLocked();
3861        }
3862    }
3863
3864    @Override
3865    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3866        synchronized (this) {
3867            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3868            if (r == null) {
3869                return;
3870            }
3871            final long origId = Binder.clearCallingIdentity();
3872            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3873            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3874                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3875            if (config != null) {
3876                r.frozenBeforeDestroy = true;
3877                if (!updateConfigurationLocked(config, r, false, false)) {
3878                    mStackSupervisor.resumeTopActivitiesLocked();
3879                }
3880            }
3881            Binder.restoreCallingIdentity(origId);
3882        }
3883    }
3884
3885    @Override
3886    public int getRequestedOrientation(IBinder token) {
3887        synchronized (this) {
3888            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3889            if (r == null) {
3890                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3891            }
3892            return mWindowManager.getAppOrientation(r.appToken);
3893        }
3894    }
3895
3896    /**
3897     * This is the internal entry point for handling Activity.finish().
3898     *
3899     * @param token The Binder token referencing the Activity we want to finish.
3900     * @param resultCode Result code, if any, from this Activity.
3901     * @param resultData Result data (Intent), if any, from this Activity.
3902     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3903     *            the root Activity in the task.
3904     *
3905     * @return Returns true if the activity successfully finished, or false if it is still running.
3906     */
3907    @Override
3908    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3909            boolean finishTask) {
3910        // Refuse possible leaked file descriptors
3911        if (resultData != null && resultData.hasFileDescriptors() == true) {
3912            throw new IllegalArgumentException("File descriptors passed in Intent");
3913        }
3914
3915        synchronized(this) {
3916            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3917            if (r == null) {
3918                return true;
3919            }
3920            // Keep track of the root activity of the task before we finish it
3921            TaskRecord tr = r.task;
3922            ActivityRecord rootR = tr.getRootActivity();
3923            // Do not allow task to finish in Lock Task mode.
3924            if (tr == mStackSupervisor.mLockTaskModeTask) {
3925                if (rootR == r) {
3926                    mStackSupervisor.showLockTaskToast();
3927                    return false;
3928                }
3929            }
3930            if (mController != null) {
3931                // Find the first activity that is not finishing.
3932                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3933                if (next != null) {
3934                    // ask watcher if this is allowed
3935                    boolean resumeOK = true;
3936                    try {
3937                        resumeOK = mController.activityResuming(next.packageName);
3938                    } catch (RemoteException e) {
3939                        mController = null;
3940                        Watchdog.getInstance().setActivityController(null);
3941                    }
3942
3943                    if (!resumeOK) {
3944                        return false;
3945                    }
3946                }
3947            }
3948            final long origId = Binder.clearCallingIdentity();
3949            try {
3950                boolean res;
3951                if (finishTask && r == rootR) {
3952                    // If requested, remove the task that is associated to this activity only if it
3953                    // was the root activity in the task.  The result code and data is ignored because
3954                    // we don't support returning them across task boundaries.
3955                    res = removeTaskByIdLocked(tr.taskId, 0);
3956                } else {
3957                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3958                            resultData, "app-request", true);
3959                }
3960                return res;
3961            } finally {
3962                Binder.restoreCallingIdentity(origId);
3963            }
3964        }
3965    }
3966
3967    @Override
3968    public final void finishHeavyWeightApp() {
3969        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3970                != PackageManager.PERMISSION_GRANTED) {
3971            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3972                    + Binder.getCallingPid()
3973                    + ", uid=" + Binder.getCallingUid()
3974                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3975            Slog.w(TAG, msg);
3976            throw new SecurityException(msg);
3977        }
3978
3979        synchronized(this) {
3980            if (mHeavyWeightProcess == null) {
3981                return;
3982            }
3983
3984            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3985                    mHeavyWeightProcess.activities);
3986            for (int i=0; i<activities.size(); i++) {
3987                ActivityRecord r = activities.get(i);
3988                if (!r.finishing) {
3989                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3990                            null, "finish-heavy", true);
3991                }
3992            }
3993
3994            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3995                    mHeavyWeightProcess.userId, 0));
3996            mHeavyWeightProcess = null;
3997        }
3998    }
3999
4000    @Override
4001    public void crashApplication(int uid, int initialPid, String packageName,
4002            String message) {
4003        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4004                != PackageManager.PERMISSION_GRANTED) {
4005            String msg = "Permission Denial: crashApplication() from pid="
4006                    + Binder.getCallingPid()
4007                    + ", uid=" + Binder.getCallingUid()
4008                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4009            Slog.w(TAG, msg);
4010            throw new SecurityException(msg);
4011        }
4012
4013        synchronized(this) {
4014            ProcessRecord proc = null;
4015
4016            // Figure out which process to kill.  We don't trust that initialPid
4017            // still has any relation to current pids, so must scan through the
4018            // list.
4019            synchronized (mPidsSelfLocked) {
4020                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4021                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4022                    if (p.uid != uid) {
4023                        continue;
4024                    }
4025                    if (p.pid == initialPid) {
4026                        proc = p;
4027                        break;
4028                    }
4029                    if (p.pkgList.containsKey(packageName)) {
4030                        proc = p;
4031                    }
4032                }
4033            }
4034
4035            if (proc == null) {
4036                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4037                        + " initialPid=" + initialPid
4038                        + " packageName=" + packageName);
4039                return;
4040            }
4041
4042            if (proc.thread != null) {
4043                if (proc.pid == Process.myPid()) {
4044                    Log.w(TAG, "crashApplication: trying to crash self!");
4045                    return;
4046                }
4047                long ident = Binder.clearCallingIdentity();
4048                try {
4049                    proc.thread.scheduleCrash(message);
4050                } catch (RemoteException e) {
4051                }
4052                Binder.restoreCallingIdentity(ident);
4053            }
4054        }
4055    }
4056
4057    @Override
4058    public final void finishSubActivity(IBinder token, String resultWho,
4059            int requestCode) {
4060        synchronized(this) {
4061            final long origId = Binder.clearCallingIdentity();
4062            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4063            if (r != null) {
4064                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4065            }
4066            Binder.restoreCallingIdentity(origId);
4067        }
4068    }
4069
4070    @Override
4071    public boolean finishActivityAffinity(IBinder token) {
4072        synchronized(this) {
4073            final long origId = Binder.clearCallingIdentity();
4074            try {
4075                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4076
4077                ActivityRecord rootR = r.task.getRootActivity();
4078                // Do not allow task to finish in Lock Task mode.
4079                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4080                    if (rootR == r) {
4081                        mStackSupervisor.showLockTaskToast();
4082                        return false;
4083                    }
4084                }
4085                boolean res = false;
4086                if (r != null) {
4087                    res = r.task.stack.finishActivityAffinityLocked(r);
4088                }
4089                return res;
4090            } finally {
4091                Binder.restoreCallingIdentity(origId);
4092            }
4093        }
4094    }
4095
4096    @Override
4097    public void finishVoiceTask(IVoiceInteractionSession session) {
4098        synchronized(this) {
4099            final long origId = Binder.clearCallingIdentity();
4100            try {
4101                mStackSupervisor.finishVoiceTask(session);
4102            } finally {
4103                Binder.restoreCallingIdentity(origId);
4104            }
4105        }
4106
4107    }
4108
4109    @Override
4110    public boolean willActivityBeVisible(IBinder token) {
4111        synchronized(this) {
4112            ActivityStack stack = ActivityRecord.getStackLocked(token);
4113            if (stack != null) {
4114                return stack.willActivityBeVisibleLocked(token);
4115            }
4116            return false;
4117        }
4118    }
4119
4120    @Override
4121    public void overridePendingTransition(IBinder token, String packageName,
4122            int enterAnim, int exitAnim) {
4123        synchronized(this) {
4124            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4125            if (self == null) {
4126                return;
4127            }
4128
4129            final long origId = Binder.clearCallingIdentity();
4130
4131            if (self.state == ActivityState.RESUMED
4132                    || self.state == ActivityState.PAUSING) {
4133                mWindowManager.overridePendingAppTransition(packageName,
4134                        enterAnim, exitAnim, null);
4135            }
4136
4137            Binder.restoreCallingIdentity(origId);
4138        }
4139    }
4140
4141    /**
4142     * Main function for removing an existing process from the activity manager
4143     * as a result of that process going away.  Clears out all connections
4144     * to the process.
4145     */
4146    private final void handleAppDiedLocked(ProcessRecord app,
4147            boolean restarting, boolean allowRestart) {
4148        int pid = app.pid;
4149        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4150        if (!restarting) {
4151            removeLruProcessLocked(app);
4152            if (pid > 0) {
4153                ProcessList.remove(pid);
4154            }
4155        }
4156
4157        if (mProfileProc == app) {
4158            clearProfilerLocked();
4159        }
4160
4161        // Remove this application's activities from active lists.
4162        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4163
4164        app.activities.clear();
4165
4166        if (app.instrumentationClass != null) {
4167            Slog.w(TAG, "Crash of app " + app.processName
4168                  + " running instrumentation " + app.instrumentationClass);
4169            Bundle info = new Bundle();
4170            info.putString("shortMsg", "Process crashed.");
4171            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4172        }
4173
4174        if (!restarting) {
4175            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4176                // If there was nothing to resume, and we are not already
4177                // restarting this process, but there is a visible activity that
4178                // is hosted by the process...  then make sure all visible
4179                // activities are running, taking care of restarting this
4180                // process.
4181                if (hasVisibleActivities) {
4182                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4183                }
4184            }
4185        }
4186    }
4187
4188    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4189        IBinder threadBinder = thread.asBinder();
4190        // Find the application record.
4191        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4192            ProcessRecord rec = mLruProcesses.get(i);
4193            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4194                return i;
4195            }
4196        }
4197        return -1;
4198    }
4199
4200    final ProcessRecord getRecordForAppLocked(
4201            IApplicationThread thread) {
4202        if (thread == null) {
4203            return null;
4204        }
4205
4206        int appIndex = getLRURecordIndexForAppLocked(thread);
4207        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4208    }
4209
4210    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4211        // If there are no longer any background processes running,
4212        // and the app that died was not running instrumentation,
4213        // then tell everyone we are now low on memory.
4214        boolean haveBg = false;
4215        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4216            ProcessRecord rec = mLruProcesses.get(i);
4217            if (rec.thread != null
4218                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4219                haveBg = true;
4220                break;
4221            }
4222        }
4223
4224        if (!haveBg) {
4225            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4226            if (doReport) {
4227                long now = SystemClock.uptimeMillis();
4228                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4229                    doReport = false;
4230                } else {
4231                    mLastMemUsageReportTime = now;
4232                }
4233            }
4234            final ArrayList<ProcessMemInfo> memInfos
4235                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4236            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4237            long now = SystemClock.uptimeMillis();
4238            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4239                ProcessRecord rec = mLruProcesses.get(i);
4240                if (rec == dyingProc || rec.thread == null) {
4241                    continue;
4242                }
4243                if (doReport) {
4244                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4245                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4246                }
4247                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4248                    // The low memory report is overriding any current
4249                    // state for a GC request.  Make sure to do
4250                    // heavy/important/visible/foreground processes first.
4251                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4252                        rec.lastRequestedGc = 0;
4253                    } else {
4254                        rec.lastRequestedGc = rec.lastLowMemory;
4255                    }
4256                    rec.reportLowMemory = true;
4257                    rec.lastLowMemory = now;
4258                    mProcessesToGc.remove(rec);
4259                    addProcessToGcListLocked(rec);
4260                }
4261            }
4262            if (doReport) {
4263                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4264                mHandler.sendMessage(msg);
4265            }
4266            scheduleAppGcsLocked();
4267        }
4268    }
4269
4270    final void appDiedLocked(ProcessRecord app) {
4271       appDiedLocked(app, app.pid, app.thread);
4272    }
4273
4274    final void appDiedLocked(ProcessRecord app, int pid,
4275            IApplicationThread thread) {
4276
4277        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4278        synchronized (stats) {
4279            stats.noteProcessDiedLocked(app.info.uid, pid);
4280        }
4281
4282        Process.killProcessGroup(app.info.uid, pid);
4283
4284        // Clean up already done if the process has been re-started.
4285        if (app.pid == pid && app.thread != null &&
4286                app.thread.asBinder() == thread.asBinder()) {
4287            boolean doLowMem = app.instrumentationClass == null;
4288            boolean doOomAdj = doLowMem;
4289            if (!app.killedByAm) {
4290                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4291                        + ") has died.");
4292                mAllowLowerMemLevel = true;
4293            } else {
4294                // Note that we always want to do oom adj to update our state with the
4295                // new number of procs.
4296                mAllowLowerMemLevel = false;
4297                doLowMem = false;
4298            }
4299            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4300            if (DEBUG_CLEANUP) Slog.v(
4301                TAG, "Dying app: " + app + ", pid: " + pid
4302                + ", thread: " + thread.asBinder());
4303            handleAppDiedLocked(app, false, true);
4304
4305            if (doOomAdj) {
4306                updateOomAdjLocked();
4307            }
4308            if (doLowMem) {
4309                doLowMemReportIfNeededLocked(app);
4310            }
4311        } else if (app.pid != pid) {
4312            // A new process has already been started.
4313            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4314                    + ") has died and restarted (pid " + app.pid + ").");
4315            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4316        } else if (DEBUG_PROCESSES) {
4317            Slog.d(TAG, "Received spurious death notification for thread "
4318                    + thread.asBinder());
4319        }
4320    }
4321
4322    /**
4323     * If a stack trace dump file is configured, dump process stack traces.
4324     * @param clearTraces causes the dump file to be erased prior to the new
4325     *    traces being written, if true; when false, the new traces will be
4326     *    appended to any existing file content.
4327     * @param firstPids of dalvik VM processes to dump stack traces for first
4328     * @param lastPids of dalvik VM processes to dump stack traces for last
4329     * @param nativeProcs optional list of native process names to dump stack crawls
4330     * @return file containing stack traces, or null if no dump file is configured
4331     */
4332    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4333            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4334        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4335        if (tracesPath == null || tracesPath.length() == 0) {
4336            return null;
4337        }
4338
4339        File tracesFile = new File(tracesPath);
4340        try {
4341            File tracesDir = tracesFile.getParentFile();
4342            if (!tracesDir.exists()) {
4343                tracesFile.mkdirs();
4344                if (!SELinux.restorecon(tracesDir)) {
4345                    return null;
4346                }
4347            }
4348            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4349
4350            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4351            tracesFile.createNewFile();
4352            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4353        } catch (IOException e) {
4354            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4355            return null;
4356        }
4357
4358        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4359        return tracesFile;
4360    }
4361
4362    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4363            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4364        // Use a FileObserver to detect when traces finish writing.
4365        // The order of traces is considered important to maintain for legibility.
4366        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4367            @Override
4368            public synchronized void onEvent(int event, String path) { notify(); }
4369        };
4370
4371        try {
4372            observer.startWatching();
4373
4374            // First collect all of the stacks of the most important pids.
4375            if (firstPids != null) {
4376                try {
4377                    int num = firstPids.size();
4378                    for (int i = 0; i < num; i++) {
4379                        synchronized (observer) {
4380                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4381                            observer.wait(200);  // Wait for write-close, give up after 200msec
4382                        }
4383                    }
4384                } catch (InterruptedException e) {
4385                    Log.wtf(TAG, e);
4386                }
4387            }
4388
4389            // Next collect the stacks of the native pids
4390            if (nativeProcs != null) {
4391                int[] pids = Process.getPidsForCommands(nativeProcs);
4392                if (pids != null) {
4393                    for (int pid : pids) {
4394                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4395                    }
4396                }
4397            }
4398
4399            // Lastly, measure CPU usage.
4400            if (processCpuTracker != null) {
4401                processCpuTracker.init();
4402                System.gc();
4403                processCpuTracker.update();
4404                try {
4405                    synchronized (processCpuTracker) {
4406                        processCpuTracker.wait(500); // measure over 1/2 second.
4407                    }
4408                } catch (InterruptedException e) {
4409                }
4410                processCpuTracker.update();
4411
4412                // We'll take the stack crawls of just the top apps using CPU.
4413                final int N = processCpuTracker.countWorkingStats();
4414                int numProcs = 0;
4415                for (int i=0; i<N && numProcs<5; i++) {
4416                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4417                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4418                        numProcs++;
4419                        try {
4420                            synchronized (observer) {
4421                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4422                                observer.wait(200);  // Wait for write-close, give up after 200msec
4423                            }
4424                        } catch (InterruptedException e) {
4425                            Log.wtf(TAG, e);
4426                        }
4427
4428                    }
4429                }
4430            }
4431        } finally {
4432            observer.stopWatching();
4433        }
4434    }
4435
4436    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4437        if (true || IS_USER_BUILD) {
4438            return;
4439        }
4440        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4441        if (tracesPath == null || tracesPath.length() == 0) {
4442            return;
4443        }
4444
4445        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4446        StrictMode.allowThreadDiskWrites();
4447        try {
4448            final File tracesFile = new File(tracesPath);
4449            final File tracesDir = tracesFile.getParentFile();
4450            final File tracesTmp = new File(tracesDir, "__tmp__");
4451            try {
4452                if (!tracesDir.exists()) {
4453                    tracesFile.mkdirs();
4454                    if (!SELinux.restorecon(tracesDir.getPath())) {
4455                        return;
4456                    }
4457                }
4458                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4459
4460                if (tracesFile.exists()) {
4461                    tracesTmp.delete();
4462                    tracesFile.renameTo(tracesTmp);
4463                }
4464                StringBuilder sb = new StringBuilder();
4465                Time tobj = new Time();
4466                tobj.set(System.currentTimeMillis());
4467                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4468                sb.append(": ");
4469                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4470                sb.append(" since ");
4471                sb.append(msg);
4472                FileOutputStream fos = new FileOutputStream(tracesFile);
4473                fos.write(sb.toString().getBytes());
4474                if (app == null) {
4475                    fos.write("\n*** No application process!".getBytes());
4476                }
4477                fos.close();
4478                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4479            } catch (IOException e) {
4480                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4481                return;
4482            }
4483
4484            if (app != null) {
4485                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4486                firstPids.add(app.pid);
4487                dumpStackTraces(tracesPath, firstPids, null, null, null);
4488            }
4489
4490            File lastTracesFile = null;
4491            File curTracesFile = null;
4492            for (int i=9; i>=0; i--) {
4493                String name = String.format(Locale.US, "slow%02d.txt", i);
4494                curTracesFile = new File(tracesDir, name);
4495                if (curTracesFile.exists()) {
4496                    if (lastTracesFile != null) {
4497                        curTracesFile.renameTo(lastTracesFile);
4498                    } else {
4499                        curTracesFile.delete();
4500                    }
4501                }
4502                lastTracesFile = curTracesFile;
4503            }
4504            tracesFile.renameTo(curTracesFile);
4505            if (tracesTmp.exists()) {
4506                tracesTmp.renameTo(tracesFile);
4507            }
4508        } finally {
4509            StrictMode.setThreadPolicy(oldPolicy);
4510        }
4511    }
4512
4513    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4514            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4515        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4516        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4517
4518        if (mController != null) {
4519            try {
4520                // 0 == continue, -1 = kill process immediately
4521                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4522                if (res < 0 && app.pid != MY_PID) {
4523                    Process.killProcess(app.pid);
4524                    Process.killProcessGroup(app.info.uid, app.pid);
4525                }
4526            } catch (RemoteException e) {
4527                mController = null;
4528                Watchdog.getInstance().setActivityController(null);
4529            }
4530        }
4531
4532        long anrTime = SystemClock.uptimeMillis();
4533        if (MONITOR_CPU_USAGE) {
4534            updateCpuStatsNow();
4535        }
4536
4537        synchronized (this) {
4538            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4539            if (mShuttingDown) {
4540                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4541                return;
4542            } else if (app.notResponding) {
4543                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4544                return;
4545            } else if (app.crashing) {
4546                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4547                return;
4548            }
4549
4550            // In case we come through here for the same app before completing
4551            // this one, mark as anring now so we will bail out.
4552            app.notResponding = true;
4553
4554            // Log the ANR to the event log.
4555            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4556                    app.processName, app.info.flags, annotation);
4557
4558            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4559            firstPids.add(app.pid);
4560
4561            int parentPid = app.pid;
4562            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4563            if (parentPid != app.pid) firstPids.add(parentPid);
4564
4565            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4566
4567            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4568                ProcessRecord r = mLruProcesses.get(i);
4569                if (r != null && r.thread != null) {
4570                    int pid = r.pid;
4571                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4572                        if (r.persistent) {
4573                            firstPids.add(pid);
4574                        } else {
4575                            lastPids.put(pid, Boolean.TRUE);
4576                        }
4577                    }
4578                }
4579            }
4580        }
4581
4582        // Log the ANR to the main log.
4583        StringBuilder info = new StringBuilder();
4584        info.setLength(0);
4585        info.append("ANR in ").append(app.processName);
4586        if (activity != null && activity.shortComponentName != null) {
4587            info.append(" (").append(activity.shortComponentName).append(")");
4588        }
4589        info.append("\n");
4590        info.append("PID: ").append(app.pid).append("\n");
4591        if (annotation != null) {
4592            info.append("Reason: ").append(annotation).append("\n");
4593        }
4594        if (parent != null && parent != activity) {
4595            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4596        }
4597
4598        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4599
4600        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4601                NATIVE_STACKS_OF_INTEREST);
4602
4603        String cpuInfo = null;
4604        if (MONITOR_CPU_USAGE) {
4605            updateCpuStatsNow();
4606            synchronized (mProcessCpuThread) {
4607                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4608            }
4609            info.append(processCpuTracker.printCurrentLoad());
4610            info.append(cpuInfo);
4611        }
4612
4613        info.append(processCpuTracker.printCurrentState(anrTime));
4614
4615        Slog.e(TAG, info.toString());
4616        if (tracesFile == null) {
4617            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4618            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4619        }
4620
4621        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4622                cpuInfo, tracesFile, null);
4623
4624        if (mController != null) {
4625            try {
4626                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4627                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4628                if (res != 0) {
4629                    if (res < 0 && app.pid != MY_PID) {
4630                        Process.killProcess(app.pid);
4631                        Process.killProcessGroup(app.info.uid, app.pid);
4632                    } else {
4633                        synchronized (this) {
4634                            mServices.scheduleServiceTimeoutLocked(app);
4635                        }
4636                    }
4637                    return;
4638                }
4639            } catch (RemoteException e) {
4640                mController = null;
4641                Watchdog.getInstance().setActivityController(null);
4642            }
4643        }
4644
4645        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4646        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4647                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4648
4649        synchronized (this) {
4650            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4651                killUnneededProcessLocked(app, "background ANR");
4652                return;
4653            }
4654
4655            // Set the app's notResponding state, and look up the errorReportReceiver
4656            makeAppNotRespondingLocked(app,
4657                    activity != null ? activity.shortComponentName : null,
4658                    annotation != null ? "ANR " + annotation : "ANR",
4659                    info.toString());
4660
4661            // Bring up the infamous App Not Responding dialog
4662            Message msg = Message.obtain();
4663            HashMap<String, Object> map = new HashMap<String, Object>();
4664            msg.what = SHOW_NOT_RESPONDING_MSG;
4665            msg.obj = map;
4666            msg.arg1 = aboveSystem ? 1 : 0;
4667            map.put("app", app);
4668            if (activity != null) {
4669                map.put("activity", activity);
4670            }
4671
4672            mHandler.sendMessage(msg);
4673        }
4674    }
4675
4676    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4677        if (!mLaunchWarningShown) {
4678            mLaunchWarningShown = true;
4679            mHandler.post(new Runnable() {
4680                @Override
4681                public void run() {
4682                    synchronized (ActivityManagerService.this) {
4683                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4684                        d.show();
4685                        mHandler.postDelayed(new Runnable() {
4686                            @Override
4687                            public void run() {
4688                                synchronized (ActivityManagerService.this) {
4689                                    d.dismiss();
4690                                    mLaunchWarningShown = false;
4691                                }
4692                            }
4693                        }, 4000);
4694                    }
4695                }
4696            });
4697        }
4698    }
4699
4700    @Override
4701    public boolean clearApplicationUserData(final String packageName,
4702            final IPackageDataObserver observer, int userId) {
4703        enforceNotIsolatedCaller("clearApplicationUserData");
4704        int uid = Binder.getCallingUid();
4705        int pid = Binder.getCallingPid();
4706        userId = handleIncomingUser(pid, uid,
4707                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4708        long callingId = Binder.clearCallingIdentity();
4709        try {
4710            IPackageManager pm = AppGlobals.getPackageManager();
4711            int pkgUid = -1;
4712            synchronized(this) {
4713                try {
4714                    pkgUid = pm.getPackageUid(packageName, userId);
4715                } catch (RemoteException e) {
4716                }
4717                if (pkgUid == -1) {
4718                    Slog.w(TAG, "Invalid packageName: " + packageName);
4719                    if (observer != null) {
4720                        try {
4721                            observer.onRemoveCompleted(packageName, false);
4722                        } catch (RemoteException e) {
4723                            Slog.i(TAG, "Observer no longer exists.");
4724                        }
4725                    }
4726                    return false;
4727                }
4728                if (uid == pkgUid || checkComponentPermission(
4729                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4730                        pid, uid, -1, true)
4731                        == PackageManager.PERMISSION_GRANTED) {
4732                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4733                } else {
4734                    throw new SecurityException("PID " + pid + " does not have permission "
4735                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4736                                    + " of package " + packageName);
4737                }
4738
4739                // Remove all tasks match the cleared application package and user
4740                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
4741                    final TaskRecord tr = mRecentTasks.get(i);
4742                    final String taskPackageName =
4743                            tr.getBaseIntent().getComponent().getPackageName();
4744                    if (tr.userId != userId) continue;
4745                    if (!taskPackageName.equals(packageName)) continue;
4746                    removeTaskByIdLocked(tr.taskId, 0);
4747                }
4748            }
4749
4750            try {
4751                // Clear application user data
4752                pm.clearApplicationUserData(packageName, observer, userId);
4753
4754                synchronized(this) {
4755                    // Remove all permissions granted from/to this package
4756                    removeUriPermissionsForPackageLocked(packageName, userId, true);
4757                }
4758
4759                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4760                        Uri.fromParts("package", packageName, null));
4761                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4762                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4763                        null, null, 0, null, null, null, false, false, userId);
4764            } catch (RemoteException e) {
4765            }
4766        } finally {
4767            Binder.restoreCallingIdentity(callingId);
4768        }
4769        return true;
4770    }
4771
4772    @Override
4773    public void killBackgroundProcesses(final String packageName, int userId) {
4774        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4775                != PackageManager.PERMISSION_GRANTED &&
4776                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4777                        != PackageManager.PERMISSION_GRANTED) {
4778            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4779                    + Binder.getCallingPid()
4780                    + ", uid=" + Binder.getCallingUid()
4781                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4782            Slog.w(TAG, msg);
4783            throw new SecurityException(msg);
4784        }
4785
4786        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4787                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4788        long callingId = Binder.clearCallingIdentity();
4789        try {
4790            IPackageManager pm = AppGlobals.getPackageManager();
4791            synchronized(this) {
4792                int appId = -1;
4793                try {
4794                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4795                } catch (RemoteException e) {
4796                }
4797                if (appId == -1) {
4798                    Slog.w(TAG, "Invalid packageName: " + packageName);
4799                    return;
4800                }
4801                killPackageProcessesLocked(packageName, appId, userId,
4802                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4803            }
4804        } finally {
4805            Binder.restoreCallingIdentity(callingId);
4806        }
4807    }
4808
4809    @Override
4810    public void killAllBackgroundProcesses() {
4811        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4812                != PackageManager.PERMISSION_GRANTED) {
4813            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4814                    + Binder.getCallingPid()
4815                    + ", uid=" + Binder.getCallingUid()
4816                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4817            Slog.w(TAG, msg);
4818            throw new SecurityException(msg);
4819        }
4820
4821        long callingId = Binder.clearCallingIdentity();
4822        try {
4823            synchronized(this) {
4824                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4825                final int NP = mProcessNames.getMap().size();
4826                for (int ip=0; ip<NP; ip++) {
4827                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4828                    final int NA = apps.size();
4829                    for (int ia=0; ia<NA; ia++) {
4830                        ProcessRecord app = apps.valueAt(ia);
4831                        if (app.persistent) {
4832                            // we don't kill persistent processes
4833                            continue;
4834                        }
4835                        if (app.removed) {
4836                            procs.add(app);
4837                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4838                            app.removed = true;
4839                            procs.add(app);
4840                        }
4841                    }
4842                }
4843
4844                int N = procs.size();
4845                for (int i=0; i<N; i++) {
4846                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4847                }
4848                mAllowLowerMemLevel = true;
4849                updateOomAdjLocked();
4850                doLowMemReportIfNeededLocked(null);
4851            }
4852        } finally {
4853            Binder.restoreCallingIdentity(callingId);
4854        }
4855    }
4856
4857    @Override
4858    public void forceStopPackage(final String packageName, int userId) {
4859        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4860                != PackageManager.PERMISSION_GRANTED) {
4861            String msg = "Permission Denial: forceStopPackage() from pid="
4862                    + Binder.getCallingPid()
4863                    + ", uid=" + Binder.getCallingUid()
4864                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4865            Slog.w(TAG, msg);
4866            throw new SecurityException(msg);
4867        }
4868        final int callingPid = Binder.getCallingPid();
4869        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4870                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4871        long callingId = Binder.clearCallingIdentity();
4872        try {
4873            IPackageManager pm = AppGlobals.getPackageManager();
4874            synchronized(this) {
4875                int[] users = userId == UserHandle.USER_ALL
4876                        ? getUsersLocked() : new int[] { userId };
4877                for (int user : users) {
4878                    int pkgUid = -1;
4879                    try {
4880                        pkgUid = pm.getPackageUid(packageName, user);
4881                    } catch (RemoteException e) {
4882                    }
4883                    if (pkgUid == -1) {
4884                        Slog.w(TAG, "Invalid packageName: " + packageName);
4885                        continue;
4886                    }
4887                    try {
4888                        pm.setPackageStoppedState(packageName, true, user);
4889                    } catch (RemoteException e) {
4890                    } catch (IllegalArgumentException e) {
4891                        Slog.w(TAG, "Failed trying to unstop package "
4892                                + packageName + ": " + e);
4893                    }
4894                    if (isUserRunningLocked(user, false)) {
4895                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4896                    }
4897                }
4898            }
4899        } finally {
4900            Binder.restoreCallingIdentity(callingId);
4901        }
4902    }
4903
4904    @Override
4905    public void addPackageDependency(String packageName) {
4906        synchronized (this) {
4907            int callingPid = Binder.getCallingPid();
4908            if (callingPid == Process.myPid()) {
4909                //  Yeah, um, no.
4910                Slog.w(TAG, "Can't addPackageDependency on system process");
4911                return;
4912            }
4913            ProcessRecord proc;
4914            synchronized (mPidsSelfLocked) {
4915                proc = mPidsSelfLocked.get(Binder.getCallingPid());
4916            }
4917            if (proc != null) {
4918                if (proc.pkgDeps == null) {
4919                    proc.pkgDeps = new ArraySet<String>(1);
4920                }
4921                proc.pkgDeps.add(packageName);
4922            }
4923        }
4924    }
4925
4926    /*
4927     * The pkg name and app id have to be specified.
4928     */
4929    @Override
4930    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4931        if (pkg == null) {
4932            return;
4933        }
4934        // Make sure the uid is valid.
4935        if (appid < 0) {
4936            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4937            return;
4938        }
4939        int callerUid = Binder.getCallingUid();
4940        // Only the system server can kill an application
4941        if (callerUid == Process.SYSTEM_UID) {
4942            // Post an aysnc message to kill the application
4943            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4944            msg.arg1 = appid;
4945            msg.arg2 = 0;
4946            Bundle bundle = new Bundle();
4947            bundle.putString("pkg", pkg);
4948            bundle.putString("reason", reason);
4949            msg.obj = bundle;
4950            mHandler.sendMessage(msg);
4951        } else {
4952            throw new SecurityException(callerUid + " cannot kill pkg: " +
4953                    pkg);
4954        }
4955    }
4956
4957    @Override
4958    public void closeSystemDialogs(String reason) {
4959        enforceNotIsolatedCaller("closeSystemDialogs");
4960
4961        final int pid = Binder.getCallingPid();
4962        final int uid = Binder.getCallingUid();
4963        final long origId = Binder.clearCallingIdentity();
4964        try {
4965            synchronized (this) {
4966                // Only allow this from foreground processes, so that background
4967                // applications can't abuse it to prevent system UI from being shown.
4968                if (uid >= Process.FIRST_APPLICATION_UID) {
4969                    ProcessRecord proc;
4970                    synchronized (mPidsSelfLocked) {
4971                        proc = mPidsSelfLocked.get(pid);
4972                    }
4973                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4974                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4975                                + " from background process " + proc);
4976                        return;
4977                    }
4978                }
4979                closeSystemDialogsLocked(reason);
4980            }
4981        } finally {
4982            Binder.restoreCallingIdentity(origId);
4983        }
4984    }
4985
4986    void closeSystemDialogsLocked(String reason) {
4987        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4988        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4989                | Intent.FLAG_RECEIVER_FOREGROUND);
4990        if (reason != null) {
4991            intent.putExtra("reason", reason);
4992        }
4993        mWindowManager.closeSystemDialogs(reason);
4994
4995        mStackSupervisor.closeSystemDialogsLocked();
4996
4997        broadcastIntentLocked(null, null, intent, null,
4998                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4999                Process.SYSTEM_UID, UserHandle.USER_ALL);
5000    }
5001
5002    @Override
5003    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5004        enforceNotIsolatedCaller("getProcessMemoryInfo");
5005        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5006        for (int i=pids.length-1; i>=0; i--) {
5007            ProcessRecord proc;
5008            int oomAdj;
5009            synchronized (this) {
5010                synchronized (mPidsSelfLocked) {
5011                    proc = mPidsSelfLocked.get(pids[i]);
5012                    oomAdj = proc != null ? proc.setAdj : 0;
5013                }
5014            }
5015            infos[i] = new Debug.MemoryInfo();
5016            Debug.getMemoryInfo(pids[i], infos[i]);
5017            if (proc != null) {
5018                synchronized (this) {
5019                    if (proc.thread != null && proc.setAdj == oomAdj) {
5020                        // Record this for posterity if the process has been stable.
5021                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5022                                infos[i].getTotalUss(), false, proc.pkgList);
5023                    }
5024                }
5025            }
5026        }
5027        return infos;
5028    }
5029
5030    @Override
5031    public long[] getProcessPss(int[] pids) {
5032        enforceNotIsolatedCaller("getProcessPss");
5033        long[] pss = new long[pids.length];
5034        for (int i=pids.length-1; i>=0; i--) {
5035            ProcessRecord proc;
5036            int oomAdj;
5037            synchronized (this) {
5038                synchronized (mPidsSelfLocked) {
5039                    proc = mPidsSelfLocked.get(pids[i]);
5040                    oomAdj = proc != null ? proc.setAdj : 0;
5041                }
5042            }
5043            long[] tmpUss = new long[1];
5044            pss[i] = Debug.getPss(pids[i], tmpUss);
5045            if (proc != null) {
5046                synchronized (this) {
5047                    if (proc.thread != null && proc.setAdj == oomAdj) {
5048                        // Record this for posterity if the process has been stable.
5049                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5050                    }
5051                }
5052            }
5053        }
5054        return pss;
5055    }
5056
5057    @Override
5058    public void killApplicationProcess(String processName, int uid) {
5059        if (processName == null) {
5060            return;
5061        }
5062
5063        int callerUid = Binder.getCallingUid();
5064        // Only the system server can kill an application
5065        if (callerUid == Process.SYSTEM_UID) {
5066            synchronized (this) {
5067                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5068                if (app != null && app.thread != null) {
5069                    try {
5070                        app.thread.scheduleSuicide();
5071                    } catch (RemoteException e) {
5072                        // If the other end already died, then our work here is done.
5073                    }
5074                } else {
5075                    Slog.w(TAG, "Process/uid not found attempting kill of "
5076                            + processName + " / " + uid);
5077                }
5078            }
5079        } else {
5080            throw new SecurityException(callerUid + " cannot kill app process: " +
5081                    processName);
5082        }
5083    }
5084
5085    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5086        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5087                false, true, false, false, UserHandle.getUserId(uid), reason);
5088        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5089                Uri.fromParts("package", packageName, null));
5090        if (!mProcessesReady) {
5091            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5092                    | Intent.FLAG_RECEIVER_FOREGROUND);
5093        }
5094        intent.putExtra(Intent.EXTRA_UID, uid);
5095        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5096        broadcastIntentLocked(null, null, intent,
5097                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5098                false, false,
5099                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5100    }
5101
5102    private void forceStopUserLocked(int userId, String reason) {
5103        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5104        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5105        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5106                | Intent.FLAG_RECEIVER_FOREGROUND);
5107        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5108        broadcastIntentLocked(null, null, intent,
5109                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5110                false, false,
5111                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5112    }
5113
5114    private final boolean killPackageProcessesLocked(String packageName, int appId,
5115            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5116            boolean doit, boolean evenPersistent, String reason) {
5117        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5118
5119        // Remove all processes this package may have touched: all with the
5120        // same UID (except for the system or root user), and all whose name
5121        // matches the package name.
5122        final int NP = mProcessNames.getMap().size();
5123        for (int ip=0; ip<NP; ip++) {
5124            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5125            final int NA = apps.size();
5126            for (int ia=0; ia<NA; ia++) {
5127                ProcessRecord app = apps.valueAt(ia);
5128                if (app.persistent && !evenPersistent) {
5129                    // we don't kill persistent processes
5130                    continue;
5131                }
5132                if (app.removed) {
5133                    if (doit) {
5134                        procs.add(app);
5135                    }
5136                    continue;
5137                }
5138
5139                // Skip process if it doesn't meet our oom adj requirement.
5140                if (app.setAdj < minOomAdj) {
5141                    continue;
5142                }
5143
5144                // If no package is specified, we call all processes under the
5145                // give user id.
5146                if (packageName == null) {
5147                    if (app.userId != userId) {
5148                        continue;
5149                    }
5150                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5151                        continue;
5152                    }
5153                // Package has been specified, we want to hit all processes
5154                // that match it.  We need to qualify this by the processes
5155                // that are running under the specified app and user ID.
5156                } else {
5157                    final boolean isDep = app.pkgDeps != null
5158                            && app.pkgDeps.contains(packageName);
5159                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5160                        continue;
5161                    }
5162                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5163                        continue;
5164                    }
5165                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5166                        continue;
5167                    }
5168                }
5169
5170                // Process has passed all conditions, kill it!
5171                if (!doit) {
5172                    return true;
5173                }
5174                app.removed = true;
5175                procs.add(app);
5176            }
5177        }
5178
5179        int N = procs.size();
5180        for (int i=0; i<N; i++) {
5181            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5182        }
5183        updateOomAdjLocked();
5184        return N > 0;
5185    }
5186
5187    private final boolean forceStopPackageLocked(String name, int appId,
5188            boolean callerWillRestart, boolean purgeCache, boolean doit,
5189            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5190        int i;
5191        int N;
5192
5193        if (userId == UserHandle.USER_ALL && name == null) {
5194            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5195        }
5196
5197        if (appId < 0 && name != null) {
5198            try {
5199                appId = UserHandle.getAppId(
5200                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5201            } catch (RemoteException e) {
5202            }
5203        }
5204
5205        if (doit) {
5206            if (name != null) {
5207                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5208                        + " user=" + userId + ": " + reason);
5209            } else {
5210                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5211            }
5212
5213            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5214            for (int ip=pmap.size()-1; ip>=0; ip--) {
5215                SparseArray<Long> ba = pmap.valueAt(ip);
5216                for (i=ba.size()-1; i>=0; i--) {
5217                    boolean remove = false;
5218                    final int entUid = ba.keyAt(i);
5219                    if (name != null) {
5220                        if (userId == UserHandle.USER_ALL) {
5221                            if (UserHandle.getAppId(entUid) == appId) {
5222                                remove = true;
5223                            }
5224                        } else {
5225                            if (entUid == UserHandle.getUid(userId, appId)) {
5226                                remove = true;
5227                            }
5228                        }
5229                    } else if (UserHandle.getUserId(entUid) == userId) {
5230                        remove = true;
5231                    }
5232                    if (remove) {
5233                        ba.removeAt(i);
5234                    }
5235                }
5236                if (ba.size() == 0) {
5237                    pmap.removeAt(ip);
5238                }
5239            }
5240        }
5241
5242        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5243                -100, callerWillRestart, true, doit, evenPersistent,
5244                name == null ? ("stop user " + userId) : ("stop " + name));
5245
5246        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5247            if (!doit) {
5248                return true;
5249            }
5250            didSomething = true;
5251        }
5252
5253        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5254            if (!doit) {
5255                return true;
5256            }
5257            didSomething = true;
5258        }
5259
5260        if (name == null) {
5261            // Remove all sticky broadcasts from this user.
5262            mStickyBroadcasts.remove(userId);
5263        }
5264
5265        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5266        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5267                userId, providers)) {
5268            if (!doit) {
5269                return true;
5270            }
5271            didSomething = true;
5272        }
5273        N = providers.size();
5274        for (i=0; i<N; i++) {
5275            removeDyingProviderLocked(null, providers.get(i), true);
5276        }
5277
5278        // Remove transient permissions granted from/to this package/user
5279        removeUriPermissionsForPackageLocked(name, userId, false);
5280
5281        if (name == null || uninstalling) {
5282            // Remove pending intents.  For now we only do this when force
5283            // stopping users, because we have some problems when doing this
5284            // for packages -- app widgets are not currently cleaned up for
5285            // such packages, so they can be left with bad pending intents.
5286            if (mIntentSenderRecords.size() > 0) {
5287                Iterator<WeakReference<PendingIntentRecord>> it
5288                        = mIntentSenderRecords.values().iterator();
5289                while (it.hasNext()) {
5290                    WeakReference<PendingIntentRecord> wpir = it.next();
5291                    if (wpir == null) {
5292                        it.remove();
5293                        continue;
5294                    }
5295                    PendingIntentRecord pir = wpir.get();
5296                    if (pir == null) {
5297                        it.remove();
5298                        continue;
5299                    }
5300                    if (name == null) {
5301                        // Stopping user, remove all objects for the user.
5302                        if (pir.key.userId != userId) {
5303                            // Not the same user, skip it.
5304                            continue;
5305                        }
5306                    } else {
5307                        if (UserHandle.getAppId(pir.uid) != appId) {
5308                            // Different app id, skip it.
5309                            continue;
5310                        }
5311                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5312                            // Different user, skip it.
5313                            continue;
5314                        }
5315                        if (!pir.key.packageName.equals(name)) {
5316                            // Different package, skip it.
5317                            continue;
5318                        }
5319                    }
5320                    if (!doit) {
5321                        return true;
5322                    }
5323                    didSomething = true;
5324                    it.remove();
5325                    pir.canceled = true;
5326                    if (pir.key.activity != null) {
5327                        pir.key.activity.pendingResults.remove(pir.ref);
5328                    }
5329                }
5330            }
5331        }
5332
5333        if (doit) {
5334            if (purgeCache && name != null) {
5335                AttributeCache ac = AttributeCache.instance();
5336                if (ac != null) {
5337                    ac.removePackage(name);
5338                }
5339            }
5340            if (mBooted) {
5341                mStackSupervisor.resumeTopActivitiesLocked();
5342                mStackSupervisor.scheduleIdleLocked();
5343            }
5344        }
5345
5346        return didSomething;
5347    }
5348
5349    private final boolean removeProcessLocked(ProcessRecord app,
5350            boolean callerWillRestart, boolean allowRestart, String reason) {
5351        final String name = app.processName;
5352        final int uid = app.uid;
5353        if (DEBUG_PROCESSES) Slog.d(
5354            TAG, "Force removing proc " + app.toShortString() + " (" + name
5355            + "/" + uid + ")");
5356
5357        mProcessNames.remove(name, uid);
5358        mIsolatedProcesses.remove(app.uid);
5359        if (mHeavyWeightProcess == app) {
5360            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5361                    mHeavyWeightProcess.userId, 0));
5362            mHeavyWeightProcess = null;
5363        }
5364        boolean needRestart = false;
5365        if (app.pid > 0 && app.pid != MY_PID) {
5366            int pid = app.pid;
5367            synchronized (mPidsSelfLocked) {
5368                mPidsSelfLocked.remove(pid);
5369                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5370            }
5371            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5372            if (app.isolated) {
5373                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5374            }
5375            killUnneededProcessLocked(app, reason);
5376            Process.killProcessGroup(app.info.uid, app.pid);
5377            handleAppDiedLocked(app, true, allowRestart);
5378            removeLruProcessLocked(app);
5379
5380            if (app.persistent && !app.isolated) {
5381                if (!callerWillRestart) {
5382                    addAppLocked(app.info, false, null /* ABI override */);
5383                } else {
5384                    needRestart = true;
5385                }
5386            }
5387        } else {
5388            mRemovedProcesses.add(app);
5389        }
5390
5391        return needRestart;
5392    }
5393
5394    private final void processStartTimedOutLocked(ProcessRecord app) {
5395        final int pid = app.pid;
5396        boolean gone = false;
5397        synchronized (mPidsSelfLocked) {
5398            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5399            if (knownApp != null && knownApp.thread == null) {
5400                mPidsSelfLocked.remove(pid);
5401                gone = true;
5402            }
5403        }
5404
5405        if (gone) {
5406            Slog.w(TAG, "Process " + app + " failed to attach");
5407            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5408                    pid, app.uid, app.processName);
5409            mProcessNames.remove(app.processName, app.uid);
5410            mIsolatedProcesses.remove(app.uid);
5411            if (mHeavyWeightProcess == app) {
5412                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5413                        mHeavyWeightProcess.userId, 0));
5414                mHeavyWeightProcess = null;
5415            }
5416            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5417            if (app.isolated) {
5418                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5419            }
5420            // Take care of any launching providers waiting for this process.
5421            checkAppInLaunchingProvidersLocked(app, true);
5422            // Take care of any services that are waiting for the process.
5423            mServices.processStartTimedOutLocked(app);
5424            killUnneededProcessLocked(app, "start timeout");
5425            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5426                Slog.w(TAG, "Unattached app died before backup, skipping");
5427                try {
5428                    IBackupManager bm = IBackupManager.Stub.asInterface(
5429                            ServiceManager.getService(Context.BACKUP_SERVICE));
5430                    bm.agentDisconnected(app.info.packageName);
5431                } catch (RemoteException e) {
5432                    // Can't happen; the backup manager is local
5433                }
5434            }
5435            if (isPendingBroadcastProcessLocked(pid)) {
5436                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5437                skipPendingBroadcastLocked(pid);
5438            }
5439        } else {
5440            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5441        }
5442    }
5443
5444    private final boolean attachApplicationLocked(IApplicationThread thread,
5445            int pid) {
5446
5447        // Find the application record that is being attached...  either via
5448        // the pid if we are running in multiple processes, or just pull the
5449        // next app record if we are emulating process with anonymous threads.
5450        ProcessRecord app;
5451        if (pid != MY_PID && pid >= 0) {
5452            synchronized (mPidsSelfLocked) {
5453                app = mPidsSelfLocked.get(pid);
5454            }
5455        } else {
5456            app = null;
5457        }
5458
5459        if (app == null) {
5460            Slog.w(TAG, "No pending application record for pid " + pid
5461                    + " (IApplicationThread " + thread + "); dropping process");
5462            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5463            if (pid > 0 && pid != MY_PID) {
5464                Process.killProcessQuiet(pid);
5465                //TODO: Process.killProcessGroup(app.info.uid, pid);
5466            } else {
5467                try {
5468                    thread.scheduleExit();
5469                } catch (Exception e) {
5470                    // Ignore exceptions.
5471                }
5472            }
5473            return false;
5474        }
5475
5476        // If this application record is still attached to a previous
5477        // process, clean it up now.
5478        if (app.thread != null) {
5479            handleAppDiedLocked(app, true, true);
5480        }
5481
5482        // Tell the process all about itself.
5483
5484        if (localLOGV) Slog.v(
5485                TAG, "Binding process pid " + pid + " to record " + app);
5486
5487        final String processName = app.processName;
5488        try {
5489            AppDeathRecipient adr = new AppDeathRecipient(
5490                    app, pid, thread);
5491            thread.asBinder().linkToDeath(adr, 0);
5492            app.deathRecipient = adr;
5493        } catch (RemoteException e) {
5494            app.resetPackageList(mProcessStats);
5495            startProcessLocked(app, "link fail", processName);
5496            return false;
5497        }
5498
5499        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5500
5501        app.makeActive(thread, mProcessStats);
5502        app.curAdj = app.setAdj = -100;
5503        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5504        app.forcingToForeground = null;
5505        updateProcessForegroundLocked(app, false, false);
5506        app.hasShownUi = false;
5507        app.debugging = false;
5508        app.cached = false;
5509
5510        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5511
5512        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5513        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5514
5515        if (!normalMode) {
5516            Slog.i(TAG, "Launching preboot mode app: " + app);
5517        }
5518
5519        if (localLOGV) Slog.v(
5520            TAG, "New app record " + app
5521            + " thread=" + thread.asBinder() + " pid=" + pid);
5522        try {
5523            int testMode = IApplicationThread.DEBUG_OFF;
5524            if (mDebugApp != null && mDebugApp.equals(processName)) {
5525                testMode = mWaitForDebugger
5526                    ? IApplicationThread.DEBUG_WAIT
5527                    : IApplicationThread.DEBUG_ON;
5528                app.debugging = true;
5529                if (mDebugTransient) {
5530                    mDebugApp = mOrigDebugApp;
5531                    mWaitForDebugger = mOrigWaitForDebugger;
5532                }
5533            }
5534            String profileFile = app.instrumentationProfileFile;
5535            ParcelFileDescriptor profileFd = null;
5536            boolean profileAutoStop = false;
5537            if (mProfileApp != null && mProfileApp.equals(processName)) {
5538                mProfileProc = app;
5539                profileFile = mProfileFile;
5540                profileFd = mProfileFd;
5541                profileAutoStop = mAutoStopProfiler;
5542            }
5543            boolean enableOpenGlTrace = false;
5544            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5545                enableOpenGlTrace = true;
5546                mOpenGlTraceApp = null;
5547            }
5548
5549            // If the app is being launched for restore or full backup, set it up specially
5550            boolean isRestrictedBackupMode = false;
5551            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5552                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5553                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5554                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5555            }
5556
5557            ensurePackageDexOpt(app.instrumentationInfo != null
5558                    ? app.instrumentationInfo.packageName
5559                    : app.info.packageName);
5560            if (app.instrumentationClass != null) {
5561                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5562            }
5563            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5564                    + processName + " with config " + mConfiguration);
5565            ApplicationInfo appInfo = app.instrumentationInfo != null
5566                    ? app.instrumentationInfo : app.info;
5567            app.compat = compatibilityInfoForPackageLocked(appInfo);
5568            if (profileFd != null) {
5569                profileFd = profileFd.dup();
5570            }
5571            thread.bindApplication(processName, appInfo, providers,
5572                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5573                    app.instrumentationArguments, app.instrumentationWatcher,
5574                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5575                    isRestrictedBackupMode || !normalMode, app.persistent,
5576                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5577                    mCoreSettingsObserver.getCoreSettingsLocked());
5578            updateLruProcessLocked(app, false, null);
5579            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5580        } catch (Exception e) {
5581            // todo: Yikes!  What should we do?  For now we will try to
5582            // start another process, but that could easily get us in
5583            // an infinite loop of restarting processes...
5584            Slog.w(TAG, "Exception thrown during bind!", e);
5585
5586            app.resetPackageList(mProcessStats);
5587            app.unlinkDeathRecipient();
5588            startProcessLocked(app, "bind fail", processName);
5589            return false;
5590        }
5591
5592        // Remove this record from the list of starting applications.
5593        mPersistentStartingProcesses.remove(app);
5594        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5595                "Attach application locked removing on hold: " + app);
5596        mProcessesOnHold.remove(app);
5597
5598        boolean badApp = false;
5599        boolean didSomething = false;
5600
5601        // See if the top visible activity is waiting to run in this process...
5602        if (normalMode) {
5603            try {
5604                if (mStackSupervisor.attachApplicationLocked(app)) {
5605                    didSomething = true;
5606                }
5607            } catch (Exception e) {
5608                badApp = true;
5609            }
5610        }
5611
5612        // Find any services that should be running in this process...
5613        if (!badApp) {
5614            try {
5615                didSomething |= mServices.attachApplicationLocked(app, processName);
5616            } catch (Exception e) {
5617                badApp = true;
5618            }
5619        }
5620
5621        // Check if a next-broadcast receiver is in this process...
5622        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5623            try {
5624                didSomething |= sendPendingBroadcastsLocked(app);
5625            } catch (Exception e) {
5626                // If the app died trying to launch the receiver we declare it 'bad'
5627                badApp = true;
5628            }
5629        }
5630
5631        // Check whether the next backup agent is in this process...
5632        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5633            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5634            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5635            try {
5636                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5637                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5638                        mBackupTarget.backupMode);
5639            } catch (Exception e) {
5640                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5641                e.printStackTrace();
5642            }
5643        }
5644
5645        if (badApp) {
5646            // todo: Also need to kill application to deal with all
5647            // kinds of exceptions.
5648            handleAppDiedLocked(app, false, true);
5649            return false;
5650        }
5651
5652        if (!didSomething) {
5653            updateOomAdjLocked();
5654        }
5655
5656        return true;
5657    }
5658
5659    @Override
5660    public final void attachApplication(IApplicationThread thread) {
5661        synchronized (this) {
5662            int callingPid = Binder.getCallingPid();
5663            final long origId = Binder.clearCallingIdentity();
5664            attachApplicationLocked(thread, callingPid);
5665            Binder.restoreCallingIdentity(origId);
5666        }
5667    }
5668
5669    @Override
5670    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5671        final long origId = Binder.clearCallingIdentity();
5672        synchronized (this) {
5673            ActivityStack stack = ActivityRecord.getStackLocked(token);
5674            if (stack != null) {
5675                ActivityRecord r =
5676                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5677                if (stopProfiling) {
5678                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5679                        try {
5680                            mProfileFd.close();
5681                        } catch (IOException e) {
5682                        }
5683                        clearProfilerLocked();
5684                    }
5685                }
5686            }
5687        }
5688        Binder.restoreCallingIdentity(origId);
5689    }
5690
5691    void postEnableScreenAfterBootLocked() {
5692        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
5693    }
5694
5695    void enableScreenAfterBoot() {
5696        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5697                SystemClock.uptimeMillis());
5698        mWindowManager.enableScreenAfterBoot();
5699
5700        synchronized (this) {
5701            updateEventDispatchingLocked();
5702        }
5703    }
5704
5705    @Override
5706    public void showBootMessage(final CharSequence msg, final boolean always) {
5707        enforceNotIsolatedCaller("showBootMessage");
5708        mWindowManager.showBootMessage(msg, always);
5709    }
5710
5711    @Override
5712    public void keyguardWaitingForActivityDrawn() {
5713        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
5714        final long token = Binder.clearCallingIdentity();
5715        try {
5716            synchronized (this) {
5717                if (DEBUG_LOCKSCREEN) logLockScreen("");
5718                mWindowManager.keyguardWaitingForActivityDrawn();
5719            }
5720        } finally {
5721            Binder.restoreCallingIdentity(token);
5722        }
5723    }
5724
5725    final void finishBooting() {
5726        // Register receivers to handle package update events
5727        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5728
5729        // Let system services know.
5730        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
5731
5732        synchronized (this) {
5733            // Ensure that any processes we had put on hold are now started
5734            // up.
5735            final int NP = mProcessesOnHold.size();
5736            if (NP > 0) {
5737                ArrayList<ProcessRecord> procs =
5738                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5739                for (int ip=0; ip<NP; ip++) {
5740                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5741                            + procs.get(ip));
5742                    startProcessLocked(procs.get(ip), "on-hold", null);
5743                }
5744            }
5745
5746            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5747                // Start looking for apps that are abusing wake locks.
5748                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5749                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5750                // Tell anyone interested that we are done booting!
5751                SystemProperties.set("sys.boot_completed", "1");
5752                SystemProperties.set("dev.bootcomplete", "1");
5753                for (int i=0; i<mStartedUsers.size(); i++) {
5754                    UserStartedState uss = mStartedUsers.valueAt(i);
5755                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5756                        uss.mState = UserStartedState.STATE_RUNNING;
5757                        final int userId = mStartedUsers.keyAt(i);
5758                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5759                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5760                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5761                        broadcastIntentLocked(null, null, intent, null,
5762                                new IIntentReceiver.Stub() {
5763                                    @Override
5764                                    public void performReceive(Intent intent, int resultCode,
5765                                            String data, Bundle extras, boolean ordered,
5766                                            boolean sticky, int sendingUser) {
5767                                        synchronized (ActivityManagerService.this) {
5768                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5769                                                    true, false);
5770                                        }
5771                                    }
5772                                },
5773                                0, null, null,
5774                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5775                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5776                                userId);
5777                    }
5778                }
5779                scheduleStartProfilesLocked();
5780            }
5781        }
5782    }
5783
5784    final void ensureBootCompleted() {
5785        boolean booting;
5786        boolean enableScreen;
5787        synchronized (this) {
5788            booting = mBooting;
5789            mBooting = false;
5790            enableScreen = !mBooted;
5791            mBooted = true;
5792        }
5793
5794        if (booting) {
5795            finishBooting();
5796        }
5797
5798        if (enableScreen) {
5799            enableScreenAfterBoot();
5800        }
5801    }
5802
5803    @Override
5804    public final void activityResumed(IBinder token) {
5805        final long origId = Binder.clearCallingIdentity();
5806        synchronized(this) {
5807            ActivityStack stack = ActivityRecord.getStackLocked(token);
5808            if (stack != null) {
5809                ActivityRecord.activityResumedLocked(token);
5810            }
5811        }
5812        Binder.restoreCallingIdentity(origId);
5813    }
5814
5815    @Override
5816    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5817        final long origId = Binder.clearCallingIdentity();
5818        synchronized(this) {
5819            ActivityStack stack = ActivityRecord.getStackLocked(token);
5820            if (stack != null) {
5821                stack.activityPausedLocked(token, false, persistentState);
5822            }
5823        }
5824        Binder.restoreCallingIdentity(origId);
5825    }
5826
5827    @Override
5828    public final void activityStopped(IBinder token, Bundle icicle,
5829            PersistableBundle persistentState, CharSequence description) {
5830        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5831
5832        // Refuse possible leaked file descriptors
5833        if (icicle != null && icicle.hasFileDescriptors()) {
5834            throw new IllegalArgumentException("File descriptors passed in Bundle");
5835        }
5836
5837        final long origId = Binder.clearCallingIdentity();
5838
5839        synchronized (this) {
5840            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5841            if (r != null) {
5842                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5843            }
5844        }
5845
5846        trimApplications();
5847
5848        Binder.restoreCallingIdentity(origId);
5849    }
5850
5851    @Override
5852    public final void activityDestroyed(IBinder token) {
5853        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5854        synchronized (this) {
5855            ActivityStack stack = ActivityRecord.getStackLocked(token);
5856            if (stack != null) {
5857                stack.activityDestroyedLocked(token);
5858            }
5859        }
5860    }
5861
5862    @Override
5863    public final void backgroundResourcesReleased(IBinder token) {
5864        final long origId = Binder.clearCallingIdentity();
5865        try {
5866            synchronized (this) {
5867                ActivityStack stack = ActivityRecord.getStackLocked(token);
5868                if (stack != null) {
5869                    stack.backgroundResourcesReleased(token);
5870                }
5871            }
5872        } finally {
5873            Binder.restoreCallingIdentity(origId);
5874        }
5875    }
5876
5877    @Override
5878    public final void notifyLaunchTaskBehindComplete(IBinder token) {
5879        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
5880    }
5881
5882    @Override
5883    public final void notifyEnterAnimationComplete(IBinder token) {
5884        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
5885    }
5886
5887    @Override
5888    public String getCallingPackage(IBinder token) {
5889        synchronized (this) {
5890            ActivityRecord r = getCallingRecordLocked(token);
5891            return r != null ? r.info.packageName : null;
5892        }
5893    }
5894
5895    @Override
5896    public ComponentName getCallingActivity(IBinder token) {
5897        synchronized (this) {
5898            ActivityRecord r = getCallingRecordLocked(token);
5899            return r != null ? r.intent.getComponent() : null;
5900        }
5901    }
5902
5903    private ActivityRecord getCallingRecordLocked(IBinder token) {
5904        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5905        if (r == null) {
5906            return null;
5907        }
5908        return r.resultTo;
5909    }
5910
5911    @Override
5912    public ComponentName getActivityClassForToken(IBinder token) {
5913        synchronized(this) {
5914            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5915            if (r == null) {
5916                return null;
5917            }
5918            return r.intent.getComponent();
5919        }
5920    }
5921
5922    @Override
5923    public String getPackageForToken(IBinder token) {
5924        synchronized(this) {
5925            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5926            if (r == null) {
5927                return null;
5928            }
5929            return r.packageName;
5930        }
5931    }
5932
5933    @Override
5934    public IIntentSender getIntentSender(int type,
5935            String packageName, IBinder token, String resultWho,
5936            int requestCode, Intent[] intents, String[] resolvedTypes,
5937            int flags, Bundle options, int userId) {
5938        enforceNotIsolatedCaller("getIntentSender");
5939        // Refuse possible leaked file descriptors
5940        if (intents != null) {
5941            if (intents.length < 1) {
5942                throw new IllegalArgumentException("Intents array length must be >= 1");
5943            }
5944            for (int i=0; i<intents.length; i++) {
5945                Intent intent = intents[i];
5946                if (intent != null) {
5947                    if (intent.hasFileDescriptors()) {
5948                        throw new IllegalArgumentException("File descriptors passed in Intent");
5949                    }
5950                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5951                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5952                        throw new IllegalArgumentException(
5953                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5954                    }
5955                    intents[i] = new Intent(intent);
5956                }
5957            }
5958            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5959                throw new IllegalArgumentException(
5960                        "Intent array length does not match resolvedTypes length");
5961            }
5962        }
5963        if (options != null) {
5964            if (options.hasFileDescriptors()) {
5965                throw new IllegalArgumentException("File descriptors passed in options");
5966            }
5967        }
5968
5969        synchronized(this) {
5970            int callingUid = Binder.getCallingUid();
5971            int origUserId = userId;
5972            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5973                    type == ActivityManager.INTENT_SENDER_BROADCAST,
5974                    ALLOW_NON_FULL, "getIntentSender", null);
5975            if (origUserId == UserHandle.USER_CURRENT) {
5976                // We don't want to evaluate this until the pending intent is
5977                // actually executed.  However, we do want to always do the
5978                // security checking for it above.
5979                userId = UserHandle.USER_CURRENT;
5980            }
5981            try {
5982                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5983                    int uid = AppGlobals.getPackageManager()
5984                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5985                    if (!UserHandle.isSameApp(callingUid, uid)) {
5986                        String msg = "Permission Denial: getIntentSender() from pid="
5987                            + Binder.getCallingPid()
5988                            + ", uid=" + Binder.getCallingUid()
5989                            + ", (need uid=" + uid + ")"
5990                            + " is not allowed to send as package " + packageName;
5991                        Slog.w(TAG, msg);
5992                        throw new SecurityException(msg);
5993                    }
5994                }
5995
5996                return getIntentSenderLocked(type, packageName, callingUid, userId,
5997                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5998
5999            } catch (RemoteException e) {
6000                throw new SecurityException(e);
6001            }
6002        }
6003    }
6004
6005    IIntentSender getIntentSenderLocked(int type, String packageName,
6006            int callingUid, int userId, IBinder token, String resultWho,
6007            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6008            Bundle options) {
6009        if (DEBUG_MU)
6010            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6011        ActivityRecord activity = null;
6012        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6013            activity = ActivityRecord.isInStackLocked(token);
6014            if (activity == null) {
6015                return null;
6016            }
6017            if (activity.finishing) {
6018                return null;
6019            }
6020        }
6021
6022        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6023        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6024        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6025        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6026                |PendingIntent.FLAG_UPDATE_CURRENT);
6027
6028        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6029                type, packageName, activity, resultWho,
6030                requestCode, intents, resolvedTypes, flags, options, userId);
6031        WeakReference<PendingIntentRecord> ref;
6032        ref = mIntentSenderRecords.get(key);
6033        PendingIntentRecord rec = ref != null ? ref.get() : null;
6034        if (rec != null) {
6035            if (!cancelCurrent) {
6036                if (updateCurrent) {
6037                    if (rec.key.requestIntent != null) {
6038                        rec.key.requestIntent.replaceExtras(intents != null ?
6039                                intents[intents.length - 1] : null);
6040                    }
6041                    if (intents != null) {
6042                        intents[intents.length-1] = rec.key.requestIntent;
6043                        rec.key.allIntents = intents;
6044                        rec.key.allResolvedTypes = resolvedTypes;
6045                    } else {
6046                        rec.key.allIntents = null;
6047                        rec.key.allResolvedTypes = null;
6048                    }
6049                }
6050                return rec;
6051            }
6052            rec.canceled = true;
6053            mIntentSenderRecords.remove(key);
6054        }
6055        if (noCreate) {
6056            return rec;
6057        }
6058        rec = new PendingIntentRecord(this, key, callingUid);
6059        mIntentSenderRecords.put(key, rec.ref);
6060        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6061            if (activity.pendingResults == null) {
6062                activity.pendingResults
6063                        = new HashSet<WeakReference<PendingIntentRecord>>();
6064            }
6065            activity.pendingResults.add(rec.ref);
6066        }
6067        return rec;
6068    }
6069
6070    @Override
6071    public void cancelIntentSender(IIntentSender sender) {
6072        if (!(sender instanceof PendingIntentRecord)) {
6073            return;
6074        }
6075        synchronized(this) {
6076            PendingIntentRecord rec = (PendingIntentRecord)sender;
6077            try {
6078                int uid = AppGlobals.getPackageManager()
6079                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6080                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6081                    String msg = "Permission Denial: cancelIntentSender() from pid="
6082                        + Binder.getCallingPid()
6083                        + ", uid=" + Binder.getCallingUid()
6084                        + " is not allowed to cancel packges "
6085                        + rec.key.packageName;
6086                    Slog.w(TAG, msg);
6087                    throw new SecurityException(msg);
6088                }
6089            } catch (RemoteException e) {
6090                throw new SecurityException(e);
6091            }
6092            cancelIntentSenderLocked(rec, true);
6093        }
6094    }
6095
6096    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6097        rec.canceled = true;
6098        mIntentSenderRecords.remove(rec.key);
6099        if (cleanActivity && rec.key.activity != null) {
6100            rec.key.activity.pendingResults.remove(rec.ref);
6101        }
6102    }
6103
6104    @Override
6105    public String getPackageForIntentSender(IIntentSender pendingResult) {
6106        if (!(pendingResult instanceof PendingIntentRecord)) {
6107            return null;
6108        }
6109        try {
6110            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6111            return res.key.packageName;
6112        } catch (ClassCastException e) {
6113        }
6114        return null;
6115    }
6116
6117    @Override
6118    public int getUidForIntentSender(IIntentSender sender) {
6119        if (sender instanceof PendingIntentRecord) {
6120            try {
6121                PendingIntentRecord res = (PendingIntentRecord)sender;
6122                return res.uid;
6123            } catch (ClassCastException e) {
6124            }
6125        }
6126        return -1;
6127    }
6128
6129    @Override
6130    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6131        if (!(pendingResult instanceof PendingIntentRecord)) {
6132            return false;
6133        }
6134        try {
6135            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6136            if (res.key.allIntents == null) {
6137                return false;
6138            }
6139            for (int i=0; i<res.key.allIntents.length; i++) {
6140                Intent intent = res.key.allIntents[i];
6141                if (intent.getPackage() != null && intent.getComponent() != null) {
6142                    return false;
6143                }
6144            }
6145            return true;
6146        } catch (ClassCastException e) {
6147        }
6148        return false;
6149    }
6150
6151    @Override
6152    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6153        if (!(pendingResult instanceof PendingIntentRecord)) {
6154            return false;
6155        }
6156        try {
6157            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6158            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6159                return true;
6160            }
6161            return false;
6162        } catch (ClassCastException e) {
6163        }
6164        return false;
6165    }
6166
6167    @Override
6168    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6169        if (!(pendingResult instanceof PendingIntentRecord)) {
6170            return null;
6171        }
6172        try {
6173            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6174            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6175        } catch (ClassCastException e) {
6176        }
6177        return null;
6178    }
6179
6180    @Override
6181    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6182        if (!(pendingResult instanceof PendingIntentRecord)) {
6183            return null;
6184        }
6185        try {
6186            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6187            Intent intent = res.key.requestIntent;
6188            if (intent != null) {
6189                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6190                        || res.lastTagPrefix.equals(prefix))) {
6191                    return res.lastTag;
6192                }
6193                res.lastTagPrefix = prefix;
6194                StringBuilder sb = new StringBuilder(128);
6195                if (prefix != null) {
6196                    sb.append(prefix);
6197                }
6198                if (intent.getAction() != null) {
6199                    sb.append(intent.getAction());
6200                } else if (intent.getComponent() != null) {
6201                    intent.getComponent().appendShortString(sb);
6202                } else {
6203                    sb.append("?");
6204                }
6205                return res.lastTag = sb.toString();
6206            }
6207        } catch (ClassCastException e) {
6208        }
6209        return null;
6210    }
6211
6212    @Override
6213    public void setProcessLimit(int max) {
6214        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6215                "setProcessLimit()");
6216        synchronized (this) {
6217            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6218            mProcessLimitOverride = max;
6219        }
6220        trimApplications();
6221    }
6222
6223    @Override
6224    public int getProcessLimit() {
6225        synchronized (this) {
6226            return mProcessLimitOverride;
6227        }
6228    }
6229
6230    void foregroundTokenDied(ForegroundToken token) {
6231        synchronized (ActivityManagerService.this) {
6232            synchronized (mPidsSelfLocked) {
6233                ForegroundToken cur
6234                    = mForegroundProcesses.get(token.pid);
6235                if (cur != token) {
6236                    return;
6237                }
6238                mForegroundProcesses.remove(token.pid);
6239                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6240                if (pr == null) {
6241                    return;
6242                }
6243                pr.forcingToForeground = null;
6244                updateProcessForegroundLocked(pr, false, false);
6245            }
6246            updateOomAdjLocked();
6247        }
6248    }
6249
6250    @Override
6251    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6252        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6253                "setProcessForeground()");
6254        synchronized(this) {
6255            boolean changed = false;
6256
6257            synchronized (mPidsSelfLocked) {
6258                ProcessRecord pr = mPidsSelfLocked.get(pid);
6259                if (pr == null && isForeground) {
6260                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6261                    return;
6262                }
6263                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6264                if (oldToken != null) {
6265                    oldToken.token.unlinkToDeath(oldToken, 0);
6266                    mForegroundProcesses.remove(pid);
6267                    if (pr != null) {
6268                        pr.forcingToForeground = null;
6269                    }
6270                    changed = true;
6271                }
6272                if (isForeground && token != null) {
6273                    ForegroundToken newToken = new ForegroundToken() {
6274                        @Override
6275                        public void binderDied() {
6276                            foregroundTokenDied(this);
6277                        }
6278                    };
6279                    newToken.pid = pid;
6280                    newToken.token = token;
6281                    try {
6282                        token.linkToDeath(newToken, 0);
6283                        mForegroundProcesses.put(pid, newToken);
6284                        pr.forcingToForeground = token;
6285                        changed = true;
6286                    } catch (RemoteException e) {
6287                        // If the process died while doing this, we will later
6288                        // do the cleanup with the process death link.
6289                    }
6290                }
6291            }
6292
6293            if (changed) {
6294                updateOomAdjLocked();
6295            }
6296        }
6297    }
6298
6299    // =========================================================
6300    // PERMISSIONS
6301    // =========================================================
6302
6303    static class PermissionController extends IPermissionController.Stub {
6304        ActivityManagerService mActivityManagerService;
6305        PermissionController(ActivityManagerService activityManagerService) {
6306            mActivityManagerService = activityManagerService;
6307        }
6308
6309        @Override
6310        public boolean checkPermission(String permission, int pid, int uid) {
6311            return mActivityManagerService.checkPermission(permission, pid,
6312                    uid) == PackageManager.PERMISSION_GRANTED;
6313        }
6314    }
6315
6316    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6317        @Override
6318        public int checkComponentPermission(String permission, int pid, int uid,
6319                int owningUid, boolean exported) {
6320            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6321                    owningUid, exported);
6322        }
6323
6324        @Override
6325        public Object getAMSLock() {
6326            return ActivityManagerService.this;
6327        }
6328    }
6329
6330    /**
6331     * This can be called with or without the global lock held.
6332     */
6333    int checkComponentPermission(String permission, int pid, int uid,
6334            int owningUid, boolean exported) {
6335        // We might be performing an operation on behalf of an indirect binder
6336        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6337        // client identity accordingly before proceeding.
6338        Identity tlsIdentity = sCallerIdentity.get();
6339        if (tlsIdentity != null) {
6340            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6341                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6342            uid = tlsIdentity.uid;
6343            pid = tlsIdentity.pid;
6344        }
6345
6346        if (pid == MY_PID) {
6347            return PackageManager.PERMISSION_GRANTED;
6348        }
6349
6350        return ActivityManager.checkComponentPermission(permission, uid,
6351                owningUid, exported);
6352    }
6353
6354    /**
6355     * As the only public entry point for permissions checking, this method
6356     * can enforce the semantic that requesting a check on a null global
6357     * permission is automatically denied.  (Internally a null permission
6358     * string is used when calling {@link #checkComponentPermission} in cases
6359     * when only uid-based security is needed.)
6360     *
6361     * This can be called with or without the global lock held.
6362     */
6363    @Override
6364    public int checkPermission(String permission, int pid, int uid) {
6365        if (permission == null) {
6366            return PackageManager.PERMISSION_DENIED;
6367        }
6368        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6369    }
6370
6371    /**
6372     * Binder IPC calls go through the public entry point.
6373     * This can be called with or without the global lock held.
6374     */
6375    int checkCallingPermission(String permission) {
6376        return checkPermission(permission,
6377                Binder.getCallingPid(),
6378                UserHandle.getAppId(Binder.getCallingUid()));
6379    }
6380
6381    /**
6382     * This can be called with or without the global lock held.
6383     */
6384    void enforceCallingPermission(String permission, String func) {
6385        if (checkCallingPermission(permission)
6386                == PackageManager.PERMISSION_GRANTED) {
6387            return;
6388        }
6389
6390        String msg = "Permission Denial: " + func + " from pid="
6391                + Binder.getCallingPid()
6392                + ", uid=" + Binder.getCallingUid()
6393                + " requires " + permission;
6394        Slog.w(TAG, msg);
6395        throw new SecurityException(msg);
6396    }
6397
6398    /**
6399     * Determine if UID is holding permissions required to access {@link Uri} in
6400     * the given {@link ProviderInfo}. Final permission checking is always done
6401     * in {@link ContentProvider}.
6402     */
6403    private final boolean checkHoldingPermissionsLocked(
6404            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6405        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6406                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6407        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6408            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6409                    != PERMISSION_GRANTED) {
6410                return false;
6411            }
6412        }
6413        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6414    }
6415
6416    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6417            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6418        if (pi.applicationInfo.uid == uid) {
6419            return true;
6420        } else if (!pi.exported) {
6421            return false;
6422        }
6423
6424        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6425        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6426        try {
6427            // check if target holds top-level <provider> permissions
6428            if (!readMet && pi.readPermission != null && considerUidPermissions
6429                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6430                readMet = true;
6431            }
6432            if (!writeMet && pi.writePermission != null && considerUidPermissions
6433                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6434                writeMet = true;
6435            }
6436
6437            // track if unprotected read/write is allowed; any denied
6438            // <path-permission> below removes this ability
6439            boolean allowDefaultRead = pi.readPermission == null;
6440            boolean allowDefaultWrite = pi.writePermission == null;
6441
6442            // check if target holds any <path-permission> that match uri
6443            final PathPermission[] pps = pi.pathPermissions;
6444            if (pps != null) {
6445                final String path = grantUri.uri.getPath();
6446                int i = pps.length;
6447                while (i > 0 && (!readMet || !writeMet)) {
6448                    i--;
6449                    PathPermission pp = pps[i];
6450                    if (pp.match(path)) {
6451                        if (!readMet) {
6452                            final String pprperm = pp.getReadPermission();
6453                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6454                                    + pprperm + " for " + pp.getPath()
6455                                    + ": match=" + pp.match(path)
6456                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6457                            if (pprperm != null) {
6458                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6459                                        == PERMISSION_GRANTED) {
6460                                    readMet = true;
6461                                } else {
6462                                    allowDefaultRead = false;
6463                                }
6464                            }
6465                        }
6466                        if (!writeMet) {
6467                            final String ppwperm = pp.getWritePermission();
6468                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6469                                    + ppwperm + " for " + pp.getPath()
6470                                    + ": match=" + pp.match(path)
6471                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6472                            if (ppwperm != null) {
6473                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6474                                        == PERMISSION_GRANTED) {
6475                                    writeMet = true;
6476                                } else {
6477                                    allowDefaultWrite = false;
6478                                }
6479                            }
6480                        }
6481                    }
6482                }
6483            }
6484
6485            // grant unprotected <provider> read/write, if not blocked by
6486            // <path-permission> above
6487            if (allowDefaultRead) readMet = true;
6488            if (allowDefaultWrite) writeMet = true;
6489
6490        } catch (RemoteException e) {
6491            return false;
6492        }
6493
6494        return readMet && writeMet;
6495    }
6496
6497    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6498        ProviderInfo pi = null;
6499        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6500        if (cpr != null) {
6501            pi = cpr.info;
6502        } else {
6503            try {
6504                pi = AppGlobals.getPackageManager().resolveContentProvider(
6505                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6506            } catch (RemoteException ex) {
6507            }
6508        }
6509        return pi;
6510    }
6511
6512    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6513        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6514        if (targetUris != null) {
6515            return targetUris.get(grantUri);
6516        }
6517        return null;
6518    }
6519
6520    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6521            String targetPkg, int targetUid, GrantUri grantUri) {
6522        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6523        if (targetUris == null) {
6524            targetUris = Maps.newArrayMap();
6525            mGrantedUriPermissions.put(targetUid, targetUris);
6526        }
6527
6528        UriPermission perm = targetUris.get(grantUri);
6529        if (perm == null) {
6530            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6531            targetUris.put(grantUri, perm);
6532        }
6533
6534        return perm;
6535    }
6536
6537    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6538            final int modeFlags) {
6539        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6540        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6541                : UriPermission.STRENGTH_OWNED;
6542
6543        // Root gets to do everything.
6544        if (uid == 0) {
6545            return true;
6546        }
6547
6548        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6549        if (perms == null) return false;
6550
6551        // First look for exact match
6552        final UriPermission exactPerm = perms.get(grantUri);
6553        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6554            return true;
6555        }
6556
6557        // No exact match, look for prefixes
6558        final int N = perms.size();
6559        for (int i = 0; i < N; i++) {
6560            final UriPermission perm = perms.valueAt(i);
6561            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6562                    && perm.getStrength(modeFlags) >= minStrength) {
6563                return true;
6564            }
6565        }
6566
6567        return false;
6568    }
6569
6570    @Override
6571    public int checkUriPermission(Uri uri, int pid, int uid,
6572            final int modeFlags, int userId) {
6573        enforceNotIsolatedCaller("checkUriPermission");
6574
6575        // Another redirected-binder-call permissions check as in
6576        // {@link checkComponentPermission}.
6577        Identity tlsIdentity = sCallerIdentity.get();
6578        if (tlsIdentity != null) {
6579            uid = tlsIdentity.uid;
6580            pid = tlsIdentity.pid;
6581        }
6582
6583        // Our own process gets to do everything.
6584        if (pid == MY_PID) {
6585            return PackageManager.PERMISSION_GRANTED;
6586        }
6587        synchronized (this) {
6588            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6589                    ? PackageManager.PERMISSION_GRANTED
6590                    : PackageManager.PERMISSION_DENIED;
6591        }
6592    }
6593
6594    /**
6595     * Check if the targetPkg can be granted permission to access uri by
6596     * the callingUid using the given modeFlags.  Throws a security exception
6597     * if callingUid is not allowed to do this.  Returns the uid of the target
6598     * if the URI permission grant should be performed; returns -1 if it is not
6599     * needed (for example targetPkg already has permission to access the URI).
6600     * If you already know the uid of the target, you can supply it in
6601     * lastTargetUid else set that to -1.
6602     */
6603    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6604            final int modeFlags, int lastTargetUid) {
6605        if (!Intent.isAccessUriMode(modeFlags)) {
6606            return -1;
6607        }
6608
6609        if (targetPkg != null) {
6610            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6611                    "Checking grant " + targetPkg + " permission to " + grantUri);
6612        }
6613
6614        final IPackageManager pm = AppGlobals.getPackageManager();
6615
6616        // If this is not a content: uri, we can't do anything with it.
6617        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6618            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6619                    "Can't grant URI permission for non-content URI: " + grantUri);
6620            return -1;
6621        }
6622
6623        final String authority = grantUri.uri.getAuthority();
6624        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6625        if (pi == null) {
6626            Slog.w(TAG, "No content provider found for permission check: " +
6627                    grantUri.uri.toSafeString());
6628            return -1;
6629        }
6630
6631        int targetUid = lastTargetUid;
6632        if (targetUid < 0 && targetPkg != null) {
6633            try {
6634                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6635                if (targetUid < 0) {
6636                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6637                            "Can't grant URI permission no uid for: " + targetPkg);
6638                    return -1;
6639                }
6640            } catch (RemoteException ex) {
6641                return -1;
6642            }
6643        }
6644
6645        if (targetUid >= 0) {
6646            // First...  does the target actually need this permission?
6647            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6648                // No need to grant the target this permission.
6649                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6650                        "Target " + targetPkg + " already has full permission to " + grantUri);
6651                return -1;
6652            }
6653        } else {
6654            // First...  there is no target package, so can anyone access it?
6655            boolean allowed = pi.exported;
6656            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6657                if (pi.readPermission != null) {
6658                    allowed = false;
6659                }
6660            }
6661            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6662                if (pi.writePermission != null) {
6663                    allowed = false;
6664                }
6665            }
6666            if (allowed) {
6667                return -1;
6668            }
6669        }
6670
6671        /* There is a special cross user grant if:
6672         * - The target is on another user.
6673         * - Apps on the current user can access the uri without any uid permissions.
6674         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6675         * grant uri permissions.
6676         */
6677        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6678                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6679                modeFlags, false /*without considering the uid permissions*/);
6680
6681        // Second...  is the provider allowing granting of URI permissions?
6682        if (!specialCrossUserGrant) {
6683            if (!pi.grantUriPermissions) {
6684                throw new SecurityException("Provider " + pi.packageName
6685                        + "/" + pi.name
6686                        + " does not allow granting of Uri permissions (uri "
6687                        + grantUri + ")");
6688            }
6689            if (pi.uriPermissionPatterns != null) {
6690                final int N = pi.uriPermissionPatterns.length;
6691                boolean allowed = false;
6692                for (int i=0; i<N; i++) {
6693                    if (pi.uriPermissionPatterns[i] != null
6694                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6695                        allowed = true;
6696                        break;
6697                    }
6698                }
6699                if (!allowed) {
6700                    throw new SecurityException("Provider " + pi.packageName
6701                            + "/" + pi.name
6702                            + " does not allow granting of permission to path of Uri "
6703                            + grantUri);
6704                }
6705            }
6706        }
6707
6708        // Third...  does the caller itself have permission to access
6709        // this uri?
6710        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6711            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6712                // Require they hold a strong enough Uri permission
6713                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6714                    throw new SecurityException("Uid " + callingUid
6715                            + " does not have permission to uri " + grantUri);
6716                }
6717            }
6718        }
6719        return targetUid;
6720    }
6721
6722    @Override
6723    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6724            final int modeFlags, int userId) {
6725        enforceNotIsolatedCaller("checkGrantUriPermission");
6726        synchronized(this) {
6727            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6728                    new GrantUri(userId, uri, false), modeFlags, -1);
6729        }
6730    }
6731
6732    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6733            final int modeFlags, UriPermissionOwner owner) {
6734        if (!Intent.isAccessUriMode(modeFlags)) {
6735            return;
6736        }
6737
6738        // So here we are: the caller has the assumed permission
6739        // to the uri, and the target doesn't.  Let's now give this to
6740        // the target.
6741
6742        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6743                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6744
6745        final String authority = grantUri.uri.getAuthority();
6746        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6747        if (pi == null) {
6748            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6749            return;
6750        }
6751
6752        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6753            grantUri.prefix = true;
6754        }
6755        final UriPermission perm = findOrCreateUriPermissionLocked(
6756                pi.packageName, targetPkg, targetUid, grantUri);
6757        perm.grantModes(modeFlags, owner);
6758    }
6759
6760    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6761            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
6762        if (targetPkg == null) {
6763            throw new NullPointerException("targetPkg");
6764        }
6765        int targetUid;
6766        final IPackageManager pm = AppGlobals.getPackageManager();
6767        try {
6768            targetUid = pm.getPackageUid(targetPkg, targetUserId);
6769        } catch (RemoteException ex) {
6770            return;
6771        }
6772
6773        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6774                targetUid);
6775        if (targetUid < 0) {
6776            return;
6777        }
6778
6779        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6780                owner);
6781    }
6782
6783    static class NeededUriGrants extends ArrayList<GrantUri> {
6784        final String targetPkg;
6785        final int targetUid;
6786        final int flags;
6787
6788        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6789            this.targetPkg = targetPkg;
6790            this.targetUid = targetUid;
6791            this.flags = flags;
6792        }
6793    }
6794
6795    /**
6796     * Like checkGrantUriPermissionLocked, but takes an Intent.
6797     */
6798    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6799            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6800        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6801                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6802                + " clip=" + (intent != null ? intent.getClipData() : null)
6803                + " from " + intent + "; flags=0x"
6804                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6805
6806        if (targetPkg == null) {
6807            throw new NullPointerException("targetPkg");
6808        }
6809
6810        if (intent == null) {
6811            return null;
6812        }
6813        Uri data = intent.getData();
6814        ClipData clip = intent.getClipData();
6815        if (data == null && clip == null) {
6816            return null;
6817        }
6818        // Default userId for uris in the intent (if they don't specify it themselves)
6819        int contentUserHint = intent.getContentUserHint();
6820        if (contentUserHint == UserHandle.USER_CURRENT) {
6821            contentUserHint = UserHandle.getUserId(callingUid);
6822        }
6823        final IPackageManager pm = AppGlobals.getPackageManager();
6824        int targetUid;
6825        if (needed != null) {
6826            targetUid = needed.targetUid;
6827        } else {
6828            try {
6829                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6830            } catch (RemoteException ex) {
6831                return null;
6832            }
6833            if (targetUid < 0) {
6834                if (DEBUG_URI_PERMISSION) {
6835                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6836                            + " on user " + targetUserId);
6837                }
6838                return null;
6839            }
6840        }
6841        if (data != null) {
6842            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
6843            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6844                    targetUid);
6845            if (targetUid > 0) {
6846                if (needed == null) {
6847                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6848                }
6849                needed.add(grantUri);
6850            }
6851        }
6852        if (clip != null) {
6853            for (int i=0; i<clip.getItemCount(); i++) {
6854                Uri uri = clip.getItemAt(i).getUri();
6855                if (uri != null) {
6856                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
6857                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6858                            targetUid);
6859                    if (targetUid > 0) {
6860                        if (needed == null) {
6861                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6862                        }
6863                        needed.add(grantUri);
6864                    }
6865                } else {
6866                    Intent clipIntent = clip.getItemAt(i).getIntent();
6867                    if (clipIntent != null) {
6868                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6869                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6870                        if (newNeeded != null) {
6871                            needed = newNeeded;
6872                        }
6873                    }
6874                }
6875            }
6876        }
6877
6878        return needed;
6879    }
6880
6881    /**
6882     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6883     */
6884    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6885            UriPermissionOwner owner) {
6886        if (needed != null) {
6887            for (int i=0; i<needed.size(); i++) {
6888                GrantUri grantUri = needed.get(i);
6889                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6890                        grantUri, needed.flags, owner);
6891            }
6892        }
6893    }
6894
6895    void grantUriPermissionFromIntentLocked(int callingUid,
6896            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6897        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6898                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6899        if (needed == null) {
6900            return;
6901        }
6902
6903        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6904    }
6905
6906    @Override
6907    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6908            final int modeFlags, int userId) {
6909        enforceNotIsolatedCaller("grantUriPermission");
6910        GrantUri grantUri = new GrantUri(userId, uri, false);
6911        synchronized(this) {
6912            final ProcessRecord r = getRecordForAppLocked(caller);
6913            if (r == null) {
6914                throw new SecurityException("Unable to find app for caller "
6915                        + caller
6916                        + " when granting permission to uri " + grantUri);
6917            }
6918            if (targetPkg == null) {
6919                throw new IllegalArgumentException("null target");
6920            }
6921            if (grantUri == null) {
6922                throw new IllegalArgumentException("null uri");
6923            }
6924
6925            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6926                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6927                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6928                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6929
6930            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
6931                    UserHandle.getUserId(r.uid));
6932        }
6933    }
6934
6935    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6936        if (perm.modeFlags == 0) {
6937            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6938                    perm.targetUid);
6939            if (perms != null) {
6940                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6941                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6942
6943                perms.remove(perm.uri);
6944                if (perms.isEmpty()) {
6945                    mGrantedUriPermissions.remove(perm.targetUid);
6946                }
6947            }
6948        }
6949    }
6950
6951    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6952        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6953
6954        final IPackageManager pm = AppGlobals.getPackageManager();
6955        final String authority = grantUri.uri.getAuthority();
6956        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6957        if (pi == null) {
6958            Slog.w(TAG, "No content provider found for permission revoke: "
6959                    + grantUri.toSafeString());
6960            return;
6961        }
6962
6963        // Does the caller have this permission on the URI?
6964        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6965            // Right now, if you are not the original owner of the permission,
6966            // you are not allowed to revoke it.
6967            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6968                throw new SecurityException("Uid " + callingUid
6969                        + " does not have permission to uri " + grantUri);
6970            //}
6971        }
6972
6973        boolean persistChanged = false;
6974
6975        // Go through all of the permissions and remove any that match.
6976        int N = mGrantedUriPermissions.size();
6977        for (int i = 0; i < N; i++) {
6978            final int targetUid = mGrantedUriPermissions.keyAt(i);
6979            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6980
6981            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6982                final UriPermission perm = it.next();
6983                if (perm.uri.sourceUserId == grantUri.sourceUserId
6984                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6985                    if (DEBUG_URI_PERMISSION)
6986                        Slog.v(TAG,
6987                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6988                    persistChanged |= perm.revokeModes(
6989                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6990                    if (perm.modeFlags == 0) {
6991                        it.remove();
6992                    }
6993                }
6994            }
6995
6996            if (perms.isEmpty()) {
6997                mGrantedUriPermissions.remove(targetUid);
6998                N--;
6999                i--;
7000            }
7001        }
7002
7003        if (persistChanged) {
7004            schedulePersistUriGrants();
7005        }
7006    }
7007
7008    @Override
7009    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7010            int userId) {
7011        enforceNotIsolatedCaller("revokeUriPermission");
7012        synchronized(this) {
7013            final ProcessRecord r = getRecordForAppLocked(caller);
7014            if (r == null) {
7015                throw new SecurityException("Unable to find app for caller "
7016                        + caller
7017                        + " when revoking permission to uri " + uri);
7018            }
7019            if (uri == null) {
7020                Slog.w(TAG, "revokeUriPermission: null uri");
7021                return;
7022            }
7023
7024            if (!Intent.isAccessUriMode(modeFlags)) {
7025                return;
7026            }
7027
7028            final IPackageManager pm = AppGlobals.getPackageManager();
7029            final String authority = uri.getAuthority();
7030            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7031            if (pi == null) {
7032                Slog.w(TAG, "No content provider found for permission revoke: "
7033                        + uri.toSafeString());
7034                return;
7035            }
7036
7037            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7038        }
7039    }
7040
7041    /**
7042     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7043     * given package.
7044     *
7045     * @param packageName Package name to match, or {@code null} to apply to all
7046     *            packages.
7047     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7048     *            to all users.
7049     * @param persistable If persistable grants should be removed.
7050     */
7051    private void removeUriPermissionsForPackageLocked(
7052            String packageName, int userHandle, boolean persistable) {
7053        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7054            throw new IllegalArgumentException("Must narrow by either package or user");
7055        }
7056
7057        boolean persistChanged = false;
7058
7059        int N = mGrantedUriPermissions.size();
7060        for (int i = 0; i < N; i++) {
7061            final int targetUid = mGrantedUriPermissions.keyAt(i);
7062            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7063
7064            // Only inspect grants matching user
7065            if (userHandle == UserHandle.USER_ALL
7066                    || userHandle == UserHandle.getUserId(targetUid)) {
7067                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7068                    final UriPermission perm = it.next();
7069
7070                    // Only inspect grants matching package
7071                    if (packageName == null || perm.sourcePkg.equals(packageName)
7072                            || perm.targetPkg.equals(packageName)) {
7073                        persistChanged |= perm.revokeModes(
7074                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7075
7076                        // Only remove when no modes remain; any persisted grants
7077                        // will keep this alive.
7078                        if (perm.modeFlags == 0) {
7079                            it.remove();
7080                        }
7081                    }
7082                }
7083
7084                if (perms.isEmpty()) {
7085                    mGrantedUriPermissions.remove(targetUid);
7086                    N--;
7087                    i--;
7088                }
7089            }
7090        }
7091
7092        if (persistChanged) {
7093            schedulePersistUriGrants();
7094        }
7095    }
7096
7097    @Override
7098    public IBinder newUriPermissionOwner(String name) {
7099        enforceNotIsolatedCaller("newUriPermissionOwner");
7100        synchronized(this) {
7101            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7102            return owner.getExternalTokenLocked();
7103        }
7104    }
7105
7106    @Override
7107    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7108            final int modeFlags, int sourceUserId, int targetUserId) {
7109        synchronized(this) {
7110            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7111            if (owner == null) {
7112                throw new IllegalArgumentException("Unknown owner: " + token);
7113            }
7114            if (fromUid != Binder.getCallingUid()) {
7115                if (Binder.getCallingUid() != Process.myUid()) {
7116                    // Only system code can grant URI permissions on behalf
7117                    // of other users.
7118                    throw new SecurityException("nice try");
7119                }
7120            }
7121            if (targetPkg == null) {
7122                throw new IllegalArgumentException("null target");
7123            }
7124            if (uri == null) {
7125                throw new IllegalArgumentException("null uri");
7126            }
7127
7128            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7129                    modeFlags, owner, targetUserId);
7130        }
7131    }
7132
7133    @Override
7134    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7135        synchronized(this) {
7136            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7137            if (owner == null) {
7138                throw new IllegalArgumentException("Unknown owner: " + token);
7139            }
7140
7141            if (uri == null) {
7142                owner.removeUriPermissionsLocked(mode);
7143            } else {
7144                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7145            }
7146        }
7147    }
7148
7149    private void schedulePersistUriGrants() {
7150        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7151            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7152                    10 * DateUtils.SECOND_IN_MILLIS);
7153        }
7154    }
7155
7156    private void writeGrantedUriPermissions() {
7157        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7158
7159        // Snapshot permissions so we can persist without lock
7160        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7161        synchronized (this) {
7162            final int size = mGrantedUriPermissions.size();
7163            for (int i = 0; i < size; i++) {
7164                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7165                for (UriPermission perm : perms.values()) {
7166                    if (perm.persistedModeFlags != 0) {
7167                        persist.add(perm.snapshot());
7168                    }
7169                }
7170            }
7171        }
7172
7173        FileOutputStream fos = null;
7174        try {
7175            fos = mGrantFile.startWrite();
7176
7177            XmlSerializer out = new FastXmlSerializer();
7178            out.setOutput(fos, "utf-8");
7179            out.startDocument(null, true);
7180            out.startTag(null, TAG_URI_GRANTS);
7181            for (UriPermission.Snapshot perm : persist) {
7182                out.startTag(null, TAG_URI_GRANT);
7183                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7184                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7185                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7186                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7187                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7188                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7189                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7190                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7191                out.endTag(null, TAG_URI_GRANT);
7192            }
7193            out.endTag(null, TAG_URI_GRANTS);
7194            out.endDocument();
7195
7196            mGrantFile.finishWrite(fos);
7197        } catch (IOException e) {
7198            if (fos != null) {
7199                mGrantFile.failWrite(fos);
7200            }
7201        }
7202    }
7203
7204    private void readGrantedUriPermissionsLocked() {
7205        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7206
7207        final long now = System.currentTimeMillis();
7208
7209        FileInputStream fis = null;
7210        try {
7211            fis = mGrantFile.openRead();
7212            final XmlPullParser in = Xml.newPullParser();
7213            in.setInput(fis, null);
7214
7215            int type;
7216            while ((type = in.next()) != END_DOCUMENT) {
7217                final String tag = in.getName();
7218                if (type == START_TAG) {
7219                    if (TAG_URI_GRANT.equals(tag)) {
7220                        final int sourceUserId;
7221                        final int targetUserId;
7222                        final int userHandle = readIntAttribute(in,
7223                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7224                        if (userHandle != UserHandle.USER_NULL) {
7225                            // For backwards compatibility.
7226                            sourceUserId = userHandle;
7227                            targetUserId = userHandle;
7228                        } else {
7229                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7230                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7231                        }
7232                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7233                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7234                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7235                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7236                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7237                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7238
7239                        // Sanity check that provider still belongs to source package
7240                        final ProviderInfo pi = getProviderInfoLocked(
7241                                uri.getAuthority(), sourceUserId);
7242                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7243                            int targetUid = -1;
7244                            try {
7245                                targetUid = AppGlobals.getPackageManager()
7246                                        .getPackageUid(targetPkg, targetUserId);
7247                            } catch (RemoteException e) {
7248                            }
7249                            if (targetUid != -1) {
7250                                final UriPermission perm = findOrCreateUriPermissionLocked(
7251                                        sourcePkg, targetPkg, targetUid,
7252                                        new GrantUri(sourceUserId, uri, prefix));
7253                                perm.initPersistedModes(modeFlags, createdTime);
7254                            }
7255                        } else {
7256                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7257                                    + " but instead found " + pi);
7258                        }
7259                    }
7260                }
7261            }
7262        } catch (FileNotFoundException e) {
7263            // Missing grants is okay
7264        } catch (IOException e) {
7265            Log.wtf(TAG, "Failed reading Uri grants", e);
7266        } catch (XmlPullParserException e) {
7267            Log.wtf(TAG, "Failed reading Uri grants", e);
7268        } finally {
7269            IoUtils.closeQuietly(fis);
7270        }
7271    }
7272
7273    @Override
7274    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7275        enforceNotIsolatedCaller("takePersistableUriPermission");
7276
7277        Preconditions.checkFlagsArgument(modeFlags,
7278                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7279
7280        synchronized (this) {
7281            final int callingUid = Binder.getCallingUid();
7282            boolean persistChanged = false;
7283            GrantUri grantUri = new GrantUri(userId, uri, false);
7284
7285            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7286                    new GrantUri(userId, uri, false));
7287            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7288                    new GrantUri(userId, uri, true));
7289
7290            final boolean exactValid = (exactPerm != null)
7291                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7292            final boolean prefixValid = (prefixPerm != null)
7293                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7294
7295            if (!(exactValid || prefixValid)) {
7296                throw new SecurityException("No persistable permission grants found for UID "
7297                        + callingUid + " and Uri " + grantUri.toSafeString());
7298            }
7299
7300            if (exactValid) {
7301                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7302            }
7303            if (prefixValid) {
7304                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7305            }
7306
7307            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7308
7309            if (persistChanged) {
7310                schedulePersistUriGrants();
7311            }
7312        }
7313    }
7314
7315    @Override
7316    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7317        enforceNotIsolatedCaller("releasePersistableUriPermission");
7318
7319        Preconditions.checkFlagsArgument(modeFlags,
7320                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7321
7322        synchronized (this) {
7323            final int callingUid = Binder.getCallingUid();
7324            boolean persistChanged = false;
7325
7326            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7327                    new GrantUri(userId, uri, false));
7328            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7329                    new GrantUri(userId, uri, true));
7330            if (exactPerm == null && prefixPerm == null) {
7331                throw new SecurityException("No permission grants found for UID " + callingUid
7332                        + " and Uri " + uri.toSafeString());
7333            }
7334
7335            if (exactPerm != null) {
7336                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7337                removeUriPermissionIfNeededLocked(exactPerm);
7338            }
7339            if (prefixPerm != null) {
7340                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7341                removeUriPermissionIfNeededLocked(prefixPerm);
7342            }
7343
7344            if (persistChanged) {
7345                schedulePersistUriGrants();
7346            }
7347        }
7348    }
7349
7350    /**
7351     * Prune any older {@link UriPermission} for the given UID until outstanding
7352     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7353     *
7354     * @return if any mutations occured that require persisting.
7355     */
7356    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7357        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7358        if (perms == null) return false;
7359        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7360
7361        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7362        for (UriPermission perm : perms.values()) {
7363            if (perm.persistedModeFlags != 0) {
7364                persisted.add(perm);
7365            }
7366        }
7367
7368        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7369        if (trimCount <= 0) return false;
7370
7371        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7372        for (int i = 0; i < trimCount; i++) {
7373            final UriPermission perm = persisted.get(i);
7374
7375            if (DEBUG_URI_PERMISSION) {
7376                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7377            }
7378
7379            perm.releasePersistableModes(~0);
7380            removeUriPermissionIfNeededLocked(perm);
7381        }
7382
7383        return true;
7384    }
7385
7386    @Override
7387    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7388            String packageName, boolean incoming) {
7389        enforceNotIsolatedCaller("getPersistedUriPermissions");
7390        Preconditions.checkNotNull(packageName, "packageName");
7391
7392        final int callingUid = Binder.getCallingUid();
7393        final IPackageManager pm = AppGlobals.getPackageManager();
7394        try {
7395            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7396            if (packageUid != callingUid) {
7397                throw new SecurityException(
7398                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7399            }
7400        } catch (RemoteException e) {
7401            throw new SecurityException("Failed to verify package name ownership");
7402        }
7403
7404        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7405        synchronized (this) {
7406            if (incoming) {
7407                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7408                        callingUid);
7409                if (perms == null) {
7410                    Slog.w(TAG, "No permission grants found for " + packageName);
7411                } else {
7412                    for (UriPermission perm : perms.values()) {
7413                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7414                            result.add(perm.buildPersistedPublicApiObject());
7415                        }
7416                    }
7417                }
7418            } else {
7419                final int size = mGrantedUriPermissions.size();
7420                for (int i = 0; i < size; i++) {
7421                    final ArrayMap<GrantUri, UriPermission> perms =
7422                            mGrantedUriPermissions.valueAt(i);
7423                    for (UriPermission perm : perms.values()) {
7424                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7425                            result.add(perm.buildPersistedPublicApiObject());
7426                        }
7427                    }
7428                }
7429            }
7430        }
7431        return new ParceledListSlice<android.content.UriPermission>(result);
7432    }
7433
7434    @Override
7435    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7436        synchronized (this) {
7437            ProcessRecord app =
7438                who != null ? getRecordForAppLocked(who) : null;
7439            if (app == null) return;
7440
7441            Message msg = Message.obtain();
7442            msg.what = WAIT_FOR_DEBUGGER_MSG;
7443            msg.obj = app;
7444            msg.arg1 = waiting ? 1 : 0;
7445            mHandler.sendMessage(msg);
7446        }
7447    }
7448
7449    @Override
7450    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7451        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7452        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7453        outInfo.availMem = Process.getFreeMemory();
7454        outInfo.totalMem = Process.getTotalMemory();
7455        outInfo.threshold = homeAppMem;
7456        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7457        outInfo.hiddenAppThreshold = cachedAppMem;
7458        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7459                ProcessList.SERVICE_ADJ);
7460        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7461                ProcessList.VISIBLE_APP_ADJ);
7462        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7463                ProcessList.FOREGROUND_APP_ADJ);
7464    }
7465
7466    // =========================================================
7467    // TASK MANAGEMENT
7468    // =========================================================
7469
7470    @Override
7471    public List<IAppTask> getAppTasks() {
7472        final PackageManager pm = mContext.getPackageManager();
7473        int callingUid = Binder.getCallingUid();
7474        long ident = Binder.clearCallingIdentity();
7475
7476        // Compose the list of packages for this id to test against
7477        HashSet<String> packages = new HashSet<String>();
7478        String[] uidPackages = pm.getPackagesForUid(callingUid);
7479        for (int i = 0; i < uidPackages.length; i++) {
7480            packages.add(uidPackages[i]);
7481        }
7482
7483        synchronized(this) {
7484            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7485            try {
7486                if (localLOGV) Slog.v(TAG, "getAppTasks");
7487
7488                final int N = mRecentTasks.size();
7489                for (int i = 0; i < N; i++) {
7490                    TaskRecord tr = mRecentTasks.get(i);
7491                    // Skip tasks that do not match the package name
7492                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
7493                        ActivityManager.RecentTaskInfo taskInfo =
7494                                createRecentTaskInfoFromTaskRecord(tr);
7495                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7496                        list.add(taskImpl);
7497                    }
7498                }
7499            } finally {
7500                Binder.restoreCallingIdentity(ident);
7501            }
7502            return list;
7503        }
7504    }
7505
7506    @Override
7507    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7508        final int callingUid = Binder.getCallingUid();
7509        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7510
7511        synchronized(this) {
7512            if (localLOGV) Slog.v(
7513                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7514
7515            final boolean allowed = checkCallingPermission(
7516                    android.Manifest.permission.GET_TASKS)
7517                    == PackageManager.PERMISSION_GRANTED;
7518            if (!allowed) {
7519                Slog.w(TAG, "getTasks: caller " + callingUid
7520                        + " does not hold GET_TASKS; limiting output");
7521            }
7522
7523            // TODO: Improve with MRU list from all ActivityStacks.
7524            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7525        }
7526
7527        return list;
7528    }
7529
7530    TaskRecord getMostRecentTask() {
7531        return mRecentTasks.get(0);
7532    }
7533
7534    /**
7535     * Creates a new RecentTaskInfo from a TaskRecord.
7536     */
7537    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7538        // Update the task description to reflect any changes in the task stack
7539        tr.updateTaskDescription();
7540
7541        // Compose the recent task info
7542        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7543        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7544        rti.persistentId = tr.taskId;
7545        rti.baseIntent = new Intent(tr.getBaseIntent());
7546        rti.origActivity = tr.origActivity;
7547        rti.description = tr.lastDescription;
7548        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7549        rti.userId = tr.userId;
7550        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7551        rti.firstActiveTime = tr.firstActiveTime;
7552        rti.lastActiveTime = tr.lastActiveTime;
7553        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7554        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
7555        return rti;
7556    }
7557
7558    @Override
7559    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7560        final int callingUid = Binder.getCallingUid();
7561        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7562                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7563
7564        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7565        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7566        synchronized (this) {
7567            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
7568                    == PackageManager.PERMISSION_GRANTED;
7569            if (!allowed) {
7570                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7571                        + " does not hold GET_TASKS; limiting output");
7572            }
7573            final boolean detailed = checkCallingPermission(
7574                    android.Manifest.permission.GET_DETAILED_TASKS)
7575                    == PackageManager.PERMISSION_GRANTED;
7576
7577            IPackageManager pm = AppGlobals.getPackageManager();
7578
7579            final int N = mRecentTasks.size();
7580            ArrayList<ActivityManager.RecentTaskInfo> res
7581                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7582                            maxNum < N ? maxNum : N);
7583
7584            final Set<Integer> includedUsers;
7585            if (includeProfiles) {
7586                includedUsers = getProfileIdsLocked(userId);
7587            } else {
7588                includedUsers = new HashSet<Integer>();
7589            }
7590            includedUsers.add(Integer.valueOf(userId));
7591
7592            // Regroup affiliated tasks together.
7593            for (int i = 0; i < N; ) {
7594                TaskRecord task = mRecentTasks.remove(i);
7595                if (mTmpRecents.contains(task)) {
7596                    continue;
7597                }
7598                int affiliatedTaskId = task.mAffiliatedTaskId;
7599                while (true) {
7600                    TaskRecord next = task.mNextAffiliate;
7601                    if (next == null) {
7602                        break;
7603                    }
7604                    if (next.mAffiliatedTaskId != affiliatedTaskId) {
7605                        Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
7606                                next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
7607                        task.setNextAffiliate(null);
7608                        if (next.mPrevAffiliate == task) {
7609                            next.setPrevAffiliate(null);
7610                        }
7611                        break;
7612                    }
7613                    if (next.mPrevAffiliate != task) {
7614                        Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
7615                                next.mPrevAffiliate + " task=" + task);
7616                        next.setPrevAffiliate(null);
7617                        break;
7618                    }
7619                    if (!mRecentTasks.contains(next)) {
7620                        Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
7621                        task.setNextAffiliate(null);
7622                        if (next.mPrevAffiliate == task) {
7623                            next.setPrevAffiliate(null);
7624                        }
7625                        break;
7626                    }
7627                    task = next;
7628                }
7629                // task is now the end of the list
7630                do {
7631                    mRecentTasks.remove(task);
7632                    mRecentTasks.add(i++, task);
7633                    mTmpRecents.add(task);
7634                } while ((task = task.mPrevAffiliate) != null);
7635            }
7636            mTmpRecents.clear();
7637            // mRecentTasks is now in sorted, affiliated order.
7638
7639            for (int i=0; i<N && maxNum > 0; i++) {
7640                TaskRecord tr = mRecentTasks.get(i);
7641                // Only add calling user or related users recent tasks
7642                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7643
7644                // Return the entry if desired by the caller.  We always return
7645                // the first entry, because callers always expect this to be the
7646                // foreground app.  We may filter others if the caller has
7647                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7648                // we should exclude the entry.
7649
7650                if (i == 0
7651                        || withExcluded
7652                        || (tr.intent == null)
7653                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7654                                == 0)) {
7655                    if (!allowed) {
7656                        // If the caller doesn't have the GET_TASKS permission, then only
7657                        // allow them to see a small subset of tasks -- their own and home.
7658                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7659                            continue;
7660                        }
7661                    }
7662                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
7663                        // Don't include auto remove tasks that are finished or finishing.
7664                        continue;
7665                    }
7666
7667                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7668                    if (!detailed) {
7669                        rti.baseIntent.replaceExtras((Bundle)null);
7670                    }
7671
7672                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7673                        // Check whether this activity is currently available.
7674                        try {
7675                            if (rti.origActivity != null) {
7676                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7677                                        == null) {
7678                                    continue;
7679                                }
7680                            } else if (rti.baseIntent != null) {
7681                                if (pm.queryIntentActivities(rti.baseIntent,
7682                                        null, 0, userId) == null) {
7683                                    continue;
7684                                }
7685                            }
7686                        } catch (RemoteException e) {
7687                            // Will never happen.
7688                        }
7689                    }
7690
7691                    res.add(rti);
7692                    maxNum--;
7693                }
7694            }
7695            return res;
7696        }
7697    }
7698
7699    private TaskRecord recentTaskForIdLocked(int id) {
7700        final int N = mRecentTasks.size();
7701            for (int i=0; i<N; i++) {
7702                TaskRecord tr = mRecentTasks.get(i);
7703                if (tr.taskId == id) {
7704                    return tr;
7705                }
7706            }
7707            return null;
7708    }
7709
7710    @Override
7711    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7712        synchronized (this) {
7713            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7714                    "getTaskThumbnail()");
7715            TaskRecord tr = recentTaskForIdLocked(id);
7716            if (tr != null) {
7717                return tr.getTaskThumbnailLocked();
7718            }
7719        }
7720        return null;
7721    }
7722
7723    @Override
7724    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7725        synchronized (this) {
7726            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7727            if (r != null) {
7728                r.taskDescription = td;
7729                r.task.updateTaskDescription();
7730            }
7731        }
7732    }
7733
7734    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7735        if (!pr.killedByAm) {
7736            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7737            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7738                    pr.processName, pr.setAdj, reason);
7739            pr.killedByAm = true;
7740            Process.killProcessQuiet(pr.pid);
7741            Process.killProcessGroup(pr.info.uid, pr.pid);
7742        }
7743    }
7744
7745    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7746        tr.disposeThumbnail();
7747        mRecentTasks.remove(tr);
7748        tr.closeRecentsChain();
7749        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7750        Intent baseIntent = new Intent(
7751                tr.intent != null ? tr.intent : tr.affinityIntent);
7752        ComponentName component = baseIntent.getComponent();
7753        if (component == null) {
7754            Slog.w(TAG, "Now component for base intent of task: " + tr);
7755            return;
7756        }
7757
7758        // Find any running services associated with this app.
7759        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7760
7761        if (killProcesses) {
7762            // Find any running processes associated with this app.
7763            final String pkg = component.getPackageName();
7764            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7765            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7766            for (int i=0; i<pmap.size(); i++) {
7767                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7768                for (int j=0; j<uids.size(); j++) {
7769                    ProcessRecord proc = uids.valueAt(j);
7770                    if (proc.userId != tr.userId) {
7771                        continue;
7772                    }
7773                    if (!proc.pkgList.containsKey(pkg)) {
7774                        continue;
7775                    }
7776                    procs.add(proc);
7777                }
7778            }
7779
7780            // Kill the running processes.
7781            for (int i=0; i<procs.size(); i++) {
7782                ProcessRecord pr = procs.get(i);
7783                if (pr == mHomeProcess) {
7784                    // Don't kill the home process along with tasks from the same package.
7785                    continue;
7786                }
7787                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7788                    killUnneededProcessLocked(pr, "remove task");
7789                } else {
7790                    pr.waitingToKill = "remove task";
7791                }
7792            }
7793        }
7794    }
7795
7796    /**
7797     * Removes the task with the specified task id.
7798     *
7799     * @param taskId Identifier of the task to be removed.
7800     * @param flags Additional operational flags.  May be 0 or
7801     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7802     * @return Returns true if the given task was found and removed.
7803     */
7804    private boolean removeTaskByIdLocked(int taskId, int flags) {
7805        TaskRecord tr = recentTaskForIdLocked(taskId);
7806        if (tr != null) {
7807            tr.removeTaskActivitiesLocked();
7808            cleanUpRemovedTaskLocked(tr, flags);
7809            if (tr.isPersistable) {
7810                notifyTaskPersisterLocked(null, true);
7811            }
7812            return true;
7813        }
7814        return false;
7815    }
7816
7817    @Override
7818    public boolean removeTask(int taskId, int flags) {
7819        synchronized (this) {
7820            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7821                    "removeTask()");
7822            long ident = Binder.clearCallingIdentity();
7823            try {
7824                return removeTaskByIdLocked(taskId, flags);
7825            } finally {
7826                Binder.restoreCallingIdentity(ident);
7827            }
7828        }
7829    }
7830
7831    /**
7832     * TODO: Add mController hook
7833     */
7834    @Override
7835    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7836        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7837                "moveTaskToFront()");
7838
7839        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7840        synchronized(this) {
7841            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7842                    Binder.getCallingUid(), "Task to front")) {
7843                ActivityOptions.abort(options);
7844                return;
7845            }
7846            final long origId = Binder.clearCallingIdentity();
7847            try {
7848                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7849                if (task == null) {
7850                    return;
7851                }
7852                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7853                    mStackSupervisor.showLockTaskToast();
7854                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7855                    return;
7856                }
7857                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7858                if (prev != null && prev.isRecentsActivity()) {
7859                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7860                }
7861                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7862            } finally {
7863                Binder.restoreCallingIdentity(origId);
7864            }
7865            ActivityOptions.abort(options);
7866        }
7867    }
7868
7869    @Override
7870    public void moveTaskToBack(int taskId) {
7871        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7872                "moveTaskToBack()");
7873
7874        synchronized(this) {
7875            TaskRecord tr = recentTaskForIdLocked(taskId);
7876            if (tr != null) {
7877                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7878                ActivityStack stack = tr.stack;
7879                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7880                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7881                            Binder.getCallingUid(), "Task to back")) {
7882                        return;
7883                    }
7884                }
7885                final long origId = Binder.clearCallingIdentity();
7886                try {
7887                    stack.moveTaskToBackLocked(taskId, null);
7888                } finally {
7889                    Binder.restoreCallingIdentity(origId);
7890                }
7891            }
7892        }
7893    }
7894
7895    /**
7896     * Moves an activity, and all of the other activities within the same task, to the bottom
7897     * of the history stack.  The activity's order within the task is unchanged.
7898     *
7899     * @param token A reference to the activity we wish to move
7900     * @param nonRoot If false then this only works if the activity is the root
7901     *                of a task; if true it will work for any activity in a task.
7902     * @return Returns true if the move completed, false if not.
7903     */
7904    @Override
7905    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7906        enforceNotIsolatedCaller("moveActivityTaskToBack");
7907        synchronized(this) {
7908            final long origId = Binder.clearCallingIdentity();
7909            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7910            if (taskId >= 0) {
7911                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7912            }
7913            Binder.restoreCallingIdentity(origId);
7914        }
7915        return false;
7916    }
7917
7918    @Override
7919    public void moveTaskBackwards(int task) {
7920        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7921                "moveTaskBackwards()");
7922
7923        synchronized(this) {
7924            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7925                    Binder.getCallingUid(), "Task backwards")) {
7926                return;
7927            }
7928            final long origId = Binder.clearCallingIdentity();
7929            moveTaskBackwardsLocked(task);
7930            Binder.restoreCallingIdentity(origId);
7931        }
7932    }
7933
7934    private final void moveTaskBackwardsLocked(int task) {
7935        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7936    }
7937
7938    @Override
7939    public IBinder getHomeActivityToken() throws RemoteException {
7940        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7941                "getHomeActivityToken()");
7942        synchronized (this) {
7943            return mStackSupervisor.getHomeActivityToken();
7944        }
7945    }
7946
7947    @Override
7948    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7949            IActivityContainerCallback callback) throws RemoteException {
7950        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7951                "createActivityContainer()");
7952        synchronized (this) {
7953            if (parentActivityToken == null) {
7954                throw new IllegalArgumentException("parent token must not be null");
7955            }
7956            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7957            if (r == null) {
7958                return null;
7959            }
7960            if (callback == null) {
7961                throw new IllegalArgumentException("callback must not be null");
7962            }
7963            return mStackSupervisor.createActivityContainer(r, callback);
7964        }
7965    }
7966
7967    @Override
7968    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7969        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7970                "deleteActivityContainer()");
7971        synchronized (this) {
7972            mStackSupervisor.deleteActivityContainer(container);
7973        }
7974    }
7975
7976    @Override
7977    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7978            throws RemoteException {
7979        synchronized (this) {
7980            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7981            if (stack != null) {
7982                return stack.mActivityContainer;
7983            }
7984            return null;
7985        }
7986    }
7987
7988    @Override
7989    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7990        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7991                "moveTaskToStack()");
7992        if (stackId == HOME_STACK_ID) {
7993            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7994                    new RuntimeException("here").fillInStackTrace());
7995        }
7996        synchronized (this) {
7997            long ident = Binder.clearCallingIdentity();
7998            try {
7999                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8000                        + stackId + " toTop=" + toTop);
8001                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8002            } finally {
8003                Binder.restoreCallingIdentity(ident);
8004            }
8005        }
8006    }
8007
8008    @Override
8009    public void resizeStack(int stackBoxId, Rect bounds) {
8010        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8011                "resizeStackBox()");
8012        long ident = Binder.clearCallingIdentity();
8013        try {
8014            mWindowManager.resizeStack(stackBoxId, bounds);
8015        } finally {
8016            Binder.restoreCallingIdentity(ident);
8017        }
8018    }
8019
8020    @Override
8021    public List<StackInfo> getAllStackInfos() {
8022        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8023                "getAllStackInfos()");
8024        long ident = Binder.clearCallingIdentity();
8025        try {
8026            synchronized (this) {
8027                return mStackSupervisor.getAllStackInfosLocked();
8028            }
8029        } finally {
8030            Binder.restoreCallingIdentity(ident);
8031        }
8032    }
8033
8034    @Override
8035    public StackInfo getStackInfo(int stackId) {
8036        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8037                "getStackInfo()");
8038        long ident = Binder.clearCallingIdentity();
8039        try {
8040            synchronized (this) {
8041                return mStackSupervisor.getStackInfoLocked(stackId);
8042            }
8043        } finally {
8044            Binder.restoreCallingIdentity(ident);
8045        }
8046    }
8047
8048    @Override
8049    public boolean isInHomeStack(int taskId) {
8050        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8051                "getStackInfo()");
8052        long ident = Binder.clearCallingIdentity();
8053        try {
8054            synchronized (this) {
8055                TaskRecord tr = recentTaskForIdLocked(taskId);
8056                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8057            }
8058        } finally {
8059            Binder.restoreCallingIdentity(ident);
8060        }
8061    }
8062
8063    @Override
8064    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8065        synchronized(this) {
8066            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8067        }
8068    }
8069
8070    private boolean isLockTaskAuthorized(String pkg) {
8071        final DevicePolicyManager dpm = (DevicePolicyManager)
8072                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8073        try {
8074            int uid = mContext.getPackageManager().getPackageUid(pkg,
8075                    Binder.getCallingUserHandle().getIdentifier());
8076            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8077        } catch (NameNotFoundException e) {
8078            return false;
8079        }
8080    }
8081
8082    void startLockTaskMode(TaskRecord task) {
8083        final String pkg;
8084        synchronized (this) {
8085            pkg = task.intent.getComponent().getPackageName();
8086        }
8087        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8088        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8089            final TaskRecord taskRecord = task;
8090            mHandler.post(new Runnable() {
8091                @Override
8092                public void run() {
8093                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8094                }
8095            });
8096            return;
8097        }
8098        long ident = Binder.clearCallingIdentity();
8099        try {
8100            synchronized (this) {
8101                // Since we lost lock on task, make sure it is still there.
8102                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8103                if (task != null) {
8104                    if (!isSystemInitiated
8105                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8106                        throw new IllegalArgumentException("Invalid task, not in foreground");
8107                    }
8108                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8109                }
8110            }
8111        } finally {
8112            Binder.restoreCallingIdentity(ident);
8113        }
8114    }
8115
8116    @Override
8117    public void startLockTaskMode(int taskId) {
8118        final TaskRecord task;
8119        long ident = Binder.clearCallingIdentity();
8120        try {
8121            synchronized (this) {
8122                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8123            }
8124        } finally {
8125            Binder.restoreCallingIdentity(ident);
8126        }
8127        if (task != null) {
8128            startLockTaskMode(task);
8129        }
8130    }
8131
8132    @Override
8133    public void startLockTaskMode(IBinder token) {
8134        final TaskRecord task;
8135        long ident = Binder.clearCallingIdentity();
8136        try {
8137            synchronized (this) {
8138                final ActivityRecord r = ActivityRecord.forToken(token);
8139                if (r == null) {
8140                    return;
8141                }
8142                task = r.task;
8143            }
8144        } finally {
8145            Binder.restoreCallingIdentity(ident);
8146        }
8147        if (task != null) {
8148            startLockTaskMode(task);
8149        }
8150    }
8151
8152    @Override
8153    public void startLockTaskModeOnCurrent() throws RemoteException {
8154        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8155        ActivityRecord r = null;
8156        synchronized (this) {
8157            r = mStackSupervisor.topRunningActivityLocked();
8158        }
8159        startLockTaskMode(r.task);
8160    }
8161
8162    @Override
8163    public void stopLockTaskMode() {
8164        // Verify that the user matches the package of the intent for the TaskRecord
8165        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8166        // and stopLockTaskMode.
8167        final int callingUid = Binder.getCallingUid();
8168        if (callingUid != Process.SYSTEM_UID) {
8169            try {
8170                String pkg =
8171                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8172                int uid = mContext.getPackageManager().getPackageUid(pkg,
8173                        Binder.getCallingUserHandle().getIdentifier());
8174                if (uid != callingUid) {
8175                    throw new SecurityException("Invalid uid, expected " + uid);
8176                }
8177            } catch (NameNotFoundException e) {
8178                Log.d(TAG, "stopLockTaskMode " + e);
8179                return;
8180            }
8181        }
8182        long ident = Binder.clearCallingIdentity();
8183        try {
8184            Log.d(TAG, "stopLockTaskMode");
8185            // Stop lock task
8186            synchronized (this) {
8187                mStackSupervisor.setLockTaskModeLocked(null, false);
8188            }
8189        } finally {
8190            Binder.restoreCallingIdentity(ident);
8191        }
8192    }
8193
8194    @Override
8195    public void stopLockTaskModeOnCurrent() throws RemoteException {
8196        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8197        long ident = Binder.clearCallingIdentity();
8198        try {
8199            stopLockTaskMode();
8200        } finally {
8201            Binder.restoreCallingIdentity(ident);
8202        }
8203    }
8204
8205    @Override
8206    public boolean isInLockTaskMode() {
8207        synchronized (this) {
8208            return mStackSupervisor.isInLockTaskMode();
8209        }
8210    }
8211
8212    // =========================================================
8213    // CONTENT PROVIDERS
8214    // =========================================================
8215
8216    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8217        List<ProviderInfo> providers = null;
8218        try {
8219            providers = AppGlobals.getPackageManager().
8220                queryContentProviders(app.processName, app.uid,
8221                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8222        } catch (RemoteException ex) {
8223        }
8224        if (DEBUG_MU)
8225            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8226        int userId = app.userId;
8227        if (providers != null) {
8228            int N = providers.size();
8229            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8230            for (int i=0; i<N; i++) {
8231                ProviderInfo cpi =
8232                    (ProviderInfo)providers.get(i);
8233                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8234                        cpi.name, cpi.flags);
8235                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8236                    // This is a singleton provider, but a user besides the
8237                    // default user is asking to initialize a process it runs
8238                    // in...  well, no, it doesn't actually run in this process,
8239                    // it runs in the process of the default user.  Get rid of it.
8240                    providers.remove(i);
8241                    N--;
8242                    i--;
8243                    continue;
8244                }
8245
8246                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8247                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8248                if (cpr == null) {
8249                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8250                    mProviderMap.putProviderByClass(comp, cpr);
8251                }
8252                if (DEBUG_MU)
8253                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8254                app.pubProviders.put(cpi.name, cpr);
8255                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8256                    // Don't add this if it is a platform component that is marked
8257                    // to run in multiple processes, because this is actually
8258                    // part of the framework so doesn't make sense to track as a
8259                    // separate apk in the process.
8260                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8261                            mProcessStats);
8262                }
8263                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8264            }
8265        }
8266        return providers;
8267    }
8268
8269    /**
8270     * Check if {@link ProcessRecord} has a possible chance at accessing the
8271     * given {@link ProviderInfo}. Final permission checking is always done
8272     * in {@link ContentProvider}.
8273     */
8274    private final String checkContentProviderPermissionLocked(
8275            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8276        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8277        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8278        boolean checkedGrants = false;
8279        if (checkUser) {
8280            // Looking for cross-user grants before enforcing the typical cross-users permissions
8281            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8282            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8283                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8284                    return null;
8285                }
8286                checkedGrants = true;
8287            }
8288            userId = handleIncomingUser(callingPid, callingUid, userId,
8289                    false, ALLOW_NON_FULL,
8290                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8291            if (userId != tmpTargetUserId) {
8292                // When we actually went to determine the final targer user ID, this ended
8293                // up different than our initial check for the authority.  This is because
8294                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8295                // SELF.  So we need to re-check the grants again.
8296                checkedGrants = false;
8297            }
8298        }
8299        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8300                cpi.applicationInfo.uid, cpi.exported)
8301                == PackageManager.PERMISSION_GRANTED) {
8302            return null;
8303        }
8304        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8305                cpi.applicationInfo.uid, cpi.exported)
8306                == PackageManager.PERMISSION_GRANTED) {
8307            return null;
8308        }
8309
8310        PathPermission[] pps = cpi.pathPermissions;
8311        if (pps != null) {
8312            int i = pps.length;
8313            while (i > 0) {
8314                i--;
8315                PathPermission pp = pps[i];
8316                String pprperm = pp.getReadPermission();
8317                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8318                        cpi.applicationInfo.uid, cpi.exported)
8319                        == PackageManager.PERMISSION_GRANTED) {
8320                    return null;
8321                }
8322                String ppwperm = pp.getWritePermission();
8323                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8324                        cpi.applicationInfo.uid, cpi.exported)
8325                        == PackageManager.PERMISSION_GRANTED) {
8326                    return null;
8327                }
8328            }
8329        }
8330        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8331            return null;
8332        }
8333
8334        String msg;
8335        if (!cpi.exported) {
8336            msg = "Permission Denial: opening provider " + cpi.name
8337                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8338                    + ", uid=" + callingUid + ") that is not exported from uid "
8339                    + cpi.applicationInfo.uid;
8340        } else {
8341            msg = "Permission Denial: opening provider " + cpi.name
8342                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8343                    + ", uid=" + callingUid + ") requires "
8344                    + cpi.readPermission + " or " + cpi.writePermission;
8345        }
8346        Slog.w(TAG, msg);
8347        return msg;
8348    }
8349
8350    /**
8351     * Returns if the ContentProvider has granted a uri to callingUid
8352     */
8353    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8354        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8355        if (perms != null) {
8356            for (int i=perms.size()-1; i>=0; i--) {
8357                GrantUri grantUri = perms.keyAt(i);
8358                if (grantUri.sourceUserId == userId || !checkUser) {
8359                    if (matchesProvider(grantUri.uri, cpi)) {
8360                        return true;
8361                    }
8362                }
8363            }
8364        }
8365        return false;
8366    }
8367
8368    /**
8369     * Returns true if the uri authority is one of the authorities specified in the provider.
8370     */
8371    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8372        String uriAuth = uri.getAuthority();
8373        String cpiAuth = cpi.authority;
8374        if (cpiAuth.indexOf(';') == -1) {
8375            return cpiAuth.equals(uriAuth);
8376        }
8377        String[] cpiAuths = cpiAuth.split(";");
8378        int length = cpiAuths.length;
8379        for (int i = 0; i < length; i++) {
8380            if (cpiAuths[i].equals(uriAuth)) return true;
8381        }
8382        return false;
8383    }
8384
8385    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8386            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8387        if (r != null) {
8388            for (int i=0; i<r.conProviders.size(); i++) {
8389                ContentProviderConnection conn = r.conProviders.get(i);
8390                if (conn.provider == cpr) {
8391                    if (DEBUG_PROVIDER) Slog.v(TAG,
8392                            "Adding provider requested by "
8393                            + r.processName + " from process "
8394                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8395                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8396                    if (stable) {
8397                        conn.stableCount++;
8398                        conn.numStableIncs++;
8399                    } else {
8400                        conn.unstableCount++;
8401                        conn.numUnstableIncs++;
8402                    }
8403                    return conn;
8404                }
8405            }
8406            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8407            if (stable) {
8408                conn.stableCount = 1;
8409                conn.numStableIncs = 1;
8410            } else {
8411                conn.unstableCount = 1;
8412                conn.numUnstableIncs = 1;
8413            }
8414            cpr.connections.add(conn);
8415            r.conProviders.add(conn);
8416            return conn;
8417        }
8418        cpr.addExternalProcessHandleLocked(externalProcessToken);
8419        return null;
8420    }
8421
8422    boolean decProviderCountLocked(ContentProviderConnection conn,
8423            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8424        if (conn != null) {
8425            cpr = conn.provider;
8426            if (DEBUG_PROVIDER) Slog.v(TAG,
8427                    "Removing provider requested by "
8428                    + conn.client.processName + " from process "
8429                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8430                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8431            if (stable) {
8432                conn.stableCount--;
8433            } else {
8434                conn.unstableCount--;
8435            }
8436            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8437                cpr.connections.remove(conn);
8438                conn.client.conProviders.remove(conn);
8439                return true;
8440            }
8441            return false;
8442        }
8443        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8444        return false;
8445    }
8446
8447    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8448            String name, IBinder token, boolean stable, int userId) {
8449        ContentProviderRecord cpr;
8450        ContentProviderConnection conn = null;
8451        ProviderInfo cpi = null;
8452
8453        synchronized(this) {
8454            ProcessRecord r = null;
8455            if (caller != null) {
8456                r = getRecordForAppLocked(caller);
8457                if (r == null) {
8458                    throw new SecurityException(
8459                            "Unable to find app for caller " + caller
8460                          + " (pid=" + Binder.getCallingPid()
8461                          + ") when getting content provider " + name);
8462                }
8463            }
8464
8465            boolean checkCrossUser = true;
8466
8467            // First check if this content provider has been published...
8468            cpr = mProviderMap.getProviderByName(name, userId);
8469            // If that didn't work, check if it exists for user 0 and then
8470            // verify that it's a singleton provider before using it.
8471            if (cpr == null && userId != UserHandle.USER_OWNER) {
8472                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8473                if (cpr != null) {
8474                    cpi = cpr.info;
8475                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8476                            cpi.name, cpi.flags)
8477                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8478                        userId = UserHandle.USER_OWNER;
8479                        checkCrossUser = false;
8480                    } else {
8481                        cpr = null;
8482                        cpi = null;
8483                    }
8484                }
8485            }
8486
8487            boolean providerRunning = cpr != null;
8488            if (providerRunning) {
8489                cpi = cpr.info;
8490                String msg;
8491                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8492                        != null) {
8493                    throw new SecurityException(msg);
8494                }
8495
8496                if (r != null && cpr.canRunHere(r)) {
8497                    // This provider has been published or is in the process
8498                    // of being published...  but it is also allowed to run
8499                    // in the caller's process, so don't make a connection
8500                    // and just let the caller instantiate its own instance.
8501                    ContentProviderHolder holder = cpr.newHolder(null);
8502                    // don't give caller the provider object, it needs
8503                    // to make its own.
8504                    holder.provider = null;
8505                    return holder;
8506                }
8507
8508                final long origId = Binder.clearCallingIdentity();
8509
8510                // In this case the provider instance already exists, so we can
8511                // return it right away.
8512                conn = incProviderCountLocked(r, cpr, token, stable);
8513                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8514                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8515                        // If this is a perceptible app accessing the provider,
8516                        // make sure to count it as being accessed and thus
8517                        // back up on the LRU list.  This is good because
8518                        // content providers are often expensive to start.
8519                        updateLruProcessLocked(cpr.proc, false, null);
8520                    }
8521                }
8522
8523                if (cpr.proc != null) {
8524                    if (false) {
8525                        if (cpr.name.flattenToShortString().equals(
8526                                "com.android.providers.calendar/.CalendarProvider2")) {
8527                            Slog.v(TAG, "****************** KILLING "
8528                                + cpr.name.flattenToShortString());
8529                            Process.killProcess(cpr.proc.pid);
8530                        }
8531                    }
8532                    boolean success = updateOomAdjLocked(cpr.proc);
8533                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8534                    // NOTE: there is still a race here where a signal could be
8535                    // pending on the process even though we managed to update its
8536                    // adj level.  Not sure what to do about this, but at least
8537                    // the race is now smaller.
8538                    if (!success) {
8539                        // Uh oh...  it looks like the provider's process
8540                        // has been killed on us.  We need to wait for a new
8541                        // process to be started, and make sure its death
8542                        // doesn't kill our process.
8543                        Slog.i(TAG,
8544                                "Existing provider " + cpr.name.flattenToShortString()
8545                                + " is crashing; detaching " + r);
8546                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8547                        appDiedLocked(cpr.proc);
8548                        if (!lastRef) {
8549                            // This wasn't the last ref our process had on
8550                            // the provider...  we have now been killed, bail.
8551                            return null;
8552                        }
8553                        providerRunning = false;
8554                        conn = null;
8555                    }
8556                }
8557
8558                Binder.restoreCallingIdentity(origId);
8559            }
8560
8561            boolean singleton;
8562            if (!providerRunning) {
8563                try {
8564                    cpi = AppGlobals.getPackageManager().
8565                        resolveContentProvider(name,
8566                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8567                } catch (RemoteException ex) {
8568                }
8569                if (cpi == null) {
8570                    return null;
8571                }
8572                // If the provider is a singleton AND
8573                // (it's a call within the same user || the provider is a
8574                // privileged app)
8575                // Then allow connecting to the singleton provider
8576                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8577                        cpi.name, cpi.flags)
8578                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8579                if (singleton) {
8580                    userId = UserHandle.USER_OWNER;
8581                }
8582                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8583
8584                String msg;
8585                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8586                        != null) {
8587                    throw new SecurityException(msg);
8588                }
8589
8590                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8591                        && !cpi.processName.equals("system")) {
8592                    // If this content provider does not run in the system
8593                    // process, and the system is not yet ready to run other
8594                    // processes, then fail fast instead of hanging.
8595                    throw new IllegalArgumentException(
8596                            "Attempt to launch content provider before system ready");
8597                }
8598
8599                // Make sure that the user who owns this provider is started.  If not,
8600                // we don't want to allow it to run.
8601                if (mStartedUsers.get(userId) == null) {
8602                    Slog.w(TAG, "Unable to launch app "
8603                            + cpi.applicationInfo.packageName + "/"
8604                            + cpi.applicationInfo.uid + " for provider "
8605                            + name + ": user " + userId + " is stopped");
8606                    return null;
8607                }
8608
8609                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8610                cpr = mProviderMap.getProviderByClass(comp, userId);
8611                final boolean firstClass = cpr == null;
8612                if (firstClass) {
8613                    try {
8614                        ApplicationInfo ai =
8615                            AppGlobals.getPackageManager().
8616                                getApplicationInfo(
8617                                        cpi.applicationInfo.packageName,
8618                                        STOCK_PM_FLAGS, userId);
8619                        if (ai == null) {
8620                            Slog.w(TAG, "No package info for content provider "
8621                                    + cpi.name);
8622                            return null;
8623                        }
8624                        ai = getAppInfoForUser(ai, userId);
8625                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8626                    } catch (RemoteException ex) {
8627                        // pm is in same process, this will never happen.
8628                    }
8629                }
8630
8631                if (r != null && cpr.canRunHere(r)) {
8632                    // If this is a multiprocess provider, then just return its
8633                    // info and allow the caller to instantiate it.  Only do
8634                    // this if the provider is the same user as the caller's
8635                    // process, or can run as root (so can be in any process).
8636                    return cpr.newHolder(null);
8637                }
8638
8639                if (DEBUG_PROVIDER) {
8640                    RuntimeException e = new RuntimeException("here");
8641                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8642                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8643                }
8644
8645                // This is single process, and our app is now connecting to it.
8646                // See if we are already in the process of launching this
8647                // provider.
8648                final int N = mLaunchingProviders.size();
8649                int i;
8650                for (i=0; i<N; i++) {
8651                    if (mLaunchingProviders.get(i) == cpr) {
8652                        break;
8653                    }
8654                }
8655
8656                // If the provider is not already being launched, then get it
8657                // started.
8658                if (i >= N) {
8659                    final long origId = Binder.clearCallingIdentity();
8660
8661                    try {
8662                        // Content provider is now in use, its package can't be stopped.
8663                        try {
8664                            AppGlobals.getPackageManager().setPackageStoppedState(
8665                                    cpr.appInfo.packageName, false, userId);
8666                        } catch (RemoteException e) {
8667                        } catch (IllegalArgumentException e) {
8668                            Slog.w(TAG, "Failed trying to unstop package "
8669                                    + cpr.appInfo.packageName + ": " + e);
8670                        }
8671
8672                        // Use existing process if already started
8673                        ProcessRecord proc = getProcessRecordLocked(
8674                                cpi.processName, cpr.appInfo.uid, false);
8675                        if (proc != null && proc.thread != null) {
8676                            if (DEBUG_PROVIDER) {
8677                                Slog.d(TAG, "Installing in existing process " + proc);
8678                            }
8679                            proc.pubProviders.put(cpi.name, cpr);
8680                            try {
8681                                proc.thread.scheduleInstallProvider(cpi);
8682                            } catch (RemoteException e) {
8683                            }
8684                        } else {
8685                            proc = startProcessLocked(cpi.processName,
8686                                    cpr.appInfo, false, 0, "content provider",
8687                                    new ComponentName(cpi.applicationInfo.packageName,
8688                                            cpi.name), false, false, false);
8689                            if (proc == null) {
8690                                Slog.w(TAG, "Unable to launch app "
8691                                        + cpi.applicationInfo.packageName + "/"
8692                                        + cpi.applicationInfo.uid + " for provider "
8693                                        + name + ": process is bad");
8694                                return null;
8695                            }
8696                        }
8697                        cpr.launchingApp = proc;
8698                        mLaunchingProviders.add(cpr);
8699                    } finally {
8700                        Binder.restoreCallingIdentity(origId);
8701                    }
8702                }
8703
8704                // Make sure the provider is published (the same provider class
8705                // may be published under multiple names).
8706                if (firstClass) {
8707                    mProviderMap.putProviderByClass(comp, cpr);
8708                }
8709
8710                mProviderMap.putProviderByName(name, cpr);
8711                conn = incProviderCountLocked(r, cpr, token, stable);
8712                if (conn != null) {
8713                    conn.waiting = true;
8714                }
8715            }
8716        }
8717
8718        // Wait for the provider to be published...
8719        synchronized (cpr) {
8720            while (cpr.provider == null) {
8721                if (cpr.launchingApp == null) {
8722                    Slog.w(TAG, "Unable to launch app "
8723                            + cpi.applicationInfo.packageName + "/"
8724                            + cpi.applicationInfo.uid + " for provider "
8725                            + name + ": launching app became null");
8726                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8727                            UserHandle.getUserId(cpi.applicationInfo.uid),
8728                            cpi.applicationInfo.packageName,
8729                            cpi.applicationInfo.uid, name);
8730                    return null;
8731                }
8732                try {
8733                    if (DEBUG_MU) {
8734                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8735                                + cpr.launchingApp);
8736                    }
8737                    if (conn != null) {
8738                        conn.waiting = true;
8739                    }
8740                    cpr.wait();
8741                } catch (InterruptedException ex) {
8742                } finally {
8743                    if (conn != null) {
8744                        conn.waiting = false;
8745                    }
8746                }
8747            }
8748        }
8749        return cpr != null ? cpr.newHolder(conn) : null;
8750    }
8751
8752    @Override
8753    public final ContentProviderHolder getContentProvider(
8754            IApplicationThread caller, String name, int userId, boolean stable) {
8755        enforceNotIsolatedCaller("getContentProvider");
8756        if (caller == null) {
8757            String msg = "null IApplicationThread when getting content provider "
8758                    + name;
8759            Slog.w(TAG, msg);
8760            throw new SecurityException(msg);
8761        }
8762        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8763        // with cross-user grant.
8764        return getContentProviderImpl(caller, name, null, stable, userId);
8765    }
8766
8767    public ContentProviderHolder getContentProviderExternal(
8768            String name, int userId, IBinder token) {
8769        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8770            "Do not have permission in call getContentProviderExternal()");
8771        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8772                false, ALLOW_FULL_ONLY, "getContentProvider", null);
8773        return getContentProviderExternalUnchecked(name, token, userId);
8774    }
8775
8776    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8777            IBinder token, int userId) {
8778        return getContentProviderImpl(null, name, token, true, userId);
8779    }
8780
8781    /**
8782     * Drop a content provider from a ProcessRecord's bookkeeping
8783     */
8784    public void removeContentProvider(IBinder connection, boolean stable) {
8785        enforceNotIsolatedCaller("removeContentProvider");
8786        long ident = Binder.clearCallingIdentity();
8787        try {
8788            synchronized (this) {
8789                ContentProviderConnection conn;
8790                try {
8791                    conn = (ContentProviderConnection)connection;
8792                } catch (ClassCastException e) {
8793                    String msg ="removeContentProvider: " + connection
8794                            + " not a ContentProviderConnection";
8795                    Slog.w(TAG, msg);
8796                    throw new IllegalArgumentException(msg);
8797                }
8798                if (conn == null) {
8799                    throw new NullPointerException("connection is null");
8800                }
8801                if (decProviderCountLocked(conn, null, null, stable)) {
8802                    updateOomAdjLocked();
8803                }
8804            }
8805        } finally {
8806            Binder.restoreCallingIdentity(ident);
8807        }
8808    }
8809
8810    public void removeContentProviderExternal(String name, IBinder token) {
8811        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8812            "Do not have permission in call removeContentProviderExternal()");
8813        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8814    }
8815
8816    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8817        synchronized (this) {
8818            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8819            if(cpr == null) {
8820                //remove from mProvidersByClass
8821                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8822                return;
8823            }
8824
8825            //update content provider record entry info
8826            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8827            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8828            if (localCpr.hasExternalProcessHandles()) {
8829                if (localCpr.removeExternalProcessHandleLocked(token)) {
8830                    updateOomAdjLocked();
8831                } else {
8832                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8833                            + " with no external reference for token: "
8834                            + token + ".");
8835                }
8836            } else {
8837                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8838                        + " with no external references.");
8839            }
8840        }
8841    }
8842
8843    public final void publishContentProviders(IApplicationThread caller,
8844            List<ContentProviderHolder> providers) {
8845        if (providers == null) {
8846            return;
8847        }
8848
8849        enforceNotIsolatedCaller("publishContentProviders");
8850        synchronized (this) {
8851            final ProcessRecord r = getRecordForAppLocked(caller);
8852            if (DEBUG_MU)
8853                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8854            if (r == null) {
8855                throw new SecurityException(
8856                        "Unable to find app for caller " + caller
8857                      + " (pid=" + Binder.getCallingPid()
8858                      + ") when publishing content providers");
8859            }
8860
8861            final long origId = Binder.clearCallingIdentity();
8862
8863            final int N = providers.size();
8864            for (int i=0; i<N; i++) {
8865                ContentProviderHolder src = providers.get(i);
8866                if (src == null || src.info == null || src.provider == null) {
8867                    continue;
8868                }
8869                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8870                if (DEBUG_MU)
8871                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8872                if (dst != null) {
8873                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8874                    mProviderMap.putProviderByClass(comp, dst);
8875                    String names[] = dst.info.authority.split(";");
8876                    for (int j = 0; j < names.length; j++) {
8877                        mProviderMap.putProviderByName(names[j], dst);
8878                    }
8879
8880                    int NL = mLaunchingProviders.size();
8881                    int j;
8882                    for (j=0; j<NL; j++) {
8883                        if (mLaunchingProviders.get(j) == dst) {
8884                            mLaunchingProviders.remove(j);
8885                            j--;
8886                            NL--;
8887                        }
8888                    }
8889                    synchronized (dst) {
8890                        dst.provider = src.provider;
8891                        dst.proc = r;
8892                        dst.notifyAll();
8893                    }
8894                    updateOomAdjLocked(r);
8895                }
8896            }
8897
8898            Binder.restoreCallingIdentity(origId);
8899        }
8900    }
8901
8902    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8903        ContentProviderConnection conn;
8904        try {
8905            conn = (ContentProviderConnection)connection;
8906        } catch (ClassCastException e) {
8907            String msg ="refContentProvider: " + connection
8908                    + " not a ContentProviderConnection";
8909            Slog.w(TAG, msg);
8910            throw new IllegalArgumentException(msg);
8911        }
8912        if (conn == null) {
8913            throw new NullPointerException("connection is null");
8914        }
8915
8916        synchronized (this) {
8917            if (stable > 0) {
8918                conn.numStableIncs += stable;
8919            }
8920            stable = conn.stableCount + stable;
8921            if (stable < 0) {
8922                throw new IllegalStateException("stableCount < 0: " + stable);
8923            }
8924
8925            if (unstable > 0) {
8926                conn.numUnstableIncs += unstable;
8927            }
8928            unstable = conn.unstableCount + unstable;
8929            if (unstable < 0) {
8930                throw new IllegalStateException("unstableCount < 0: " + unstable);
8931            }
8932
8933            if ((stable+unstable) <= 0) {
8934                throw new IllegalStateException("ref counts can't go to zero here: stable="
8935                        + stable + " unstable=" + unstable);
8936            }
8937            conn.stableCount = stable;
8938            conn.unstableCount = unstable;
8939            return !conn.dead;
8940        }
8941    }
8942
8943    public void unstableProviderDied(IBinder connection) {
8944        ContentProviderConnection conn;
8945        try {
8946            conn = (ContentProviderConnection)connection;
8947        } catch (ClassCastException e) {
8948            String msg ="refContentProvider: " + connection
8949                    + " not a ContentProviderConnection";
8950            Slog.w(TAG, msg);
8951            throw new IllegalArgumentException(msg);
8952        }
8953        if (conn == null) {
8954            throw new NullPointerException("connection is null");
8955        }
8956
8957        // Safely retrieve the content provider associated with the connection.
8958        IContentProvider provider;
8959        synchronized (this) {
8960            provider = conn.provider.provider;
8961        }
8962
8963        if (provider == null) {
8964            // Um, yeah, we're way ahead of you.
8965            return;
8966        }
8967
8968        // Make sure the caller is being honest with us.
8969        if (provider.asBinder().pingBinder()) {
8970            // Er, no, still looks good to us.
8971            synchronized (this) {
8972                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8973                        + " says " + conn + " died, but we don't agree");
8974                return;
8975            }
8976        }
8977
8978        // Well look at that!  It's dead!
8979        synchronized (this) {
8980            if (conn.provider.provider != provider) {
8981                // But something changed...  good enough.
8982                return;
8983            }
8984
8985            ProcessRecord proc = conn.provider.proc;
8986            if (proc == null || proc.thread == null) {
8987                // Seems like the process is already cleaned up.
8988                return;
8989            }
8990
8991            // As far as we're concerned, this is just like receiving a
8992            // death notification...  just a bit prematurely.
8993            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8994                    + ") early provider death");
8995            final long ident = Binder.clearCallingIdentity();
8996            try {
8997                appDiedLocked(proc);
8998            } finally {
8999                Binder.restoreCallingIdentity(ident);
9000            }
9001        }
9002    }
9003
9004    @Override
9005    public void appNotRespondingViaProvider(IBinder connection) {
9006        enforceCallingPermission(
9007                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9008
9009        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9010        if (conn == null) {
9011            Slog.w(TAG, "ContentProviderConnection is null");
9012            return;
9013        }
9014
9015        final ProcessRecord host = conn.provider.proc;
9016        if (host == null) {
9017            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9018            return;
9019        }
9020
9021        final long token = Binder.clearCallingIdentity();
9022        try {
9023            appNotResponding(host, null, null, false, "ContentProvider not responding");
9024        } finally {
9025            Binder.restoreCallingIdentity(token);
9026        }
9027    }
9028
9029    public final void installSystemProviders() {
9030        List<ProviderInfo> providers;
9031        synchronized (this) {
9032            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9033            providers = generateApplicationProvidersLocked(app);
9034            if (providers != null) {
9035                for (int i=providers.size()-1; i>=0; i--) {
9036                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9037                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9038                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9039                                + ": not system .apk");
9040                        providers.remove(i);
9041                    }
9042                }
9043            }
9044        }
9045        if (providers != null) {
9046            mSystemThread.installSystemProviders(providers);
9047        }
9048
9049        mCoreSettingsObserver = new CoreSettingsObserver(this);
9050
9051        //mUsageStatsService.monitorPackages();
9052    }
9053
9054    /**
9055     * Allows apps to retrieve the MIME type of a URI.
9056     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9057     * users, then it does not need permission to access the ContentProvider.
9058     * Either, it needs cross-user uri grants.
9059     *
9060     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9061     *
9062     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9063     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9064     */
9065    public String getProviderMimeType(Uri uri, int userId) {
9066        enforceNotIsolatedCaller("getProviderMimeType");
9067        final String name = uri.getAuthority();
9068        int callingUid = Binder.getCallingUid();
9069        int callingPid = Binder.getCallingPid();
9070        long ident = 0;
9071        boolean clearedIdentity = false;
9072        userId = unsafeConvertIncomingUser(userId);
9073        if (UserHandle.getUserId(callingUid) != userId) {
9074            if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9075                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9076                    || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9077                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9078                clearedIdentity = true;
9079                ident = Binder.clearCallingIdentity();
9080            }
9081        }
9082        ContentProviderHolder holder = null;
9083        try {
9084            holder = getContentProviderExternalUnchecked(name, null, userId);
9085            if (holder != null) {
9086                return holder.provider.getType(uri);
9087            }
9088        } catch (RemoteException e) {
9089            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9090            return null;
9091        } finally {
9092            // We need to clear the identity to call removeContentProviderExternalUnchecked
9093            if (!clearedIdentity) {
9094                ident = Binder.clearCallingIdentity();
9095            }
9096            try {
9097                if (holder != null) {
9098                    removeContentProviderExternalUnchecked(name, null, userId);
9099                }
9100            } finally {
9101                Binder.restoreCallingIdentity(ident);
9102            }
9103        }
9104
9105        return null;
9106    }
9107
9108    // =========================================================
9109    // GLOBAL MANAGEMENT
9110    // =========================================================
9111
9112    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9113            boolean isolated, int isolatedUid) {
9114        String proc = customProcess != null ? customProcess : info.processName;
9115        BatteryStatsImpl.Uid.Proc ps = null;
9116        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9117        int uid = info.uid;
9118        if (isolated) {
9119            if (isolatedUid == 0) {
9120                int userId = UserHandle.getUserId(uid);
9121                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9122                while (true) {
9123                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9124                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9125                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9126                    }
9127                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9128                    mNextIsolatedProcessUid++;
9129                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9130                        // No process for this uid, use it.
9131                        break;
9132                    }
9133                    stepsLeft--;
9134                    if (stepsLeft <= 0) {
9135                        return null;
9136                    }
9137                }
9138            } else {
9139                // Special case for startIsolatedProcess (internal only), where
9140                // the uid of the isolated process is specified by the caller.
9141                uid = isolatedUid;
9142            }
9143        }
9144        return new ProcessRecord(stats, info, proc, uid);
9145    }
9146
9147    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9148            String abiOverride) {
9149        ProcessRecord app;
9150        if (!isolated) {
9151            app = getProcessRecordLocked(info.processName, info.uid, true);
9152        } else {
9153            app = null;
9154        }
9155
9156        if (app == null) {
9157            app = newProcessRecordLocked(info, null, isolated, 0);
9158            mProcessNames.put(info.processName, app.uid, app);
9159            if (isolated) {
9160                mIsolatedProcesses.put(app.uid, app);
9161            }
9162            updateLruProcessLocked(app, false, null);
9163            updateOomAdjLocked();
9164        }
9165
9166        // This package really, really can not be stopped.
9167        try {
9168            AppGlobals.getPackageManager().setPackageStoppedState(
9169                    info.packageName, false, UserHandle.getUserId(app.uid));
9170        } catch (RemoteException e) {
9171        } catch (IllegalArgumentException e) {
9172            Slog.w(TAG, "Failed trying to unstop package "
9173                    + info.packageName + ": " + e);
9174        }
9175
9176        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9177                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9178            app.persistent = true;
9179            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9180        }
9181        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9182            mPersistentStartingProcesses.add(app);
9183            startProcessLocked(app, "added application", app.processName, abiOverride,
9184                    null /* entryPoint */, null /* entryPointArgs */);
9185        }
9186
9187        return app;
9188    }
9189
9190    public void unhandledBack() {
9191        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9192                "unhandledBack()");
9193
9194        synchronized(this) {
9195            final long origId = Binder.clearCallingIdentity();
9196            try {
9197                getFocusedStack().unhandledBackLocked();
9198            } finally {
9199                Binder.restoreCallingIdentity(origId);
9200            }
9201        }
9202    }
9203
9204    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9205        enforceNotIsolatedCaller("openContentUri");
9206        final int userId = UserHandle.getCallingUserId();
9207        String name = uri.getAuthority();
9208        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9209        ParcelFileDescriptor pfd = null;
9210        if (cph != null) {
9211            // We record the binder invoker's uid in thread-local storage before
9212            // going to the content provider to open the file.  Later, in the code
9213            // that handles all permissions checks, we look for this uid and use
9214            // that rather than the Activity Manager's own uid.  The effect is that
9215            // we do the check against the caller's permissions even though it looks
9216            // to the content provider like the Activity Manager itself is making
9217            // the request.
9218            sCallerIdentity.set(new Identity(
9219                    Binder.getCallingPid(), Binder.getCallingUid()));
9220            try {
9221                pfd = cph.provider.openFile(null, uri, "r", null);
9222            } catch (FileNotFoundException e) {
9223                // do nothing; pfd will be returned null
9224            } finally {
9225                // Ensure that whatever happens, we clean up the identity state
9226                sCallerIdentity.remove();
9227            }
9228
9229            // We've got the fd now, so we're done with the provider.
9230            removeContentProviderExternalUnchecked(name, null, userId);
9231        } else {
9232            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9233        }
9234        return pfd;
9235    }
9236
9237    // Actually is sleeping or shutting down or whatever else in the future
9238    // is an inactive state.
9239    public boolean isSleepingOrShuttingDown() {
9240        return mSleeping || mShuttingDown;
9241    }
9242
9243    public boolean isSleeping() {
9244        return mSleeping;
9245    }
9246
9247    void goingToSleep() {
9248        synchronized(this) {
9249            mWentToSleep = true;
9250            updateEventDispatchingLocked();
9251            goToSleepIfNeededLocked();
9252        }
9253    }
9254
9255    void finishRunningVoiceLocked() {
9256        if (mRunningVoice) {
9257            mRunningVoice = false;
9258            goToSleepIfNeededLocked();
9259        }
9260    }
9261
9262    void goToSleepIfNeededLocked() {
9263        if (mWentToSleep && !mRunningVoice) {
9264            if (!mSleeping) {
9265                mSleeping = true;
9266                mStackSupervisor.goingToSleepLocked();
9267
9268                // Initialize the wake times of all processes.
9269                checkExcessivePowerUsageLocked(false);
9270                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9271                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9272                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9273            }
9274        }
9275    }
9276
9277    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9278        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9279            // Never persist the home stack.
9280            return;
9281        }
9282        mTaskPersister.wakeup(task, flush);
9283    }
9284
9285    @Override
9286    public boolean shutdown(int timeout) {
9287        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9288                != PackageManager.PERMISSION_GRANTED) {
9289            throw new SecurityException("Requires permission "
9290                    + android.Manifest.permission.SHUTDOWN);
9291        }
9292
9293        boolean timedout = false;
9294
9295        synchronized(this) {
9296            mShuttingDown = true;
9297            updateEventDispatchingLocked();
9298            timedout = mStackSupervisor.shutdownLocked(timeout);
9299        }
9300
9301        mAppOpsService.shutdown();
9302        if (mUsageStatsService != null) {
9303            mUsageStatsService.prepareShutdown();
9304        }
9305        mBatteryStatsService.shutdown();
9306        synchronized (this) {
9307            mProcessStats.shutdownLocked();
9308        }
9309        notifyTaskPersisterLocked(null, true);
9310
9311        return timedout;
9312    }
9313
9314    public final void activitySlept(IBinder token) {
9315        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9316
9317        final long origId = Binder.clearCallingIdentity();
9318
9319        synchronized (this) {
9320            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9321            if (r != null) {
9322                mStackSupervisor.activitySleptLocked(r);
9323            }
9324        }
9325
9326        Binder.restoreCallingIdentity(origId);
9327    }
9328
9329    void logLockScreen(String msg) {
9330        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9331                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9332                mWentToSleep + " mSleeping=" + mSleeping);
9333    }
9334
9335    private void comeOutOfSleepIfNeededLocked() {
9336        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9337            if (mSleeping) {
9338                mSleeping = false;
9339                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9340            }
9341        }
9342    }
9343
9344    void wakingUp() {
9345        synchronized(this) {
9346            mWentToSleep = false;
9347            updateEventDispatchingLocked();
9348            comeOutOfSleepIfNeededLocked();
9349        }
9350    }
9351
9352    void startRunningVoiceLocked() {
9353        if (!mRunningVoice) {
9354            mRunningVoice = true;
9355            comeOutOfSleepIfNeededLocked();
9356        }
9357    }
9358
9359    private void updateEventDispatchingLocked() {
9360        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9361    }
9362
9363    public void setLockScreenShown(boolean shown) {
9364        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9365                != PackageManager.PERMISSION_GRANTED) {
9366            throw new SecurityException("Requires permission "
9367                    + android.Manifest.permission.DEVICE_POWER);
9368        }
9369
9370        synchronized(this) {
9371            long ident = Binder.clearCallingIdentity();
9372            try {
9373                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9374                mLockScreenShown = shown;
9375                comeOutOfSleepIfNeededLocked();
9376            } finally {
9377                Binder.restoreCallingIdentity(ident);
9378            }
9379        }
9380    }
9381
9382    @Override
9383    public void stopAppSwitches() {
9384        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9385                != PackageManager.PERMISSION_GRANTED) {
9386            throw new SecurityException("Requires permission "
9387                    + android.Manifest.permission.STOP_APP_SWITCHES);
9388        }
9389
9390        synchronized(this) {
9391            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9392                    + APP_SWITCH_DELAY_TIME;
9393            mDidAppSwitch = false;
9394            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9395            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9396            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9397        }
9398    }
9399
9400    public void resumeAppSwitches() {
9401        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9402                != PackageManager.PERMISSION_GRANTED) {
9403            throw new SecurityException("Requires permission "
9404                    + android.Manifest.permission.STOP_APP_SWITCHES);
9405        }
9406
9407        synchronized(this) {
9408            // Note that we don't execute any pending app switches... we will
9409            // let those wait until either the timeout, or the next start
9410            // activity request.
9411            mAppSwitchesAllowedTime = 0;
9412        }
9413    }
9414
9415    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9416            String name) {
9417        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9418            return true;
9419        }
9420
9421        final int perm = checkComponentPermission(
9422                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9423                callingUid, -1, true);
9424        if (perm == PackageManager.PERMISSION_GRANTED) {
9425            return true;
9426        }
9427
9428        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9429        return false;
9430    }
9431
9432    public void setDebugApp(String packageName, boolean waitForDebugger,
9433            boolean persistent) {
9434        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9435                "setDebugApp()");
9436
9437        long ident = Binder.clearCallingIdentity();
9438        try {
9439            // Note that this is not really thread safe if there are multiple
9440            // callers into it at the same time, but that's not a situation we
9441            // care about.
9442            if (persistent) {
9443                final ContentResolver resolver = mContext.getContentResolver();
9444                Settings.Global.putString(
9445                    resolver, Settings.Global.DEBUG_APP,
9446                    packageName);
9447                Settings.Global.putInt(
9448                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9449                    waitForDebugger ? 1 : 0);
9450            }
9451
9452            synchronized (this) {
9453                if (!persistent) {
9454                    mOrigDebugApp = mDebugApp;
9455                    mOrigWaitForDebugger = mWaitForDebugger;
9456                }
9457                mDebugApp = packageName;
9458                mWaitForDebugger = waitForDebugger;
9459                mDebugTransient = !persistent;
9460                if (packageName != null) {
9461                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9462                            false, UserHandle.USER_ALL, "set debug app");
9463                }
9464            }
9465        } finally {
9466            Binder.restoreCallingIdentity(ident);
9467        }
9468    }
9469
9470    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9471        synchronized (this) {
9472            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9473            if (!isDebuggable) {
9474                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9475                    throw new SecurityException("Process not debuggable: " + app.packageName);
9476                }
9477            }
9478
9479            mOpenGlTraceApp = processName;
9480        }
9481    }
9482
9483    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9484            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9485        synchronized (this) {
9486            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9487            if (!isDebuggable) {
9488                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9489                    throw new SecurityException("Process not debuggable: " + app.packageName);
9490                }
9491            }
9492            mProfileApp = processName;
9493            mProfileFile = profileFile;
9494            if (mProfileFd != null) {
9495                try {
9496                    mProfileFd.close();
9497                } catch (IOException e) {
9498                }
9499                mProfileFd = null;
9500            }
9501            mProfileFd = profileFd;
9502            mProfileType = 0;
9503            mAutoStopProfiler = autoStopProfiler;
9504        }
9505    }
9506
9507    @Override
9508    public void setAlwaysFinish(boolean enabled) {
9509        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9510                "setAlwaysFinish()");
9511
9512        Settings.Global.putInt(
9513                mContext.getContentResolver(),
9514                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9515
9516        synchronized (this) {
9517            mAlwaysFinishActivities = enabled;
9518        }
9519    }
9520
9521    @Override
9522    public void setActivityController(IActivityController controller) {
9523        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9524                "setActivityController()");
9525        synchronized (this) {
9526            mController = controller;
9527            Watchdog.getInstance().setActivityController(controller);
9528        }
9529    }
9530
9531    @Override
9532    public void setUserIsMonkey(boolean userIsMonkey) {
9533        synchronized (this) {
9534            synchronized (mPidsSelfLocked) {
9535                final int callingPid = Binder.getCallingPid();
9536                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9537                if (precessRecord == null) {
9538                    throw new SecurityException("Unknown process: " + callingPid);
9539                }
9540                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9541                    throw new SecurityException("Only an instrumentation process "
9542                            + "with a UiAutomation can call setUserIsMonkey");
9543                }
9544            }
9545            mUserIsMonkey = userIsMonkey;
9546        }
9547    }
9548
9549    @Override
9550    public boolean isUserAMonkey() {
9551        synchronized (this) {
9552            // If there is a controller also implies the user is a monkey.
9553            return (mUserIsMonkey || mController != null);
9554        }
9555    }
9556
9557    public void requestBugReport() {
9558        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9559        SystemProperties.set("ctl.start", "bugreport");
9560    }
9561
9562    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9563        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9564    }
9565
9566    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9567        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9568            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9569        }
9570        return KEY_DISPATCHING_TIMEOUT;
9571    }
9572
9573    @Override
9574    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9575        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9576                != PackageManager.PERMISSION_GRANTED) {
9577            throw new SecurityException("Requires permission "
9578                    + android.Manifest.permission.FILTER_EVENTS);
9579        }
9580        ProcessRecord proc;
9581        long timeout;
9582        synchronized (this) {
9583            synchronized (mPidsSelfLocked) {
9584                proc = mPidsSelfLocked.get(pid);
9585            }
9586            timeout = getInputDispatchingTimeoutLocked(proc);
9587        }
9588
9589        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9590            return -1;
9591        }
9592
9593        return timeout;
9594    }
9595
9596    /**
9597     * Handle input dispatching timeouts.
9598     * Returns whether input dispatching should be aborted or not.
9599     */
9600    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9601            final ActivityRecord activity, final ActivityRecord parent,
9602            final boolean aboveSystem, String reason) {
9603        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9604                != PackageManager.PERMISSION_GRANTED) {
9605            throw new SecurityException("Requires permission "
9606                    + android.Manifest.permission.FILTER_EVENTS);
9607        }
9608
9609        final String annotation;
9610        if (reason == null) {
9611            annotation = "Input dispatching timed out";
9612        } else {
9613            annotation = "Input dispatching timed out (" + reason + ")";
9614        }
9615
9616        if (proc != null) {
9617            synchronized (this) {
9618                if (proc.debugging) {
9619                    return false;
9620                }
9621
9622                if (mDidDexOpt) {
9623                    // Give more time since we were dexopting.
9624                    mDidDexOpt = false;
9625                    return false;
9626                }
9627
9628                if (proc.instrumentationClass != null) {
9629                    Bundle info = new Bundle();
9630                    info.putString("shortMsg", "keyDispatchingTimedOut");
9631                    info.putString("longMsg", annotation);
9632                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9633                    return true;
9634                }
9635            }
9636            mHandler.post(new Runnable() {
9637                @Override
9638                public void run() {
9639                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9640                }
9641            });
9642        }
9643
9644        return true;
9645    }
9646
9647    public Bundle getAssistContextExtras(int requestType) {
9648        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9649                "getAssistContextExtras()");
9650        PendingAssistExtras pae;
9651        Bundle extras = new Bundle();
9652        synchronized (this) {
9653            ActivityRecord activity = getFocusedStack().mResumedActivity;
9654            if (activity == null) {
9655                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9656                return null;
9657            }
9658            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9659            if (activity.app == null || activity.app.thread == null) {
9660                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9661                return extras;
9662            }
9663            if (activity.app.pid == Binder.getCallingPid()) {
9664                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9665                return extras;
9666            }
9667            pae = new PendingAssistExtras(activity);
9668            try {
9669                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9670                        requestType);
9671                mPendingAssistExtras.add(pae);
9672                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9673            } catch (RemoteException e) {
9674                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9675                return extras;
9676            }
9677        }
9678        synchronized (pae) {
9679            while (!pae.haveResult) {
9680                try {
9681                    pae.wait();
9682                } catch (InterruptedException e) {
9683                }
9684            }
9685            if (pae.result != null) {
9686                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9687            }
9688        }
9689        synchronized (this) {
9690            mPendingAssistExtras.remove(pae);
9691            mHandler.removeCallbacks(pae);
9692        }
9693        return extras;
9694    }
9695
9696    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9697        PendingAssistExtras pae = (PendingAssistExtras)token;
9698        synchronized (pae) {
9699            pae.result = extras;
9700            pae.haveResult = true;
9701            pae.notifyAll();
9702        }
9703    }
9704
9705    public void registerProcessObserver(IProcessObserver observer) {
9706        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9707                "registerProcessObserver()");
9708        synchronized (this) {
9709            mProcessObservers.register(observer);
9710        }
9711    }
9712
9713    @Override
9714    public void unregisterProcessObserver(IProcessObserver observer) {
9715        synchronized (this) {
9716            mProcessObservers.unregister(observer);
9717        }
9718    }
9719
9720    @Override
9721    public boolean convertFromTranslucent(IBinder token) {
9722        final long origId = Binder.clearCallingIdentity();
9723        try {
9724            synchronized (this) {
9725                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9726                if (r == null) {
9727                    return false;
9728                }
9729                if (r.changeWindowTranslucency(true)) {
9730                    mWindowManager.setAppFullscreen(token, true);
9731                    r.task.stack.releaseBackgroundResources();
9732                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9733                    return true;
9734                }
9735                return false;
9736            }
9737        } finally {
9738            Binder.restoreCallingIdentity(origId);
9739        }
9740    }
9741
9742    @Override
9743    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9744        final long origId = Binder.clearCallingIdentity();
9745        try {
9746            synchronized (this) {
9747                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9748                if (r == null) {
9749                    return false;
9750                }
9751                int index = r.task.mActivities.lastIndexOf(r);
9752                if (index > 0) {
9753                    ActivityRecord under = r.task.mActivities.get(index - 1);
9754                    under.returningOptions = options;
9755                }
9756                if (r.changeWindowTranslucency(false)) {
9757                    r.task.stack.convertToTranslucent(r);
9758                    mWindowManager.setAppFullscreen(token, false);
9759                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9760                    return true;
9761                } else {
9762                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9763                    return false;
9764                }
9765            }
9766        } finally {
9767            Binder.restoreCallingIdentity(origId);
9768        }
9769    }
9770
9771    @Override
9772    public boolean requestVisibleBehind(IBinder token, boolean visible) {
9773        final long origId = Binder.clearCallingIdentity();
9774        try {
9775            synchronized (this) {
9776                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9777                if (r != null) {
9778                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
9779                }
9780            }
9781            return false;
9782        } finally {
9783            Binder.restoreCallingIdentity(origId);
9784        }
9785    }
9786
9787    @Override
9788    public boolean isBackgroundVisibleBehind(IBinder token) {
9789        final long origId = Binder.clearCallingIdentity();
9790        try {
9791            synchronized (this) {
9792                final ActivityStack stack = ActivityRecord.getStackLocked(token);
9793                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
9794                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
9795                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
9796                return visible;
9797            }
9798        } finally {
9799            Binder.restoreCallingIdentity(origId);
9800        }
9801    }
9802
9803    @Override
9804    public ActivityOptions getActivityOptions(IBinder token) {
9805        final long origId = Binder.clearCallingIdentity();
9806        try {
9807            synchronized (this) {
9808                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9809                if (r != null) {
9810                    final ActivityOptions activityOptions = r.pendingOptions;
9811                    r.pendingOptions = null;
9812                    return activityOptions;
9813                }
9814                return null;
9815            }
9816        } finally {
9817            Binder.restoreCallingIdentity(origId);
9818        }
9819    }
9820
9821    @Override
9822    public void setImmersive(IBinder token, boolean immersive) {
9823        synchronized(this) {
9824            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9825            if (r == null) {
9826                throw new IllegalArgumentException();
9827            }
9828            r.immersive = immersive;
9829
9830            // update associated state if we're frontmost
9831            if (r == mFocusedActivity) {
9832                if (DEBUG_IMMERSIVE) {
9833                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9834                }
9835                applyUpdateLockStateLocked(r);
9836            }
9837        }
9838    }
9839
9840    @Override
9841    public boolean isImmersive(IBinder token) {
9842        synchronized (this) {
9843            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9844            if (r == null) {
9845                throw new IllegalArgumentException();
9846            }
9847            return r.immersive;
9848        }
9849    }
9850
9851    public boolean isTopActivityImmersive() {
9852        enforceNotIsolatedCaller("startActivity");
9853        synchronized (this) {
9854            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9855            return (r != null) ? r.immersive : false;
9856        }
9857    }
9858
9859    @Override
9860    public boolean isTopOfTask(IBinder token) {
9861        synchronized (this) {
9862            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9863            if (r == null) {
9864                throw new IllegalArgumentException();
9865            }
9866            return r.task.getTopActivity() == r;
9867        }
9868    }
9869
9870    public final void enterSafeMode() {
9871        synchronized(this) {
9872            // It only makes sense to do this before the system is ready
9873            // and started launching other packages.
9874            if (!mSystemReady) {
9875                try {
9876                    AppGlobals.getPackageManager().enterSafeMode();
9877                } catch (RemoteException e) {
9878                }
9879            }
9880
9881            mSafeMode = true;
9882        }
9883    }
9884
9885    public final void showSafeModeOverlay() {
9886        View v = LayoutInflater.from(mContext).inflate(
9887                com.android.internal.R.layout.safe_mode, null);
9888        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9889        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9890        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9891        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9892        lp.gravity = Gravity.BOTTOM | Gravity.START;
9893        lp.format = v.getBackground().getOpacity();
9894        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9895                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9896        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9897        ((WindowManager)mContext.getSystemService(
9898                Context.WINDOW_SERVICE)).addView(v, lp);
9899    }
9900
9901    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9902        if (!(sender instanceof PendingIntentRecord)) {
9903            return;
9904        }
9905        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9906        synchronized (stats) {
9907            if (mBatteryStatsService.isOnBattery()) {
9908                mBatteryStatsService.enforceCallingPermission();
9909                PendingIntentRecord rec = (PendingIntentRecord)sender;
9910                int MY_UID = Binder.getCallingUid();
9911                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9912                BatteryStatsImpl.Uid.Pkg pkg =
9913                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9914                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9915                pkg.incWakeupsLocked();
9916            }
9917        }
9918    }
9919
9920    public boolean killPids(int[] pids, String pReason, boolean secure) {
9921        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9922            throw new SecurityException("killPids only available to the system");
9923        }
9924        String reason = (pReason == null) ? "Unknown" : pReason;
9925        // XXX Note: don't acquire main activity lock here, because the window
9926        // manager calls in with its locks held.
9927
9928        boolean killed = false;
9929        synchronized (mPidsSelfLocked) {
9930            int[] types = new int[pids.length];
9931            int worstType = 0;
9932            for (int i=0; i<pids.length; i++) {
9933                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9934                if (proc != null) {
9935                    int type = proc.setAdj;
9936                    types[i] = type;
9937                    if (type > worstType) {
9938                        worstType = type;
9939                    }
9940                }
9941            }
9942
9943            // If the worst oom_adj is somewhere in the cached proc LRU range,
9944            // then constrain it so we will kill all cached procs.
9945            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9946                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9947                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9948            }
9949
9950            // If this is not a secure call, don't let it kill processes that
9951            // are important.
9952            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9953                worstType = ProcessList.SERVICE_ADJ;
9954            }
9955
9956            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9957            for (int i=0; i<pids.length; i++) {
9958                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9959                if (proc == null) {
9960                    continue;
9961                }
9962                int adj = proc.setAdj;
9963                if (adj >= worstType && !proc.killedByAm) {
9964                    killUnneededProcessLocked(proc, reason);
9965                    killed = true;
9966                }
9967            }
9968        }
9969        return killed;
9970    }
9971
9972    @Override
9973    public void killUid(int uid, String reason) {
9974        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9975            throw new SecurityException("killUid only available to the system");
9976        }
9977        synchronized (this) {
9978            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9979                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9980                    reason != null ? reason : "kill uid");
9981        }
9982    }
9983
9984    @Override
9985    public boolean killProcessesBelowForeground(String reason) {
9986        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9987            throw new SecurityException("killProcessesBelowForeground() only available to system");
9988        }
9989
9990        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9991    }
9992
9993    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9994        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9995            throw new SecurityException("killProcessesBelowAdj() only available to system");
9996        }
9997
9998        boolean killed = false;
9999        synchronized (mPidsSelfLocked) {
10000            final int size = mPidsSelfLocked.size();
10001            for (int i = 0; i < size; i++) {
10002                final int pid = mPidsSelfLocked.keyAt(i);
10003                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10004                if (proc == null) continue;
10005
10006                final int adj = proc.setAdj;
10007                if (adj > belowAdj && !proc.killedByAm) {
10008                    killUnneededProcessLocked(proc, reason);
10009                    killed = true;
10010                }
10011            }
10012        }
10013        return killed;
10014    }
10015
10016    @Override
10017    public void hang(final IBinder who, boolean allowRestart) {
10018        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10019                != PackageManager.PERMISSION_GRANTED) {
10020            throw new SecurityException("Requires permission "
10021                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10022        }
10023
10024        final IBinder.DeathRecipient death = new DeathRecipient() {
10025            @Override
10026            public void binderDied() {
10027                synchronized (this) {
10028                    notifyAll();
10029                }
10030            }
10031        };
10032
10033        try {
10034            who.linkToDeath(death, 0);
10035        } catch (RemoteException e) {
10036            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10037            return;
10038        }
10039
10040        synchronized (this) {
10041            Watchdog.getInstance().setAllowRestart(allowRestart);
10042            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10043            synchronized (death) {
10044                while (who.isBinderAlive()) {
10045                    try {
10046                        death.wait();
10047                    } catch (InterruptedException e) {
10048                    }
10049                }
10050            }
10051            Watchdog.getInstance().setAllowRestart(true);
10052        }
10053    }
10054
10055    @Override
10056    public void restart() {
10057        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10058                != PackageManager.PERMISSION_GRANTED) {
10059            throw new SecurityException("Requires permission "
10060                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10061        }
10062
10063        Log.i(TAG, "Sending shutdown broadcast...");
10064
10065        BroadcastReceiver br = new BroadcastReceiver() {
10066            @Override public void onReceive(Context context, Intent intent) {
10067                // Now the broadcast is done, finish up the low-level shutdown.
10068                Log.i(TAG, "Shutting down activity manager...");
10069                shutdown(10000);
10070                Log.i(TAG, "Shutdown complete, restarting!");
10071                Process.killProcess(Process.myPid());
10072                System.exit(10);
10073            }
10074        };
10075
10076        // First send the high-level shut down broadcast.
10077        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10078        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10079        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10080        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10081        mContext.sendOrderedBroadcastAsUser(intent,
10082                UserHandle.ALL, null, br, mHandler, 0, null, null);
10083        */
10084        br.onReceive(mContext, intent);
10085    }
10086
10087    private long getLowRamTimeSinceIdle(long now) {
10088        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10089    }
10090
10091    @Override
10092    public void performIdleMaintenance() {
10093        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10094                != PackageManager.PERMISSION_GRANTED) {
10095            throw new SecurityException("Requires permission "
10096                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10097        }
10098
10099        synchronized (this) {
10100            final long now = SystemClock.uptimeMillis();
10101            final long timeSinceLastIdle = now - mLastIdleTime;
10102            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10103            mLastIdleTime = now;
10104            mLowRamTimeSinceLastIdle = 0;
10105            if (mLowRamStartTime != 0) {
10106                mLowRamStartTime = now;
10107            }
10108
10109            StringBuilder sb = new StringBuilder(128);
10110            sb.append("Idle maintenance over ");
10111            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10112            sb.append(" low RAM for ");
10113            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10114            Slog.i(TAG, sb.toString());
10115
10116            // If at least 1/3 of our time since the last idle period has been spent
10117            // with RAM low, then we want to kill processes.
10118            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10119
10120            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10121                ProcessRecord proc = mLruProcesses.get(i);
10122                if (proc.notCachedSinceIdle) {
10123                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10124                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10125                        if (doKilling && proc.initialIdlePss != 0
10126                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10127                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
10128                                    + " from " + proc.initialIdlePss + ")");
10129                        }
10130                    }
10131                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10132                    proc.notCachedSinceIdle = true;
10133                    proc.initialIdlePss = 0;
10134                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10135                            isSleeping(), now);
10136                }
10137            }
10138
10139            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10140            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10141        }
10142    }
10143
10144    private void retrieveSettings() {
10145        final ContentResolver resolver = mContext.getContentResolver();
10146        String debugApp = Settings.Global.getString(
10147            resolver, Settings.Global.DEBUG_APP);
10148        boolean waitForDebugger = Settings.Global.getInt(
10149            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10150        boolean alwaysFinishActivities = Settings.Global.getInt(
10151            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10152        boolean forceRtl = Settings.Global.getInt(
10153                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10154        // Transfer any global setting for forcing RTL layout, into a System Property
10155        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10156
10157        Configuration configuration = new Configuration();
10158        Settings.System.getConfiguration(resolver, configuration);
10159        if (forceRtl) {
10160            // This will take care of setting the correct layout direction flags
10161            configuration.setLayoutDirection(configuration.locale);
10162        }
10163
10164        synchronized (this) {
10165            mDebugApp = mOrigDebugApp = debugApp;
10166            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10167            mAlwaysFinishActivities = alwaysFinishActivities;
10168            // This happens before any activities are started, so we can
10169            // change mConfiguration in-place.
10170            updateConfigurationLocked(configuration, null, false, true);
10171            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10172        }
10173    }
10174
10175    public boolean testIsSystemReady() {
10176        // no need to synchronize(this) just to read & return the value
10177        return mSystemReady;
10178    }
10179
10180    private static File getCalledPreBootReceiversFile() {
10181        File dataDir = Environment.getDataDirectory();
10182        File systemDir = new File(dataDir, "system");
10183        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10184        return fname;
10185    }
10186
10187    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10188        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10189        File file = getCalledPreBootReceiversFile();
10190        FileInputStream fis = null;
10191        try {
10192            fis = new FileInputStream(file);
10193            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10194            int fvers = dis.readInt();
10195            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10196                String vers = dis.readUTF();
10197                String codename = dis.readUTF();
10198                String build = dis.readUTF();
10199                if (android.os.Build.VERSION.RELEASE.equals(vers)
10200                        && android.os.Build.VERSION.CODENAME.equals(codename)
10201                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10202                    int num = dis.readInt();
10203                    while (num > 0) {
10204                        num--;
10205                        String pkg = dis.readUTF();
10206                        String cls = dis.readUTF();
10207                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10208                    }
10209                }
10210            }
10211        } catch (FileNotFoundException e) {
10212        } catch (IOException e) {
10213            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10214        } finally {
10215            if (fis != null) {
10216                try {
10217                    fis.close();
10218                } catch (IOException e) {
10219                }
10220            }
10221        }
10222        return lastDoneReceivers;
10223    }
10224
10225    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10226        File file = getCalledPreBootReceiversFile();
10227        FileOutputStream fos = null;
10228        DataOutputStream dos = null;
10229        try {
10230            fos = new FileOutputStream(file);
10231            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10232            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10233            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10234            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10235            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10236            dos.writeInt(list.size());
10237            for (int i=0; i<list.size(); i++) {
10238                dos.writeUTF(list.get(i).getPackageName());
10239                dos.writeUTF(list.get(i).getClassName());
10240            }
10241        } catch (IOException e) {
10242            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10243            file.delete();
10244        } finally {
10245            FileUtils.sync(fos);
10246            if (dos != null) {
10247                try {
10248                    dos.close();
10249                } catch (IOException e) {
10250                    // TODO Auto-generated catch block
10251                    e.printStackTrace();
10252                }
10253            }
10254        }
10255    }
10256
10257    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10258            ArrayList<ComponentName> doneReceivers, int userId) {
10259        boolean waitingUpdate = false;
10260        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10261        List<ResolveInfo> ris = null;
10262        try {
10263            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10264                    intent, null, 0, userId);
10265        } catch (RemoteException e) {
10266        }
10267        if (ris != null) {
10268            for (int i=ris.size()-1; i>=0; i--) {
10269                if ((ris.get(i).activityInfo.applicationInfo.flags
10270                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10271                    ris.remove(i);
10272                }
10273            }
10274            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10275
10276            // For User 0, load the version number. When delivering to a new user, deliver
10277            // to all receivers.
10278            if (userId == UserHandle.USER_OWNER) {
10279                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10280                for (int i=0; i<ris.size(); i++) {
10281                    ActivityInfo ai = ris.get(i).activityInfo;
10282                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10283                    if (lastDoneReceivers.contains(comp)) {
10284                        // We already did the pre boot receiver for this app with the current
10285                        // platform version, so don't do it again...
10286                        ris.remove(i);
10287                        i--;
10288                        // ...however, do keep it as one that has been done, so we don't
10289                        // forget about it when rewriting the file of last done receivers.
10290                        doneReceivers.add(comp);
10291                    }
10292                }
10293            }
10294
10295            // If primary user, send broadcast to all available users, else just to userId
10296            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10297                    : new int[] { userId };
10298            for (int i = 0; i < ris.size(); i++) {
10299                ActivityInfo ai = ris.get(i).activityInfo;
10300                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10301                doneReceivers.add(comp);
10302                intent.setComponent(comp);
10303                for (int j=0; j<users.length; j++) {
10304                    IIntentReceiver finisher = null;
10305                    // On last receiver and user, set up a completion callback
10306                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10307                        finisher = new IIntentReceiver.Stub() {
10308                            public void performReceive(Intent intent, int resultCode,
10309                                    String data, Bundle extras, boolean ordered,
10310                                    boolean sticky, int sendingUser) {
10311                                // The raw IIntentReceiver interface is called
10312                                // with the AM lock held, so redispatch to
10313                                // execute our code without the lock.
10314                                mHandler.post(onFinishCallback);
10315                            }
10316                        };
10317                    }
10318                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10319                            + " for user " + users[j]);
10320                    broadcastIntentLocked(null, null, intent, null, finisher,
10321                            0, null, null, null, AppOpsManager.OP_NONE,
10322                            true, false, MY_PID, Process.SYSTEM_UID,
10323                            users[j]);
10324                    if (finisher != null) {
10325                        waitingUpdate = true;
10326                    }
10327                }
10328            }
10329        }
10330
10331        return waitingUpdate;
10332    }
10333
10334    public void systemReady(final Runnable goingCallback) {
10335        synchronized(this) {
10336            if (mSystemReady) {
10337                // If we're done calling all the receivers, run the next "boot phase" passed in
10338                // by the SystemServer
10339                if (goingCallback != null) {
10340                    goingCallback.run();
10341                }
10342                return;
10343            }
10344
10345            // Make sure we have the current profile info, since it is needed for
10346            // security checks.
10347            updateCurrentProfileIdsLocked();
10348
10349            if (mRecentTasks == null) {
10350                mRecentTasks = mTaskPersister.restoreTasksLocked();
10351                if (!mRecentTasks.isEmpty()) {
10352                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10353                }
10354                mTaskPersister.startPersisting();
10355            }
10356
10357            // Check to see if there are any update receivers to run.
10358            if (!mDidUpdate) {
10359                if (mWaitingUpdate) {
10360                    return;
10361                }
10362                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10363                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10364                    public void run() {
10365                        synchronized (ActivityManagerService.this) {
10366                            mDidUpdate = true;
10367                        }
10368                        writeLastDonePreBootReceivers(doneReceivers);
10369                        showBootMessage(mContext.getText(
10370                                R.string.android_upgrading_complete),
10371                                false);
10372                        systemReady(goingCallback);
10373                    }
10374                }, doneReceivers, UserHandle.USER_OWNER);
10375
10376                if (mWaitingUpdate) {
10377                    return;
10378                }
10379                mDidUpdate = true;
10380            }
10381
10382            mAppOpsService.systemReady();
10383            mSystemReady = true;
10384        }
10385
10386        ArrayList<ProcessRecord> procsToKill = null;
10387        synchronized(mPidsSelfLocked) {
10388            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10389                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10390                if (!isAllowedWhileBooting(proc.info)){
10391                    if (procsToKill == null) {
10392                        procsToKill = new ArrayList<ProcessRecord>();
10393                    }
10394                    procsToKill.add(proc);
10395                }
10396            }
10397        }
10398
10399        synchronized(this) {
10400            if (procsToKill != null) {
10401                for (int i=procsToKill.size()-1; i>=0; i--) {
10402                    ProcessRecord proc = procsToKill.get(i);
10403                    Slog.i(TAG, "Removing system update proc: " + proc);
10404                    removeProcessLocked(proc, true, false, "system update done");
10405                }
10406            }
10407
10408            // Now that we have cleaned up any update processes, we
10409            // are ready to start launching real processes and know that
10410            // we won't trample on them any more.
10411            mProcessesReady = true;
10412        }
10413
10414        Slog.i(TAG, "System now ready");
10415        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10416            SystemClock.uptimeMillis());
10417
10418        synchronized(this) {
10419            // Make sure we have no pre-ready processes sitting around.
10420
10421            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10422                ResolveInfo ri = mContext.getPackageManager()
10423                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10424                                STOCK_PM_FLAGS);
10425                CharSequence errorMsg = null;
10426                if (ri != null) {
10427                    ActivityInfo ai = ri.activityInfo;
10428                    ApplicationInfo app = ai.applicationInfo;
10429                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10430                        mTopAction = Intent.ACTION_FACTORY_TEST;
10431                        mTopData = null;
10432                        mTopComponent = new ComponentName(app.packageName,
10433                                ai.name);
10434                    } else {
10435                        errorMsg = mContext.getResources().getText(
10436                                com.android.internal.R.string.factorytest_not_system);
10437                    }
10438                } else {
10439                    errorMsg = mContext.getResources().getText(
10440                            com.android.internal.R.string.factorytest_no_action);
10441                }
10442                if (errorMsg != null) {
10443                    mTopAction = null;
10444                    mTopData = null;
10445                    mTopComponent = null;
10446                    Message msg = Message.obtain();
10447                    msg.what = SHOW_FACTORY_ERROR_MSG;
10448                    msg.getData().putCharSequence("msg", errorMsg);
10449                    mHandler.sendMessage(msg);
10450                }
10451            }
10452        }
10453
10454        retrieveSettings();
10455
10456        synchronized (this) {
10457            readGrantedUriPermissionsLocked();
10458        }
10459
10460        if (goingCallback != null) goingCallback.run();
10461
10462        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10463                Integer.toString(mCurrentUserId), mCurrentUserId);
10464        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10465                Integer.toString(mCurrentUserId), mCurrentUserId);
10466        mSystemServiceManager.startUser(mCurrentUserId);
10467
10468        synchronized (this) {
10469            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10470                try {
10471                    List apps = AppGlobals.getPackageManager().
10472                        getPersistentApplications(STOCK_PM_FLAGS);
10473                    if (apps != null) {
10474                        int N = apps.size();
10475                        int i;
10476                        for (i=0; i<N; i++) {
10477                            ApplicationInfo info
10478                                = (ApplicationInfo)apps.get(i);
10479                            if (info != null &&
10480                                    !info.packageName.equals("android")) {
10481                                addAppLocked(info, false, null /* ABI override */);
10482                            }
10483                        }
10484                    }
10485                } catch (RemoteException ex) {
10486                    // pm is in same process, this will never happen.
10487                }
10488            }
10489
10490            // Start up initial activity.
10491            mBooting = true;
10492
10493            try {
10494                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10495                    Message msg = Message.obtain();
10496                    msg.what = SHOW_UID_ERROR_MSG;
10497                    mHandler.sendMessage(msg);
10498                }
10499            } catch (RemoteException e) {
10500            }
10501
10502            long ident = Binder.clearCallingIdentity();
10503            try {
10504                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10505                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10506                        | Intent.FLAG_RECEIVER_FOREGROUND);
10507                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10508                broadcastIntentLocked(null, null, intent,
10509                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10510                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10511                intent = new Intent(Intent.ACTION_USER_STARTING);
10512                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10513                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10514                broadcastIntentLocked(null, null, intent,
10515                        null, new IIntentReceiver.Stub() {
10516                            @Override
10517                            public void performReceive(Intent intent, int resultCode, String data,
10518                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10519                                    throws RemoteException {
10520                            }
10521                        }, 0, null, null,
10522                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10523                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10524            } catch (Throwable t) {
10525                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10526            } finally {
10527                Binder.restoreCallingIdentity(ident);
10528            }
10529            mStackSupervisor.resumeTopActivitiesLocked();
10530            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10531        }
10532    }
10533
10534    private boolean makeAppCrashingLocked(ProcessRecord app,
10535            String shortMsg, String longMsg, String stackTrace) {
10536        app.crashing = true;
10537        app.crashingReport = generateProcessError(app,
10538                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10539        startAppProblemLocked(app);
10540        app.stopFreezingAllLocked();
10541        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10542    }
10543
10544    private void makeAppNotRespondingLocked(ProcessRecord app,
10545            String activity, String shortMsg, String longMsg) {
10546        app.notResponding = true;
10547        app.notRespondingReport = generateProcessError(app,
10548                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10549                activity, shortMsg, longMsg, null);
10550        startAppProblemLocked(app);
10551        app.stopFreezingAllLocked();
10552    }
10553
10554    /**
10555     * Generate a process error record, suitable for attachment to a ProcessRecord.
10556     *
10557     * @param app The ProcessRecord in which the error occurred.
10558     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10559     *                      ActivityManager.AppErrorStateInfo
10560     * @param activity The activity associated with the crash, if known.
10561     * @param shortMsg Short message describing the crash.
10562     * @param longMsg Long message describing the crash.
10563     * @param stackTrace Full crash stack trace, may be null.
10564     *
10565     * @return Returns a fully-formed AppErrorStateInfo record.
10566     */
10567    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10568            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10569        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10570
10571        report.condition = condition;
10572        report.processName = app.processName;
10573        report.pid = app.pid;
10574        report.uid = app.info.uid;
10575        report.tag = activity;
10576        report.shortMsg = shortMsg;
10577        report.longMsg = longMsg;
10578        report.stackTrace = stackTrace;
10579
10580        return report;
10581    }
10582
10583    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10584        synchronized (this) {
10585            app.crashing = false;
10586            app.crashingReport = null;
10587            app.notResponding = false;
10588            app.notRespondingReport = null;
10589            if (app.anrDialog == fromDialog) {
10590                app.anrDialog = null;
10591            }
10592            if (app.waitDialog == fromDialog) {
10593                app.waitDialog = null;
10594            }
10595            if (app.pid > 0 && app.pid != MY_PID) {
10596                handleAppCrashLocked(app, null, null, null);
10597                killUnneededProcessLocked(app, "user request after error");
10598            }
10599        }
10600    }
10601
10602    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10603            String stackTrace) {
10604        long now = SystemClock.uptimeMillis();
10605
10606        Long crashTime;
10607        if (!app.isolated) {
10608            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10609        } else {
10610            crashTime = null;
10611        }
10612        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10613            // This process loses!
10614            Slog.w(TAG, "Process " + app.info.processName
10615                    + " has crashed too many times: killing!");
10616            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10617                    app.userId, app.info.processName, app.uid);
10618            mStackSupervisor.handleAppCrashLocked(app);
10619            if (!app.persistent) {
10620                // We don't want to start this process again until the user
10621                // explicitly does so...  but for persistent process, we really
10622                // need to keep it running.  If a persistent process is actually
10623                // repeatedly crashing, then badness for everyone.
10624                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10625                        app.info.processName);
10626                if (!app.isolated) {
10627                    // XXX We don't have a way to mark isolated processes
10628                    // as bad, since they don't have a peristent identity.
10629                    mBadProcesses.put(app.info.processName, app.uid,
10630                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10631                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10632                }
10633                app.bad = true;
10634                app.removed = true;
10635                // Don't let services in this process be restarted and potentially
10636                // annoy the user repeatedly.  Unless it is persistent, since those
10637                // processes run critical code.
10638                removeProcessLocked(app, false, false, "crash");
10639                mStackSupervisor.resumeTopActivitiesLocked();
10640                return false;
10641            }
10642            mStackSupervisor.resumeTopActivitiesLocked();
10643        } else {
10644            mStackSupervisor.finishTopRunningActivityLocked(app);
10645        }
10646
10647        // Bump up the crash count of any services currently running in the proc.
10648        for (int i=app.services.size()-1; i>=0; i--) {
10649            // Any services running in the application need to be placed
10650            // back in the pending list.
10651            ServiceRecord sr = app.services.valueAt(i);
10652            sr.crashCount++;
10653        }
10654
10655        // If the crashing process is what we consider to be the "home process" and it has been
10656        // replaced by a third-party app, clear the package preferred activities from packages
10657        // with a home activity running in the process to prevent a repeatedly crashing app
10658        // from blocking the user to manually clear the list.
10659        final ArrayList<ActivityRecord> activities = app.activities;
10660        if (app == mHomeProcess && activities.size() > 0
10661                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10662            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10663                final ActivityRecord r = activities.get(activityNdx);
10664                if (r.isHomeActivity()) {
10665                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10666                    try {
10667                        ActivityThread.getPackageManager()
10668                                .clearPackagePreferredActivities(r.packageName);
10669                    } catch (RemoteException c) {
10670                        // pm is in same process, this will never happen.
10671                    }
10672                }
10673            }
10674        }
10675
10676        if (!app.isolated) {
10677            // XXX Can't keep track of crash times for isolated processes,
10678            // because they don't have a perisistent identity.
10679            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10680        }
10681
10682        if (app.crashHandler != null) mHandler.post(app.crashHandler);
10683        return true;
10684    }
10685
10686    void startAppProblemLocked(ProcessRecord app) {
10687        // If this app is not running under the current user, then we
10688        // can't give it a report button because that would require
10689        // launching the report UI under a different user.
10690        app.errorReportReceiver = null;
10691
10692        for (int userId : mCurrentProfileIds) {
10693            if (app.userId == userId) {
10694                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10695                        mContext, app.info.packageName, app.info.flags);
10696            }
10697        }
10698        skipCurrentReceiverLocked(app);
10699    }
10700
10701    void skipCurrentReceiverLocked(ProcessRecord app) {
10702        for (BroadcastQueue queue : mBroadcastQueues) {
10703            queue.skipCurrentReceiverLocked(app);
10704        }
10705    }
10706
10707    /**
10708     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10709     * The application process will exit immediately after this call returns.
10710     * @param app object of the crashing app, null for the system server
10711     * @param crashInfo describing the exception
10712     */
10713    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10714        ProcessRecord r = findAppProcess(app, "Crash");
10715        final String processName = app == null ? "system_server"
10716                : (r == null ? "unknown" : r.processName);
10717
10718        handleApplicationCrashInner("crash", r, processName, crashInfo);
10719    }
10720
10721    /* Native crash reporting uses this inner version because it needs to be somewhat
10722     * decoupled from the AM-managed cleanup lifecycle
10723     */
10724    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10725            ApplicationErrorReport.CrashInfo crashInfo) {
10726        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10727                UserHandle.getUserId(Binder.getCallingUid()), processName,
10728                r == null ? -1 : r.info.flags,
10729                crashInfo.exceptionClassName,
10730                crashInfo.exceptionMessage,
10731                crashInfo.throwFileName,
10732                crashInfo.throwLineNumber);
10733
10734        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10735
10736        crashApplication(r, crashInfo);
10737    }
10738
10739    public void handleApplicationStrictModeViolation(
10740            IBinder app,
10741            int violationMask,
10742            StrictMode.ViolationInfo info) {
10743        ProcessRecord r = findAppProcess(app, "StrictMode");
10744        if (r == null) {
10745            return;
10746        }
10747
10748        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10749            Integer stackFingerprint = info.hashCode();
10750            boolean logIt = true;
10751            synchronized (mAlreadyLoggedViolatedStacks) {
10752                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10753                    logIt = false;
10754                    // TODO: sub-sample into EventLog for these, with
10755                    // the info.durationMillis?  Then we'd get
10756                    // the relative pain numbers, without logging all
10757                    // the stack traces repeatedly.  We'd want to do
10758                    // likewise in the client code, which also does
10759                    // dup suppression, before the Binder call.
10760                } else {
10761                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10762                        mAlreadyLoggedViolatedStacks.clear();
10763                    }
10764                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10765                }
10766            }
10767            if (logIt) {
10768                logStrictModeViolationToDropBox(r, info);
10769            }
10770        }
10771
10772        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10773            AppErrorResult result = new AppErrorResult();
10774            synchronized (this) {
10775                final long origId = Binder.clearCallingIdentity();
10776
10777                Message msg = Message.obtain();
10778                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10779                HashMap<String, Object> data = new HashMap<String, Object>();
10780                data.put("result", result);
10781                data.put("app", r);
10782                data.put("violationMask", violationMask);
10783                data.put("info", info);
10784                msg.obj = data;
10785                mHandler.sendMessage(msg);
10786
10787                Binder.restoreCallingIdentity(origId);
10788            }
10789            int res = result.get();
10790            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10791        }
10792    }
10793
10794    // Depending on the policy in effect, there could be a bunch of
10795    // these in quick succession so we try to batch these together to
10796    // minimize disk writes, number of dropbox entries, and maximize
10797    // compression, by having more fewer, larger records.
10798    private void logStrictModeViolationToDropBox(
10799            ProcessRecord process,
10800            StrictMode.ViolationInfo info) {
10801        if (info == null) {
10802            return;
10803        }
10804        final boolean isSystemApp = process == null ||
10805                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10806                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10807        final String processName = process == null ? "unknown" : process.processName;
10808        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10809        final DropBoxManager dbox = (DropBoxManager)
10810                mContext.getSystemService(Context.DROPBOX_SERVICE);
10811
10812        // Exit early if the dropbox isn't configured to accept this report type.
10813        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10814
10815        boolean bufferWasEmpty;
10816        boolean needsFlush;
10817        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10818        synchronized (sb) {
10819            bufferWasEmpty = sb.length() == 0;
10820            appendDropBoxProcessHeaders(process, processName, sb);
10821            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10822            sb.append("System-App: ").append(isSystemApp).append("\n");
10823            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10824            if (info.violationNumThisLoop != 0) {
10825                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10826            }
10827            if (info.numAnimationsRunning != 0) {
10828                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10829            }
10830            if (info.broadcastIntentAction != null) {
10831                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10832            }
10833            if (info.durationMillis != -1) {
10834                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10835            }
10836            if (info.numInstances != -1) {
10837                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10838            }
10839            if (info.tags != null) {
10840                for (String tag : info.tags) {
10841                    sb.append("Span-Tag: ").append(tag).append("\n");
10842                }
10843            }
10844            sb.append("\n");
10845            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10846                sb.append(info.crashInfo.stackTrace);
10847            }
10848            sb.append("\n");
10849
10850            // Only buffer up to ~64k.  Various logging bits truncate
10851            // things at 128k.
10852            needsFlush = (sb.length() > 64 * 1024);
10853        }
10854
10855        // Flush immediately if the buffer's grown too large, or this
10856        // is a non-system app.  Non-system apps are isolated with a
10857        // different tag & policy and not batched.
10858        //
10859        // Batching is useful during internal testing with
10860        // StrictMode settings turned up high.  Without batching,
10861        // thousands of separate files could be created on boot.
10862        if (!isSystemApp || needsFlush) {
10863            new Thread("Error dump: " + dropboxTag) {
10864                @Override
10865                public void run() {
10866                    String report;
10867                    synchronized (sb) {
10868                        report = sb.toString();
10869                        sb.delete(0, sb.length());
10870                        sb.trimToSize();
10871                    }
10872                    if (report.length() != 0) {
10873                        dbox.addText(dropboxTag, report);
10874                    }
10875                }
10876            }.start();
10877            return;
10878        }
10879
10880        // System app batching:
10881        if (!bufferWasEmpty) {
10882            // An existing dropbox-writing thread is outstanding, so
10883            // we don't need to start it up.  The existing thread will
10884            // catch the buffer appends we just did.
10885            return;
10886        }
10887
10888        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10889        // (After this point, we shouldn't access AMS internal data structures.)
10890        new Thread("Error dump: " + dropboxTag) {
10891            @Override
10892            public void run() {
10893                // 5 second sleep to let stacks arrive and be batched together
10894                try {
10895                    Thread.sleep(5000);  // 5 seconds
10896                } catch (InterruptedException e) {}
10897
10898                String errorReport;
10899                synchronized (mStrictModeBuffer) {
10900                    errorReport = mStrictModeBuffer.toString();
10901                    if (errorReport.length() == 0) {
10902                        return;
10903                    }
10904                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10905                    mStrictModeBuffer.trimToSize();
10906                }
10907                dbox.addText(dropboxTag, errorReport);
10908            }
10909        }.start();
10910    }
10911
10912    /**
10913     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10914     * @param app object of the crashing app, null for the system server
10915     * @param tag reported by the caller
10916     * @param crashInfo describing the context of the error
10917     * @return true if the process should exit immediately (WTF is fatal)
10918     */
10919    public boolean handleApplicationWtf(IBinder app, String tag,
10920            ApplicationErrorReport.CrashInfo crashInfo) {
10921        ProcessRecord r = findAppProcess(app, "WTF");
10922        final String processName = app == null ? "system_server"
10923                : (r == null ? "unknown" : r.processName);
10924
10925        EventLog.writeEvent(EventLogTags.AM_WTF,
10926                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10927                processName,
10928                r == null ? -1 : r.info.flags,
10929                tag, crashInfo.exceptionMessage);
10930
10931        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10932
10933        if (r != null && r.pid != Process.myPid() &&
10934                Settings.Global.getInt(mContext.getContentResolver(),
10935                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10936            crashApplication(r, crashInfo);
10937            return true;
10938        } else {
10939            return false;
10940        }
10941    }
10942
10943    /**
10944     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10945     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10946     */
10947    private ProcessRecord findAppProcess(IBinder app, String reason) {
10948        if (app == null) {
10949            return null;
10950        }
10951
10952        synchronized (this) {
10953            final int NP = mProcessNames.getMap().size();
10954            for (int ip=0; ip<NP; ip++) {
10955                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10956                final int NA = apps.size();
10957                for (int ia=0; ia<NA; ia++) {
10958                    ProcessRecord p = apps.valueAt(ia);
10959                    if (p.thread != null && p.thread.asBinder() == app) {
10960                        return p;
10961                    }
10962                }
10963            }
10964
10965            Slog.w(TAG, "Can't find mystery application for " + reason
10966                    + " from pid=" + Binder.getCallingPid()
10967                    + " uid=" + Binder.getCallingUid() + ": " + app);
10968            return null;
10969        }
10970    }
10971
10972    /**
10973     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10974     * to append various headers to the dropbox log text.
10975     */
10976    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10977            StringBuilder sb) {
10978        // Watchdog thread ends up invoking this function (with
10979        // a null ProcessRecord) to add the stack file to dropbox.
10980        // Do not acquire a lock on this (am) in such cases, as it
10981        // could cause a potential deadlock, if and when watchdog
10982        // is invoked due to unavailability of lock on am and it
10983        // would prevent watchdog from killing system_server.
10984        if (process == null) {
10985            sb.append("Process: ").append(processName).append("\n");
10986            return;
10987        }
10988        // Note: ProcessRecord 'process' is guarded by the service
10989        // instance.  (notably process.pkgList, which could otherwise change
10990        // concurrently during execution of this method)
10991        synchronized (this) {
10992            sb.append("Process: ").append(processName).append("\n");
10993            int flags = process.info.flags;
10994            IPackageManager pm = AppGlobals.getPackageManager();
10995            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10996            for (int ip=0; ip<process.pkgList.size(); ip++) {
10997                String pkg = process.pkgList.keyAt(ip);
10998                sb.append("Package: ").append(pkg);
10999                try {
11000                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11001                    if (pi != null) {
11002                        sb.append(" v").append(pi.versionCode);
11003                        if (pi.versionName != null) {
11004                            sb.append(" (").append(pi.versionName).append(")");
11005                        }
11006                    }
11007                } catch (RemoteException e) {
11008                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11009                }
11010                sb.append("\n");
11011            }
11012        }
11013    }
11014
11015    private static String processClass(ProcessRecord process) {
11016        if (process == null || process.pid == MY_PID) {
11017            return "system_server";
11018        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11019            return "system_app";
11020        } else {
11021            return "data_app";
11022        }
11023    }
11024
11025    /**
11026     * Write a description of an error (crash, WTF, ANR) to the drop box.
11027     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11028     * @param process which caused the error, null means the system server
11029     * @param activity which triggered the error, null if unknown
11030     * @param parent activity related to the error, null if unknown
11031     * @param subject line related to the error, null if absent
11032     * @param report in long form describing the error, null if absent
11033     * @param logFile to include in the report, null if none
11034     * @param crashInfo giving an application stack trace, null if absent
11035     */
11036    public void addErrorToDropBox(String eventType,
11037            ProcessRecord process, String processName, ActivityRecord activity,
11038            ActivityRecord parent, String subject,
11039            final String report, final File logFile,
11040            final ApplicationErrorReport.CrashInfo crashInfo) {
11041        // NOTE -- this must never acquire the ActivityManagerService lock,
11042        // otherwise the watchdog may be prevented from resetting the system.
11043
11044        final String dropboxTag = processClass(process) + "_" + eventType;
11045        final DropBoxManager dbox = (DropBoxManager)
11046                mContext.getSystemService(Context.DROPBOX_SERVICE);
11047
11048        // Exit early if the dropbox isn't configured to accept this report type.
11049        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11050
11051        final StringBuilder sb = new StringBuilder(1024);
11052        appendDropBoxProcessHeaders(process, processName, sb);
11053        if (activity != null) {
11054            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11055        }
11056        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11057            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11058        }
11059        if (parent != null && parent != activity) {
11060            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11061        }
11062        if (subject != null) {
11063            sb.append("Subject: ").append(subject).append("\n");
11064        }
11065        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11066        if (Debug.isDebuggerConnected()) {
11067            sb.append("Debugger: Connected\n");
11068        }
11069        sb.append("\n");
11070
11071        // Do the rest in a worker thread to avoid blocking the caller on I/O
11072        // (After this point, we shouldn't access AMS internal data structures.)
11073        Thread worker = new Thread("Error dump: " + dropboxTag) {
11074            @Override
11075            public void run() {
11076                if (report != null) {
11077                    sb.append(report);
11078                }
11079                if (logFile != null) {
11080                    try {
11081                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11082                                    "\n\n[[TRUNCATED]]"));
11083                    } catch (IOException e) {
11084                        Slog.e(TAG, "Error reading " + logFile, e);
11085                    }
11086                }
11087                if (crashInfo != null && crashInfo.stackTrace != null) {
11088                    sb.append(crashInfo.stackTrace);
11089                }
11090
11091                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11092                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11093                if (lines > 0) {
11094                    sb.append("\n");
11095
11096                    // Merge several logcat streams, and take the last N lines
11097                    InputStreamReader input = null;
11098                    try {
11099                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11100                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11101                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11102
11103                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11104                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11105                        input = new InputStreamReader(logcat.getInputStream());
11106
11107                        int num;
11108                        char[] buf = new char[8192];
11109                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11110                    } catch (IOException e) {
11111                        Slog.e(TAG, "Error running logcat", e);
11112                    } finally {
11113                        if (input != null) try { input.close(); } catch (IOException e) {}
11114                    }
11115                }
11116
11117                dbox.addText(dropboxTag, sb.toString());
11118            }
11119        };
11120
11121        if (process == null) {
11122            // If process is null, we are being called from some internal code
11123            // and may be about to die -- run this synchronously.
11124            worker.run();
11125        } else {
11126            worker.start();
11127        }
11128    }
11129
11130    /**
11131     * Bring up the "unexpected error" dialog box for a crashing app.
11132     * Deal with edge cases (intercepts from instrumented applications,
11133     * ActivityController, error intent receivers, that sort of thing).
11134     * @param r the application crashing
11135     * @param crashInfo describing the failure
11136     */
11137    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11138        long timeMillis = System.currentTimeMillis();
11139        String shortMsg = crashInfo.exceptionClassName;
11140        String longMsg = crashInfo.exceptionMessage;
11141        String stackTrace = crashInfo.stackTrace;
11142        if (shortMsg != null && longMsg != null) {
11143            longMsg = shortMsg + ": " + longMsg;
11144        } else if (shortMsg != null) {
11145            longMsg = shortMsg;
11146        }
11147
11148        AppErrorResult result = new AppErrorResult();
11149        synchronized (this) {
11150            if (mController != null) {
11151                try {
11152                    String name = r != null ? r.processName : null;
11153                    int pid = r != null ? r.pid : Binder.getCallingPid();
11154                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11155                    if (!mController.appCrashed(name, pid,
11156                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11157                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11158                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11159                            Slog.w(TAG, "Skip killing native crashed app " + name
11160                                    + "(" + pid + ") during testing");
11161                        } else {
11162                            Slog.w(TAG, "Force-killing crashed app " + name
11163                                    + " at watcher's request");
11164                            Process.killProcess(pid);
11165                            if (r != null) {
11166                                Process.killProcessGroup(uid, pid);
11167                            }
11168                        }
11169                        return;
11170                    }
11171                } catch (RemoteException e) {
11172                    mController = null;
11173                    Watchdog.getInstance().setActivityController(null);
11174                }
11175            }
11176
11177            final long origId = Binder.clearCallingIdentity();
11178
11179            // If this process is running instrumentation, finish it.
11180            if (r != null && r.instrumentationClass != null) {
11181                Slog.w(TAG, "Error in app " + r.processName
11182                      + " running instrumentation " + r.instrumentationClass + ":");
11183                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11184                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11185                Bundle info = new Bundle();
11186                info.putString("shortMsg", shortMsg);
11187                info.putString("longMsg", longMsg);
11188                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11189                Binder.restoreCallingIdentity(origId);
11190                return;
11191            }
11192
11193            // If we can't identify the process or it's already exceeded its crash quota,
11194            // quit right away without showing a crash dialog.
11195            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11196                Binder.restoreCallingIdentity(origId);
11197                return;
11198            }
11199
11200            Message msg = Message.obtain();
11201            msg.what = SHOW_ERROR_MSG;
11202            HashMap data = new HashMap();
11203            data.put("result", result);
11204            data.put("app", r);
11205            msg.obj = data;
11206            mHandler.sendMessage(msg);
11207
11208            Binder.restoreCallingIdentity(origId);
11209        }
11210
11211        int res = result.get();
11212
11213        Intent appErrorIntent = null;
11214        synchronized (this) {
11215            if (r != null && !r.isolated) {
11216                // XXX Can't keep track of crash time for isolated processes,
11217                // since they don't have a persistent identity.
11218                mProcessCrashTimes.put(r.info.processName, r.uid,
11219                        SystemClock.uptimeMillis());
11220            }
11221            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11222                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11223            }
11224        }
11225
11226        if (appErrorIntent != null) {
11227            try {
11228                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11229            } catch (ActivityNotFoundException e) {
11230                Slog.w(TAG, "bug report receiver dissappeared", e);
11231            }
11232        }
11233    }
11234
11235    Intent createAppErrorIntentLocked(ProcessRecord r,
11236            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11237        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11238        if (report == null) {
11239            return null;
11240        }
11241        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11242        result.setComponent(r.errorReportReceiver);
11243        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11244        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11245        return result;
11246    }
11247
11248    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11249            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11250        if (r.errorReportReceiver == null) {
11251            return null;
11252        }
11253
11254        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11255            return null;
11256        }
11257
11258        ApplicationErrorReport report = new ApplicationErrorReport();
11259        report.packageName = r.info.packageName;
11260        report.installerPackageName = r.errorReportReceiver.getPackageName();
11261        report.processName = r.processName;
11262        report.time = timeMillis;
11263        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11264
11265        if (r.crashing || r.forceCrashReport) {
11266            report.type = ApplicationErrorReport.TYPE_CRASH;
11267            report.crashInfo = crashInfo;
11268        } else if (r.notResponding) {
11269            report.type = ApplicationErrorReport.TYPE_ANR;
11270            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11271
11272            report.anrInfo.activity = r.notRespondingReport.tag;
11273            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11274            report.anrInfo.info = r.notRespondingReport.longMsg;
11275        }
11276
11277        return report;
11278    }
11279
11280    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11281        enforceNotIsolatedCaller("getProcessesInErrorState");
11282        // assume our apps are happy - lazy create the list
11283        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11284
11285        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11286                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11287        int userId = UserHandle.getUserId(Binder.getCallingUid());
11288
11289        synchronized (this) {
11290
11291            // iterate across all processes
11292            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11293                ProcessRecord app = mLruProcesses.get(i);
11294                if (!allUsers && app.userId != userId) {
11295                    continue;
11296                }
11297                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11298                    // This one's in trouble, so we'll generate a report for it
11299                    // crashes are higher priority (in case there's a crash *and* an anr)
11300                    ActivityManager.ProcessErrorStateInfo report = null;
11301                    if (app.crashing) {
11302                        report = app.crashingReport;
11303                    } else if (app.notResponding) {
11304                        report = app.notRespondingReport;
11305                    }
11306
11307                    if (report != null) {
11308                        if (errList == null) {
11309                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11310                        }
11311                        errList.add(report);
11312                    } else {
11313                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11314                                " crashing = " + app.crashing +
11315                                " notResponding = " + app.notResponding);
11316                    }
11317                }
11318            }
11319        }
11320
11321        return errList;
11322    }
11323
11324    static int procStateToImportance(int procState, int memAdj,
11325            ActivityManager.RunningAppProcessInfo currApp) {
11326        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11327        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11328            currApp.lru = memAdj;
11329        } else {
11330            currApp.lru = 0;
11331        }
11332        return imp;
11333    }
11334
11335    private void fillInProcMemInfo(ProcessRecord app,
11336            ActivityManager.RunningAppProcessInfo outInfo) {
11337        outInfo.pid = app.pid;
11338        outInfo.uid = app.info.uid;
11339        if (mHeavyWeightProcess == app) {
11340            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11341        }
11342        if (app.persistent) {
11343            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11344        }
11345        if (app.activities.size() > 0) {
11346            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11347        }
11348        outInfo.lastTrimLevel = app.trimMemoryLevel;
11349        int adj = app.curAdj;
11350        int procState = app.curProcState;
11351        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11352        outInfo.importanceReasonCode = app.adjTypeCode;
11353        outInfo.processState = app.curProcState;
11354    }
11355
11356    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11357        enforceNotIsolatedCaller("getRunningAppProcesses");
11358        // Lazy instantiation of list
11359        List<ActivityManager.RunningAppProcessInfo> runList = null;
11360        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11361                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11362        int userId = UserHandle.getUserId(Binder.getCallingUid());
11363        synchronized (this) {
11364            // Iterate across all processes
11365            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11366                ProcessRecord app = mLruProcesses.get(i);
11367                if (!allUsers && app.userId != userId) {
11368                    continue;
11369                }
11370                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11371                    // Generate process state info for running application
11372                    ActivityManager.RunningAppProcessInfo currApp =
11373                        new ActivityManager.RunningAppProcessInfo(app.processName,
11374                                app.pid, app.getPackageList());
11375                    fillInProcMemInfo(app, currApp);
11376                    if (app.adjSource instanceof ProcessRecord) {
11377                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11378                        currApp.importanceReasonImportance =
11379                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11380                                        app.adjSourceProcState);
11381                    } else if (app.adjSource instanceof ActivityRecord) {
11382                        ActivityRecord r = (ActivityRecord)app.adjSource;
11383                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11384                    }
11385                    if (app.adjTarget instanceof ComponentName) {
11386                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11387                    }
11388                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11389                    //        + " lru=" + currApp.lru);
11390                    if (runList == null) {
11391                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11392                    }
11393                    runList.add(currApp);
11394                }
11395            }
11396        }
11397        return runList;
11398    }
11399
11400    public List<ApplicationInfo> getRunningExternalApplications() {
11401        enforceNotIsolatedCaller("getRunningExternalApplications");
11402        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11403        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11404        if (runningApps != null && runningApps.size() > 0) {
11405            Set<String> extList = new HashSet<String>();
11406            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11407                if (app.pkgList != null) {
11408                    for (String pkg : app.pkgList) {
11409                        extList.add(pkg);
11410                    }
11411                }
11412            }
11413            IPackageManager pm = AppGlobals.getPackageManager();
11414            for (String pkg : extList) {
11415                try {
11416                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11417                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11418                        retList.add(info);
11419                    }
11420                } catch (RemoteException e) {
11421                }
11422            }
11423        }
11424        return retList;
11425    }
11426
11427    @Override
11428    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11429        enforceNotIsolatedCaller("getMyMemoryState");
11430        synchronized (this) {
11431            ProcessRecord proc;
11432            synchronized (mPidsSelfLocked) {
11433                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11434            }
11435            fillInProcMemInfo(proc, outInfo);
11436        }
11437    }
11438
11439    @Override
11440    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11441        if (checkCallingPermission(android.Manifest.permission.DUMP)
11442                != PackageManager.PERMISSION_GRANTED) {
11443            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11444                    + Binder.getCallingPid()
11445                    + ", uid=" + Binder.getCallingUid()
11446                    + " without permission "
11447                    + android.Manifest.permission.DUMP);
11448            return;
11449        }
11450
11451        boolean dumpAll = false;
11452        boolean dumpClient = false;
11453        String dumpPackage = null;
11454
11455        int opti = 0;
11456        while (opti < args.length) {
11457            String opt = args[opti];
11458            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11459                break;
11460            }
11461            opti++;
11462            if ("-a".equals(opt)) {
11463                dumpAll = true;
11464            } else if ("-c".equals(opt)) {
11465                dumpClient = true;
11466            } else if ("-h".equals(opt)) {
11467                pw.println("Activity manager dump options:");
11468                pw.println("  [-a] [-c] [-h] [cmd] ...");
11469                pw.println("  cmd may be one of:");
11470                pw.println("    a[ctivities]: activity stack state");
11471                pw.println("    r[recents]: recent activities state");
11472                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11473                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11474                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11475                pw.println("    o[om]: out of memory management");
11476                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11477                pw.println("    provider [COMP_SPEC]: provider client-side state");
11478                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11479                pw.println("    service [COMP_SPEC]: service client-side state");
11480                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11481                pw.println("    all: dump all activities");
11482                pw.println("    top: dump the top activity");
11483                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11484                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11485                pw.println("    a partial substring in a component name, a");
11486                pw.println("    hex object identifier.");
11487                pw.println("  -a: include all available server state.");
11488                pw.println("  -c: include client state.");
11489                return;
11490            } else {
11491                pw.println("Unknown argument: " + opt + "; use -h for help");
11492            }
11493        }
11494
11495        long origId = Binder.clearCallingIdentity();
11496        boolean more = false;
11497        // Is the caller requesting to dump a particular piece of data?
11498        if (opti < args.length) {
11499            String cmd = args[opti];
11500            opti++;
11501            if ("activities".equals(cmd) || "a".equals(cmd)) {
11502                synchronized (this) {
11503                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11504                }
11505            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
11506                synchronized (this) {
11507                    dumpRecentsLocked(fd, pw, args, opti, true, null);
11508                }
11509            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11510                String[] newArgs;
11511                String name;
11512                if (opti >= args.length) {
11513                    name = null;
11514                    newArgs = EMPTY_STRING_ARRAY;
11515                } else {
11516                    name = args[opti];
11517                    opti++;
11518                    newArgs = new String[args.length - opti];
11519                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11520                            args.length - opti);
11521                }
11522                synchronized (this) {
11523                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11524                }
11525            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11526                String[] newArgs;
11527                String name;
11528                if (opti >= args.length) {
11529                    name = null;
11530                    newArgs = EMPTY_STRING_ARRAY;
11531                } else {
11532                    name = args[opti];
11533                    opti++;
11534                    newArgs = new String[args.length - opti];
11535                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11536                            args.length - opti);
11537                }
11538                synchronized (this) {
11539                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11540                }
11541            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11542                String[] newArgs;
11543                String name;
11544                if (opti >= args.length) {
11545                    name = null;
11546                    newArgs = EMPTY_STRING_ARRAY;
11547                } else {
11548                    name = args[opti];
11549                    opti++;
11550                    newArgs = new String[args.length - opti];
11551                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11552                            args.length - opti);
11553                }
11554                synchronized (this) {
11555                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11556                }
11557            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11558                synchronized (this) {
11559                    dumpOomLocked(fd, pw, args, opti, true);
11560                }
11561            } else if ("provider".equals(cmd)) {
11562                String[] newArgs;
11563                String name;
11564                if (opti >= args.length) {
11565                    name = null;
11566                    newArgs = EMPTY_STRING_ARRAY;
11567                } else {
11568                    name = args[opti];
11569                    opti++;
11570                    newArgs = new String[args.length - opti];
11571                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11572                }
11573                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11574                    pw.println("No providers match: " + name);
11575                    pw.println("Use -h for help.");
11576                }
11577            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11578                synchronized (this) {
11579                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11580                }
11581            } else if ("service".equals(cmd)) {
11582                String[] newArgs;
11583                String name;
11584                if (opti >= args.length) {
11585                    name = null;
11586                    newArgs = EMPTY_STRING_ARRAY;
11587                } else {
11588                    name = args[opti];
11589                    opti++;
11590                    newArgs = new String[args.length - opti];
11591                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11592                            args.length - opti);
11593                }
11594                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11595                    pw.println("No services match: " + name);
11596                    pw.println("Use -h for help.");
11597                }
11598            } else if ("package".equals(cmd)) {
11599                String[] newArgs;
11600                if (opti >= args.length) {
11601                    pw.println("package: no package name specified");
11602                    pw.println("Use -h for help.");
11603                } else {
11604                    dumpPackage = args[opti];
11605                    opti++;
11606                    newArgs = new String[args.length - opti];
11607                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11608                            args.length - opti);
11609                    args = newArgs;
11610                    opti = 0;
11611                    more = true;
11612                }
11613            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11614                synchronized (this) {
11615                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11616                }
11617            } else {
11618                // Dumping a single activity?
11619                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11620                    pw.println("Bad activity command, or no activities match: " + cmd);
11621                    pw.println("Use -h for help.");
11622                }
11623            }
11624            if (!more) {
11625                Binder.restoreCallingIdentity(origId);
11626                return;
11627            }
11628        }
11629
11630        // No piece of data specified, dump everything.
11631        synchronized (this) {
11632            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11633            pw.println();
11634            if (dumpAll) {
11635                pw.println("-------------------------------------------------------------------------------");
11636            }
11637            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11638            pw.println();
11639            if (dumpAll) {
11640                pw.println("-------------------------------------------------------------------------------");
11641            }
11642            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11643            pw.println();
11644            if (dumpAll) {
11645                pw.println("-------------------------------------------------------------------------------");
11646            }
11647            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11648            pw.println();
11649            if (dumpAll) {
11650                pw.println("-------------------------------------------------------------------------------");
11651            }
11652            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11653            pw.println();
11654            if (dumpAll) {
11655                pw.println("-------------------------------------------------------------------------------");
11656            }
11657            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11658            pw.println();
11659            if (dumpAll) {
11660                pw.println("-------------------------------------------------------------------------------");
11661            }
11662            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11663        }
11664        Binder.restoreCallingIdentity(origId);
11665    }
11666
11667    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11668            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11669        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11670
11671        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11672                dumpPackage);
11673        boolean needSep = printedAnything;
11674
11675        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11676                dumpPackage, needSep, "  mFocusedActivity: ");
11677        if (printed) {
11678            printedAnything = true;
11679            needSep = false;
11680        }
11681
11682        if (dumpPackage == null) {
11683            if (needSep) {
11684                pw.println();
11685            }
11686            needSep = true;
11687            printedAnything = true;
11688            mStackSupervisor.dump(pw, "  ");
11689        }
11690
11691        if (!printedAnything) {
11692            pw.println("  (nothing)");
11693        }
11694    }
11695
11696    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11697            int opti, boolean dumpAll, String dumpPackage) {
11698        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
11699
11700        boolean printedAnything = false;
11701
11702        if (mRecentTasks.size() > 0) {
11703            boolean printedHeader = false;
11704
11705            final int N = mRecentTasks.size();
11706            for (int i=0; i<N; i++) {
11707                TaskRecord tr = mRecentTasks.get(i);
11708                if (dumpPackage != null) {
11709                    if (tr.realActivity == null ||
11710                            !dumpPackage.equals(tr.realActivity)) {
11711                        continue;
11712                    }
11713                }
11714                if (!printedHeader) {
11715                    pw.println("  Recent tasks:");
11716                    printedHeader = true;
11717                    printedAnything = true;
11718                }
11719                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11720                        pw.println(tr);
11721                if (dumpAll) {
11722                    mRecentTasks.get(i).dump(pw, "    ");
11723                }
11724            }
11725        }
11726
11727        if (!printedAnything) {
11728            pw.println("  (nothing)");
11729        }
11730    }
11731
11732    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11733            int opti, boolean dumpAll, String dumpPackage) {
11734        boolean needSep = false;
11735        boolean printedAnything = false;
11736        int numPers = 0;
11737
11738        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11739
11740        if (dumpAll) {
11741            final int NP = mProcessNames.getMap().size();
11742            for (int ip=0; ip<NP; ip++) {
11743                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11744                final int NA = procs.size();
11745                for (int ia=0; ia<NA; ia++) {
11746                    ProcessRecord r = procs.valueAt(ia);
11747                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11748                        continue;
11749                    }
11750                    if (!needSep) {
11751                        pw.println("  All known processes:");
11752                        needSep = true;
11753                        printedAnything = true;
11754                    }
11755                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11756                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11757                        pw.print(" "); pw.println(r);
11758                    r.dump(pw, "    ");
11759                    if (r.persistent) {
11760                        numPers++;
11761                    }
11762                }
11763            }
11764        }
11765
11766        if (mIsolatedProcesses.size() > 0) {
11767            boolean printed = false;
11768            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11769                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11770                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11771                    continue;
11772                }
11773                if (!printed) {
11774                    if (needSep) {
11775                        pw.println();
11776                    }
11777                    pw.println("  Isolated process list (sorted by uid):");
11778                    printedAnything = true;
11779                    printed = true;
11780                    needSep = true;
11781                }
11782                pw.println(String.format("%sIsolated #%2d: %s",
11783                        "    ", i, r.toString()));
11784            }
11785        }
11786
11787        if (mLruProcesses.size() > 0) {
11788            if (needSep) {
11789                pw.println();
11790            }
11791            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11792                    pw.print(" total, non-act at ");
11793                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11794                    pw.print(", non-svc at ");
11795                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11796                    pw.println("):");
11797            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11798            needSep = true;
11799            printedAnything = true;
11800        }
11801
11802        if (dumpAll || dumpPackage != null) {
11803            synchronized (mPidsSelfLocked) {
11804                boolean printed = false;
11805                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11806                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11807                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11808                        continue;
11809                    }
11810                    if (!printed) {
11811                        if (needSep) pw.println();
11812                        needSep = true;
11813                        pw.println("  PID mappings:");
11814                        printed = true;
11815                        printedAnything = true;
11816                    }
11817                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11818                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11819                }
11820            }
11821        }
11822
11823        if (mForegroundProcesses.size() > 0) {
11824            synchronized (mPidsSelfLocked) {
11825                boolean printed = false;
11826                for (int i=0; i<mForegroundProcesses.size(); i++) {
11827                    ProcessRecord r = mPidsSelfLocked.get(
11828                            mForegroundProcesses.valueAt(i).pid);
11829                    if (dumpPackage != null && (r == null
11830                            || !r.pkgList.containsKey(dumpPackage))) {
11831                        continue;
11832                    }
11833                    if (!printed) {
11834                        if (needSep) pw.println();
11835                        needSep = true;
11836                        pw.println("  Foreground Processes:");
11837                        printed = true;
11838                        printedAnything = true;
11839                    }
11840                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11841                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11842                }
11843            }
11844        }
11845
11846        if (mPersistentStartingProcesses.size() > 0) {
11847            if (needSep) pw.println();
11848            needSep = true;
11849            printedAnything = true;
11850            pw.println("  Persisent processes that are starting:");
11851            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11852                    "Starting Norm", "Restarting PERS", dumpPackage);
11853        }
11854
11855        if (mRemovedProcesses.size() > 0) {
11856            if (needSep) pw.println();
11857            needSep = true;
11858            printedAnything = true;
11859            pw.println("  Processes that are being removed:");
11860            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11861                    "Removed Norm", "Removed PERS", dumpPackage);
11862        }
11863
11864        if (mProcessesOnHold.size() > 0) {
11865            if (needSep) pw.println();
11866            needSep = true;
11867            printedAnything = true;
11868            pw.println("  Processes that are on old until the system is ready:");
11869            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11870                    "OnHold Norm", "OnHold PERS", dumpPackage);
11871        }
11872
11873        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11874
11875        if (mProcessCrashTimes.getMap().size() > 0) {
11876            boolean printed = false;
11877            long now = SystemClock.uptimeMillis();
11878            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11879            final int NP = pmap.size();
11880            for (int ip=0; ip<NP; ip++) {
11881                String pname = pmap.keyAt(ip);
11882                SparseArray<Long> uids = pmap.valueAt(ip);
11883                final int N = uids.size();
11884                for (int i=0; i<N; i++) {
11885                    int puid = uids.keyAt(i);
11886                    ProcessRecord r = mProcessNames.get(pname, puid);
11887                    if (dumpPackage != null && (r == null
11888                            || !r.pkgList.containsKey(dumpPackage))) {
11889                        continue;
11890                    }
11891                    if (!printed) {
11892                        if (needSep) pw.println();
11893                        needSep = true;
11894                        pw.println("  Time since processes crashed:");
11895                        printed = true;
11896                        printedAnything = true;
11897                    }
11898                    pw.print("    Process "); pw.print(pname);
11899                            pw.print(" uid "); pw.print(puid);
11900                            pw.print(": last crashed ");
11901                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11902                            pw.println(" ago");
11903                }
11904            }
11905        }
11906
11907        if (mBadProcesses.getMap().size() > 0) {
11908            boolean printed = false;
11909            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11910            final int NP = pmap.size();
11911            for (int ip=0; ip<NP; ip++) {
11912                String pname = pmap.keyAt(ip);
11913                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11914                final int N = uids.size();
11915                for (int i=0; i<N; i++) {
11916                    int puid = uids.keyAt(i);
11917                    ProcessRecord r = mProcessNames.get(pname, puid);
11918                    if (dumpPackage != null && (r == null
11919                            || !r.pkgList.containsKey(dumpPackage))) {
11920                        continue;
11921                    }
11922                    if (!printed) {
11923                        if (needSep) pw.println();
11924                        needSep = true;
11925                        pw.println("  Bad processes:");
11926                        printedAnything = true;
11927                    }
11928                    BadProcessInfo info = uids.valueAt(i);
11929                    pw.print("    Bad process "); pw.print(pname);
11930                            pw.print(" uid "); pw.print(puid);
11931                            pw.print(": crashed at time "); pw.println(info.time);
11932                    if (info.shortMsg != null) {
11933                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11934                    }
11935                    if (info.longMsg != null) {
11936                        pw.print("      Long msg: "); pw.println(info.longMsg);
11937                    }
11938                    if (info.stack != null) {
11939                        pw.println("      Stack:");
11940                        int lastPos = 0;
11941                        for (int pos=0; pos<info.stack.length(); pos++) {
11942                            if (info.stack.charAt(pos) == '\n') {
11943                                pw.print("        ");
11944                                pw.write(info.stack, lastPos, pos-lastPos);
11945                                pw.println();
11946                                lastPos = pos+1;
11947                            }
11948                        }
11949                        if (lastPos < info.stack.length()) {
11950                            pw.print("        ");
11951                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11952                            pw.println();
11953                        }
11954                    }
11955                }
11956            }
11957        }
11958
11959        if (dumpPackage == null) {
11960            pw.println();
11961            needSep = false;
11962            pw.println("  mStartedUsers:");
11963            for (int i=0; i<mStartedUsers.size(); i++) {
11964                UserStartedState uss = mStartedUsers.valueAt(i);
11965                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11966                        pw.print(": "); uss.dump("", pw);
11967            }
11968            pw.print("  mStartedUserArray: [");
11969            for (int i=0; i<mStartedUserArray.length; i++) {
11970                if (i > 0) pw.print(", ");
11971                pw.print(mStartedUserArray[i]);
11972            }
11973            pw.println("]");
11974            pw.print("  mUserLru: [");
11975            for (int i=0; i<mUserLru.size(); i++) {
11976                if (i > 0) pw.print(", ");
11977                pw.print(mUserLru.get(i));
11978            }
11979            pw.println("]");
11980            if (dumpAll) {
11981                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11982            }
11983            synchronized (mUserProfileGroupIdsSelfLocked) {
11984                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
11985                    pw.println("  mUserProfileGroupIds:");
11986                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
11987                        pw.print("    User #");
11988                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
11989                        pw.print(" -> profile #");
11990                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
11991                    }
11992                }
11993            }
11994        }
11995        if (mHomeProcess != null && (dumpPackage == null
11996                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11997            if (needSep) {
11998                pw.println();
11999                needSep = false;
12000            }
12001            pw.println("  mHomeProcess: " + mHomeProcess);
12002        }
12003        if (mPreviousProcess != null && (dumpPackage == null
12004                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12005            if (needSep) {
12006                pw.println();
12007                needSep = false;
12008            }
12009            pw.println("  mPreviousProcess: " + mPreviousProcess);
12010        }
12011        if (dumpAll) {
12012            StringBuilder sb = new StringBuilder(128);
12013            sb.append("  mPreviousProcessVisibleTime: ");
12014            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12015            pw.println(sb);
12016        }
12017        if (mHeavyWeightProcess != null && (dumpPackage == null
12018                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12019            if (needSep) {
12020                pw.println();
12021                needSep = false;
12022            }
12023            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12024        }
12025        if (dumpPackage == null) {
12026            pw.println("  mConfiguration: " + mConfiguration);
12027        }
12028        if (dumpAll) {
12029            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12030            if (mCompatModePackages.getPackages().size() > 0) {
12031                boolean printed = false;
12032                for (Map.Entry<String, Integer> entry
12033                        : mCompatModePackages.getPackages().entrySet()) {
12034                    String pkg = entry.getKey();
12035                    int mode = entry.getValue();
12036                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12037                        continue;
12038                    }
12039                    if (!printed) {
12040                        pw.println("  mScreenCompatPackages:");
12041                        printed = true;
12042                    }
12043                    pw.print("    "); pw.print(pkg); pw.print(": ");
12044                            pw.print(mode); pw.println();
12045                }
12046            }
12047        }
12048        if (dumpPackage == null) {
12049            if (mSleeping || mWentToSleep || mLockScreenShown) {
12050                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12051                        + " mLockScreenShown " + mLockScreenShown);
12052            }
12053            if (mShuttingDown || mRunningVoice) {
12054                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12055            }
12056        }
12057        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12058                || mOrigWaitForDebugger) {
12059            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12060                    || dumpPackage.equals(mOrigDebugApp)) {
12061                if (needSep) {
12062                    pw.println();
12063                    needSep = false;
12064                }
12065                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12066                        + " mDebugTransient=" + mDebugTransient
12067                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12068            }
12069        }
12070        if (mOpenGlTraceApp != null) {
12071            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12072                if (needSep) {
12073                    pw.println();
12074                    needSep = false;
12075                }
12076                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12077            }
12078        }
12079        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12080                || mProfileFd != null) {
12081            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12082                if (needSep) {
12083                    pw.println();
12084                    needSep = false;
12085                }
12086                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12087                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12088                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
12089                        + mAutoStopProfiler);
12090            }
12091        }
12092        if (dumpPackage == null) {
12093            if (mAlwaysFinishActivities || mController != null) {
12094                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12095                        + " mController=" + mController);
12096            }
12097            if (dumpAll) {
12098                pw.println("  Total persistent processes: " + numPers);
12099                pw.println("  mProcessesReady=" + mProcessesReady
12100                        + " mSystemReady=" + mSystemReady);
12101                pw.println("  mBooting=" + mBooting
12102                        + " mBooted=" + mBooted
12103                        + " mFactoryTest=" + mFactoryTest);
12104                pw.print("  mLastPowerCheckRealtime=");
12105                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12106                        pw.println("");
12107                pw.print("  mLastPowerCheckUptime=");
12108                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12109                        pw.println("");
12110                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12111                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12112                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12113                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12114                        + " (" + mLruProcesses.size() + " total)"
12115                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12116                        + " mNumServiceProcs=" + mNumServiceProcs
12117                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12118                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12119                        + " mLastMemoryLevel" + mLastMemoryLevel
12120                        + " mLastNumProcesses" + mLastNumProcesses);
12121                long now = SystemClock.uptimeMillis();
12122                pw.print("  mLastIdleTime=");
12123                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12124                        pw.print(" mLowRamSinceLastIdle=");
12125                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12126                        pw.println();
12127            }
12128        }
12129
12130        if (!printedAnything) {
12131            pw.println("  (nothing)");
12132        }
12133    }
12134
12135    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12136            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12137        if (mProcessesToGc.size() > 0) {
12138            boolean printed = false;
12139            long now = SystemClock.uptimeMillis();
12140            for (int i=0; i<mProcessesToGc.size(); i++) {
12141                ProcessRecord proc = mProcessesToGc.get(i);
12142                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12143                    continue;
12144                }
12145                if (!printed) {
12146                    if (needSep) pw.println();
12147                    needSep = true;
12148                    pw.println("  Processes that are waiting to GC:");
12149                    printed = true;
12150                }
12151                pw.print("    Process "); pw.println(proc);
12152                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12153                        pw.print(", last gced=");
12154                        pw.print(now-proc.lastRequestedGc);
12155                        pw.print(" ms ago, last lowMem=");
12156                        pw.print(now-proc.lastLowMemory);
12157                        pw.println(" ms ago");
12158
12159            }
12160        }
12161        return needSep;
12162    }
12163
12164    void printOomLevel(PrintWriter pw, String name, int adj) {
12165        pw.print("    ");
12166        if (adj >= 0) {
12167            pw.print(' ');
12168            if (adj < 10) pw.print(' ');
12169        } else {
12170            if (adj > -10) pw.print(' ');
12171        }
12172        pw.print(adj);
12173        pw.print(": ");
12174        pw.print(name);
12175        pw.print(" (");
12176        pw.print(mProcessList.getMemLevel(adj)/1024);
12177        pw.println(" kB)");
12178    }
12179
12180    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12181            int opti, boolean dumpAll) {
12182        boolean needSep = false;
12183
12184        if (mLruProcesses.size() > 0) {
12185            if (needSep) pw.println();
12186            needSep = true;
12187            pw.println("  OOM levels:");
12188            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12189            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12190            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12191            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12192            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12193            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12194            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12195            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12196            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12197            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12198            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12199            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12200            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12201
12202            if (needSep) pw.println();
12203            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12204                    pw.print(" total, non-act at ");
12205                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12206                    pw.print(", non-svc at ");
12207                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12208                    pw.println("):");
12209            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12210            needSep = true;
12211        }
12212
12213        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12214
12215        pw.println();
12216        pw.println("  mHomeProcess: " + mHomeProcess);
12217        pw.println("  mPreviousProcess: " + mPreviousProcess);
12218        if (mHeavyWeightProcess != null) {
12219            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12220        }
12221
12222        return true;
12223    }
12224
12225    /**
12226     * There are three ways to call this:
12227     *  - no provider specified: dump all the providers
12228     *  - a flattened component name that matched an existing provider was specified as the
12229     *    first arg: dump that one provider
12230     *  - the first arg isn't the flattened component name of an existing provider:
12231     *    dump all providers whose component contains the first arg as a substring
12232     */
12233    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12234            int opti, boolean dumpAll) {
12235        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12236    }
12237
12238    static class ItemMatcher {
12239        ArrayList<ComponentName> components;
12240        ArrayList<String> strings;
12241        ArrayList<Integer> objects;
12242        boolean all;
12243
12244        ItemMatcher() {
12245            all = true;
12246        }
12247
12248        void build(String name) {
12249            ComponentName componentName = ComponentName.unflattenFromString(name);
12250            if (componentName != null) {
12251                if (components == null) {
12252                    components = new ArrayList<ComponentName>();
12253                }
12254                components.add(componentName);
12255                all = false;
12256            } else {
12257                int objectId = 0;
12258                // Not a '/' separated full component name; maybe an object ID?
12259                try {
12260                    objectId = Integer.parseInt(name, 16);
12261                    if (objects == null) {
12262                        objects = new ArrayList<Integer>();
12263                    }
12264                    objects.add(objectId);
12265                    all = false;
12266                } catch (RuntimeException e) {
12267                    // Not an integer; just do string match.
12268                    if (strings == null) {
12269                        strings = new ArrayList<String>();
12270                    }
12271                    strings.add(name);
12272                    all = false;
12273                }
12274            }
12275        }
12276
12277        int build(String[] args, int opti) {
12278            for (; opti<args.length; opti++) {
12279                String name = args[opti];
12280                if ("--".equals(name)) {
12281                    return opti+1;
12282                }
12283                build(name);
12284            }
12285            return opti;
12286        }
12287
12288        boolean match(Object object, ComponentName comp) {
12289            if (all) {
12290                return true;
12291            }
12292            if (components != null) {
12293                for (int i=0; i<components.size(); i++) {
12294                    if (components.get(i).equals(comp)) {
12295                        return true;
12296                    }
12297                }
12298            }
12299            if (objects != null) {
12300                for (int i=0; i<objects.size(); i++) {
12301                    if (System.identityHashCode(object) == objects.get(i)) {
12302                        return true;
12303                    }
12304                }
12305            }
12306            if (strings != null) {
12307                String flat = comp.flattenToString();
12308                for (int i=0; i<strings.size(); i++) {
12309                    if (flat.contains(strings.get(i))) {
12310                        return true;
12311                    }
12312                }
12313            }
12314            return false;
12315        }
12316    }
12317
12318    /**
12319     * There are three things that cmd can be:
12320     *  - a flattened component name that matches an existing activity
12321     *  - the cmd arg isn't the flattened component name of an existing activity:
12322     *    dump all activity whose component contains the cmd as a substring
12323     *  - A hex number of the ActivityRecord object instance.
12324     */
12325    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12326            int opti, boolean dumpAll) {
12327        ArrayList<ActivityRecord> activities;
12328
12329        synchronized (this) {
12330            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12331        }
12332
12333        if (activities.size() <= 0) {
12334            return false;
12335        }
12336
12337        String[] newArgs = new String[args.length - opti];
12338        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12339
12340        TaskRecord lastTask = null;
12341        boolean needSep = false;
12342        for (int i=activities.size()-1; i>=0; i--) {
12343            ActivityRecord r = activities.get(i);
12344            if (needSep) {
12345                pw.println();
12346            }
12347            needSep = true;
12348            synchronized (this) {
12349                if (lastTask != r.task) {
12350                    lastTask = r.task;
12351                    pw.print("TASK "); pw.print(lastTask.affinity);
12352                            pw.print(" id="); pw.println(lastTask.taskId);
12353                    if (dumpAll) {
12354                        lastTask.dump(pw, "  ");
12355                    }
12356                }
12357            }
12358            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12359        }
12360        return true;
12361    }
12362
12363    /**
12364     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12365     * there is a thread associated with the activity.
12366     */
12367    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12368            final ActivityRecord r, String[] args, boolean dumpAll) {
12369        String innerPrefix = prefix + "  ";
12370        synchronized (this) {
12371            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12372                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12373                    pw.print(" pid=");
12374                    if (r.app != null) pw.println(r.app.pid);
12375                    else pw.println("(not running)");
12376            if (dumpAll) {
12377                r.dump(pw, innerPrefix);
12378            }
12379        }
12380        if (r.app != null && r.app.thread != null) {
12381            // flush anything that is already in the PrintWriter since the thread is going
12382            // to write to the file descriptor directly
12383            pw.flush();
12384            try {
12385                TransferPipe tp = new TransferPipe();
12386                try {
12387                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12388                            r.appToken, innerPrefix, args);
12389                    tp.go(fd);
12390                } finally {
12391                    tp.kill();
12392                }
12393            } catch (IOException e) {
12394                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12395            } catch (RemoteException e) {
12396                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12397            }
12398        }
12399    }
12400
12401    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12402            int opti, boolean dumpAll, String dumpPackage) {
12403        boolean needSep = false;
12404        boolean onlyHistory = false;
12405        boolean printedAnything = false;
12406
12407        if ("history".equals(dumpPackage)) {
12408            if (opti < args.length && "-s".equals(args[opti])) {
12409                dumpAll = false;
12410            }
12411            onlyHistory = true;
12412            dumpPackage = null;
12413        }
12414
12415        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12416        if (!onlyHistory && dumpAll) {
12417            if (mRegisteredReceivers.size() > 0) {
12418                boolean printed = false;
12419                Iterator it = mRegisteredReceivers.values().iterator();
12420                while (it.hasNext()) {
12421                    ReceiverList r = (ReceiverList)it.next();
12422                    if (dumpPackage != null && (r.app == null ||
12423                            !dumpPackage.equals(r.app.info.packageName))) {
12424                        continue;
12425                    }
12426                    if (!printed) {
12427                        pw.println("  Registered Receivers:");
12428                        needSep = true;
12429                        printed = true;
12430                        printedAnything = true;
12431                    }
12432                    pw.print("  * "); pw.println(r);
12433                    r.dump(pw, "    ");
12434                }
12435            }
12436
12437            if (mReceiverResolver.dump(pw, needSep ?
12438                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12439                    "    ", dumpPackage, false)) {
12440                needSep = true;
12441                printedAnything = true;
12442            }
12443        }
12444
12445        for (BroadcastQueue q : mBroadcastQueues) {
12446            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12447            printedAnything |= needSep;
12448        }
12449
12450        needSep = true;
12451
12452        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12453            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12454                if (needSep) {
12455                    pw.println();
12456                }
12457                needSep = true;
12458                printedAnything = true;
12459                pw.print("  Sticky broadcasts for user ");
12460                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12461                StringBuilder sb = new StringBuilder(128);
12462                for (Map.Entry<String, ArrayList<Intent>> ent
12463                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12464                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12465                    if (dumpAll) {
12466                        pw.println(":");
12467                        ArrayList<Intent> intents = ent.getValue();
12468                        final int N = intents.size();
12469                        for (int i=0; i<N; i++) {
12470                            sb.setLength(0);
12471                            sb.append("    Intent: ");
12472                            intents.get(i).toShortString(sb, false, true, false, false);
12473                            pw.println(sb.toString());
12474                            Bundle bundle = intents.get(i).getExtras();
12475                            if (bundle != null) {
12476                                pw.print("      ");
12477                                pw.println(bundle.toString());
12478                            }
12479                        }
12480                    } else {
12481                        pw.println("");
12482                    }
12483                }
12484            }
12485        }
12486
12487        if (!onlyHistory && dumpAll) {
12488            pw.println();
12489            for (BroadcastQueue queue : mBroadcastQueues) {
12490                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12491                        + queue.mBroadcastsScheduled);
12492            }
12493            pw.println("  mHandler:");
12494            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12495            needSep = true;
12496            printedAnything = true;
12497        }
12498
12499        if (!printedAnything) {
12500            pw.println("  (nothing)");
12501        }
12502    }
12503
12504    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12505            int opti, boolean dumpAll, String dumpPackage) {
12506        boolean needSep;
12507        boolean printedAnything = false;
12508
12509        ItemMatcher matcher = new ItemMatcher();
12510        matcher.build(args, opti);
12511
12512        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12513
12514        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12515        printedAnything |= needSep;
12516
12517        if (mLaunchingProviders.size() > 0) {
12518            boolean printed = false;
12519            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12520                ContentProviderRecord r = mLaunchingProviders.get(i);
12521                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12522                    continue;
12523                }
12524                if (!printed) {
12525                    if (needSep) pw.println();
12526                    needSep = true;
12527                    pw.println("  Launching content providers:");
12528                    printed = true;
12529                    printedAnything = true;
12530                }
12531                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12532                        pw.println(r);
12533            }
12534        }
12535
12536        if (mGrantedUriPermissions.size() > 0) {
12537            boolean printed = false;
12538            int dumpUid = -2;
12539            if (dumpPackage != null) {
12540                try {
12541                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12542                } catch (NameNotFoundException e) {
12543                    dumpUid = -1;
12544                }
12545            }
12546            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12547                int uid = mGrantedUriPermissions.keyAt(i);
12548                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12549                    continue;
12550                }
12551                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12552                if (!printed) {
12553                    if (needSep) pw.println();
12554                    needSep = true;
12555                    pw.println("  Granted Uri Permissions:");
12556                    printed = true;
12557                    printedAnything = true;
12558                }
12559                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12560                for (UriPermission perm : perms.values()) {
12561                    pw.print("    "); pw.println(perm);
12562                    if (dumpAll) {
12563                        perm.dump(pw, "      ");
12564                    }
12565                }
12566            }
12567        }
12568
12569        if (!printedAnything) {
12570            pw.println("  (nothing)");
12571        }
12572    }
12573
12574    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12575            int opti, boolean dumpAll, String dumpPackage) {
12576        boolean printed = false;
12577
12578        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12579
12580        if (mIntentSenderRecords.size() > 0) {
12581            Iterator<WeakReference<PendingIntentRecord>> it
12582                    = mIntentSenderRecords.values().iterator();
12583            while (it.hasNext()) {
12584                WeakReference<PendingIntentRecord> ref = it.next();
12585                PendingIntentRecord rec = ref != null ? ref.get(): null;
12586                if (dumpPackage != null && (rec == null
12587                        || !dumpPackage.equals(rec.key.packageName))) {
12588                    continue;
12589                }
12590                printed = true;
12591                if (rec != null) {
12592                    pw.print("  * "); pw.println(rec);
12593                    if (dumpAll) {
12594                        rec.dump(pw, "    ");
12595                    }
12596                } else {
12597                    pw.print("  * "); pw.println(ref);
12598                }
12599            }
12600        }
12601
12602        if (!printed) {
12603            pw.println("  (nothing)");
12604        }
12605    }
12606
12607    private static final int dumpProcessList(PrintWriter pw,
12608            ActivityManagerService service, List list,
12609            String prefix, String normalLabel, String persistentLabel,
12610            String dumpPackage) {
12611        int numPers = 0;
12612        final int N = list.size()-1;
12613        for (int i=N; i>=0; i--) {
12614            ProcessRecord r = (ProcessRecord)list.get(i);
12615            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12616                continue;
12617            }
12618            pw.println(String.format("%s%s #%2d: %s",
12619                    prefix, (r.persistent ? persistentLabel : normalLabel),
12620                    i, r.toString()));
12621            if (r.persistent) {
12622                numPers++;
12623            }
12624        }
12625        return numPers;
12626    }
12627
12628    private static final boolean dumpProcessOomList(PrintWriter pw,
12629            ActivityManagerService service, List<ProcessRecord> origList,
12630            String prefix, String normalLabel, String persistentLabel,
12631            boolean inclDetails, String dumpPackage) {
12632
12633        ArrayList<Pair<ProcessRecord, Integer>> list
12634                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12635        for (int i=0; i<origList.size(); i++) {
12636            ProcessRecord r = origList.get(i);
12637            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12638                continue;
12639            }
12640            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12641        }
12642
12643        if (list.size() <= 0) {
12644            return false;
12645        }
12646
12647        Comparator<Pair<ProcessRecord, Integer>> comparator
12648                = new Comparator<Pair<ProcessRecord, Integer>>() {
12649            @Override
12650            public int compare(Pair<ProcessRecord, Integer> object1,
12651                    Pair<ProcessRecord, Integer> object2) {
12652                if (object1.first.setAdj != object2.first.setAdj) {
12653                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12654                }
12655                if (object1.second.intValue() != object2.second.intValue()) {
12656                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12657                }
12658                return 0;
12659            }
12660        };
12661
12662        Collections.sort(list, comparator);
12663
12664        final long curRealtime = SystemClock.elapsedRealtime();
12665        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12666        final long curUptime = SystemClock.uptimeMillis();
12667        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12668
12669        for (int i=list.size()-1; i>=0; i--) {
12670            ProcessRecord r = list.get(i).first;
12671            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12672            char schedGroup;
12673            switch (r.setSchedGroup) {
12674                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12675                    schedGroup = 'B';
12676                    break;
12677                case Process.THREAD_GROUP_DEFAULT:
12678                    schedGroup = 'F';
12679                    break;
12680                default:
12681                    schedGroup = '?';
12682                    break;
12683            }
12684            char foreground;
12685            if (r.foregroundActivities) {
12686                foreground = 'A';
12687            } else if (r.foregroundServices) {
12688                foreground = 'S';
12689            } else {
12690                foreground = ' ';
12691            }
12692            String procState = ProcessList.makeProcStateString(r.curProcState);
12693            pw.print(prefix);
12694            pw.print(r.persistent ? persistentLabel : normalLabel);
12695            pw.print(" #");
12696            int num = (origList.size()-1)-list.get(i).second;
12697            if (num < 10) pw.print(' ');
12698            pw.print(num);
12699            pw.print(": ");
12700            pw.print(oomAdj);
12701            pw.print(' ');
12702            pw.print(schedGroup);
12703            pw.print('/');
12704            pw.print(foreground);
12705            pw.print('/');
12706            pw.print(procState);
12707            pw.print(" trm:");
12708            if (r.trimMemoryLevel < 10) pw.print(' ');
12709            pw.print(r.trimMemoryLevel);
12710            pw.print(' ');
12711            pw.print(r.toShortString());
12712            pw.print(" (");
12713            pw.print(r.adjType);
12714            pw.println(')');
12715            if (r.adjSource != null || r.adjTarget != null) {
12716                pw.print(prefix);
12717                pw.print("    ");
12718                if (r.adjTarget instanceof ComponentName) {
12719                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12720                } else if (r.adjTarget != null) {
12721                    pw.print(r.adjTarget.toString());
12722                } else {
12723                    pw.print("{null}");
12724                }
12725                pw.print("<=");
12726                if (r.adjSource instanceof ProcessRecord) {
12727                    pw.print("Proc{");
12728                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12729                    pw.println("}");
12730                } else if (r.adjSource != null) {
12731                    pw.println(r.adjSource.toString());
12732                } else {
12733                    pw.println("{null}");
12734                }
12735            }
12736            if (inclDetails) {
12737                pw.print(prefix);
12738                pw.print("    ");
12739                pw.print("oom: max="); pw.print(r.maxAdj);
12740                pw.print(" curRaw="); pw.print(r.curRawAdj);
12741                pw.print(" setRaw="); pw.print(r.setRawAdj);
12742                pw.print(" cur="); pw.print(r.curAdj);
12743                pw.print(" set="); pw.println(r.setAdj);
12744                pw.print(prefix);
12745                pw.print("    ");
12746                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12747                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12748                pw.print(" lastPss="); pw.print(r.lastPss);
12749                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12750                pw.print(prefix);
12751                pw.print("    ");
12752                pw.print("cached="); pw.print(r.cached);
12753                pw.print(" empty="); pw.print(r.empty);
12754                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12755
12756                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
12757                    if (r.lastWakeTime != 0) {
12758                        long wtime;
12759                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12760                        synchronized (stats) {
12761                            wtime = stats.getProcessWakeTime(r.info.uid,
12762                                    r.pid, curRealtime);
12763                        }
12764                        long timeUsed = wtime - r.lastWakeTime;
12765                        pw.print(prefix);
12766                        pw.print("    ");
12767                        pw.print("keep awake over ");
12768                        TimeUtils.formatDuration(realtimeSince, pw);
12769                        pw.print(" used ");
12770                        TimeUtils.formatDuration(timeUsed, pw);
12771                        pw.print(" (");
12772                        pw.print((timeUsed*100)/realtimeSince);
12773                        pw.println("%)");
12774                    }
12775                    if (r.lastCpuTime != 0) {
12776                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12777                        pw.print(prefix);
12778                        pw.print("    ");
12779                        pw.print("run cpu over ");
12780                        TimeUtils.formatDuration(uptimeSince, pw);
12781                        pw.print(" used ");
12782                        TimeUtils.formatDuration(timeUsed, pw);
12783                        pw.print(" (");
12784                        pw.print((timeUsed*100)/uptimeSince);
12785                        pw.println("%)");
12786                    }
12787                }
12788            }
12789        }
12790        return true;
12791    }
12792
12793    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12794        ArrayList<ProcessRecord> procs;
12795        synchronized (this) {
12796            if (args != null && args.length > start
12797                    && args[start].charAt(0) != '-') {
12798                procs = new ArrayList<ProcessRecord>();
12799                int pid = -1;
12800                try {
12801                    pid = Integer.parseInt(args[start]);
12802                } catch (NumberFormatException e) {
12803                }
12804                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12805                    ProcessRecord proc = mLruProcesses.get(i);
12806                    if (proc.pid == pid) {
12807                        procs.add(proc);
12808                    } else if (proc.processName.equals(args[start])) {
12809                        procs.add(proc);
12810                    }
12811                }
12812                if (procs.size() <= 0) {
12813                    return null;
12814                }
12815            } else {
12816                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12817            }
12818        }
12819        return procs;
12820    }
12821
12822    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12823            PrintWriter pw, String[] args) {
12824        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12825        if (procs == null) {
12826            pw.println("No process found for: " + args[0]);
12827            return;
12828        }
12829
12830        long uptime = SystemClock.uptimeMillis();
12831        long realtime = SystemClock.elapsedRealtime();
12832        pw.println("Applications Graphics Acceleration Info:");
12833        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12834
12835        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12836            ProcessRecord r = procs.get(i);
12837            if (r.thread != null) {
12838                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12839                pw.flush();
12840                try {
12841                    TransferPipe tp = new TransferPipe();
12842                    try {
12843                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12844                        tp.go(fd);
12845                    } finally {
12846                        tp.kill();
12847                    }
12848                } catch (IOException e) {
12849                    pw.println("Failure while dumping the app: " + r);
12850                    pw.flush();
12851                } catch (RemoteException e) {
12852                    pw.println("Got a RemoteException while dumping the app " + r);
12853                    pw.flush();
12854                }
12855            }
12856        }
12857    }
12858
12859    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12860        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12861        if (procs == null) {
12862            pw.println("No process found for: " + args[0]);
12863            return;
12864        }
12865
12866        pw.println("Applications Database Info:");
12867
12868        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12869            ProcessRecord r = procs.get(i);
12870            if (r.thread != null) {
12871                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12872                pw.flush();
12873                try {
12874                    TransferPipe tp = new TransferPipe();
12875                    try {
12876                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12877                        tp.go(fd);
12878                    } finally {
12879                        tp.kill();
12880                    }
12881                } catch (IOException e) {
12882                    pw.println("Failure while dumping the app: " + r);
12883                    pw.flush();
12884                } catch (RemoteException e) {
12885                    pw.println("Got a RemoteException while dumping the app " + r);
12886                    pw.flush();
12887                }
12888            }
12889        }
12890    }
12891
12892    final static class MemItem {
12893        final boolean isProc;
12894        final String label;
12895        final String shortLabel;
12896        final long pss;
12897        final int id;
12898        final boolean hasActivities;
12899        ArrayList<MemItem> subitems;
12900
12901        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12902                boolean _hasActivities) {
12903            isProc = true;
12904            label = _label;
12905            shortLabel = _shortLabel;
12906            pss = _pss;
12907            id = _id;
12908            hasActivities = _hasActivities;
12909        }
12910
12911        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12912            isProc = false;
12913            label = _label;
12914            shortLabel = _shortLabel;
12915            pss = _pss;
12916            id = _id;
12917            hasActivities = false;
12918        }
12919    }
12920
12921    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12922            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12923        if (sort && !isCompact) {
12924            Collections.sort(items, new Comparator<MemItem>() {
12925                @Override
12926                public int compare(MemItem lhs, MemItem rhs) {
12927                    if (lhs.pss < rhs.pss) {
12928                        return 1;
12929                    } else if (lhs.pss > rhs.pss) {
12930                        return -1;
12931                    }
12932                    return 0;
12933                }
12934            });
12935        }
12936
12937        for (int i=0; i<items.size(); i++) {
12938            MemItem mi = items.get(i);
12939            if (!isCompact) {
12940                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12941            } else if (mi.isProc) {
12942                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12943                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12944                pw.println(mi.hasActivities ? ",a" : ",e");
12945            } else {
12946                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12947                pw.println(mi.pss);
12948            }
12949            if (mi.subitems != null) {
12950                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12951                        true, isCompact);
12952            }
12953        }
12954    }
12955
12956    // These are in KB.
12957    static final long[] DUMP_MEM_BUCKETS = new long[] {
12958        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12959        120*1024, 160*1024, 200*1024,
12960        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12961        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12962    };
12963
12964    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12965            boolean stackLike) {
12966        int start = label.lastIndexOf('.');
12967        if (start >= 0) start++;
12968        else start = 0;
12969        int end = label.length();
12970        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12971            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12972                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12973                out.append(bucket);
12974                out.append(stackLike ? "MB." : "MB ");
12975                out.append(label, start, end);
12976                return;
12977            }
12978        }
12979        out.append(memKB/1024);
12980        out.append(stackLike ? "MB." : "MB ");
12981        out.append(label, start, end);
12982    }
12983
12984    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12985            ProcessList.NATIVE_ADJ,
12986            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12987            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12988            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12989            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12990            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12991    };
12992    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12993            "Native",
12994            "System", "Persistent", "Foreground",
12995            "Visible", "Perceptible",
12996            "Heavy Weight", "Backup",
12997            "A Services", "Home",
12998            "Previous", "B Services", "Cached"
12999    };
13000    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13001            "native",
13002            "sys", "pers", "fore",
13003            "vis", "percept",
13004            "heavy", "backup",
13005            "servicea", "home",
13006            "prev", "serviceb", "cached"
13007    };
13008
13009    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13010            long realtime, boolean isCheckinRequest, boolean isCompact) {
13011        if (isCheckinRequest || isCompact) {
13012            // short checkin version
13013            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13014        } else {
13015            pw.println("Applications Memory Usage (kB):");
13016            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13017        }
13018    }
13019
13020    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13021            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13022        boolean dumpDetails = false;
13023        boolean dumpFullDetails = false;
13024        boolean dumpDalvik = false;
13025        boolean oomOnly = false;
13026        boolean isCompact = false;
13027        boolean localOnly = false;
13028
13029        int opti = 0;
13030        while (opti < args.length) {
13031            String opt = args[opti];
13032            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13033                break;
13034            }
13035            opti++;
13036            if ("-a".equals(opt)) {
13037                dumpDetails = true;
13038                dumpFullDetails = true;
13039                dumpDalvik = true;
13040            } else if ("-d".equals(opt)) {
13041                dumpDalvik = true;
13042            } else if ("-c".equals(opt)) {
13043                isCompact = true;
13044            } else if ("--oom".equals(opt)) {
13045                oomOnly = true;
13046            } else if ("--local".equals(opt)) {
13047                localOnly = true;
13048            } else if ("-h".equals(opt)) {
13049                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13050                pw.println("  -a: include all available information for each process.");
13051                pw.println("  -d: include dalvik details when dumping process details.");
13052                pw.println("  -c: dump in a compact machine-parseable representation.");
13053                pw.println("  --oom: only show processes organized by oom adj.");
13054                pw.println("  --local: only collect details locally, don't call process.");
13055                pw.println("If [process] is specified it can be the name or ");
13056                pw.println("pid of a specific process to dump.");
13057                return;
13058            } else {
13059                pw.println("Unknown argument: " + opt + "; use -h for help");
13060            }
13061        }
13062
13063        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13064        long uptime = SystemClock.uptimeMillis();
13065        long realtime = SystemClock.elapsedRealtime();
13066        final long[] tmpLong = new long[1];
13067
13068        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13069        if (procs == null) {
13070            // No Java processes.  Maybe they want to print a native process.
13071            if (args != null && args.length > opti
13072                    && args[opti].charAt(0) != '-') {
13073                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13074                        = new ArrayList<ProcessCpuTracker.Stats>();
13075                updateCpuStatsNow();
13076                int findPid = -1;
13077                try {
13078                    findPid = Integer.parseInt(args[opti]);
13079                } catch (NumberFormatException e) {
13080                }
13081                synchronized (mProcessCpuThread) {
13082                    final int N = mProcessCpuTracker.countStats();
13083                    for (int i=0; i<N; i++) {
13084                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13085                        if (st.pid == findPid || (st.baseName != null
13086                                && st.baseName.equals(args[opti]))) {
13087                            nativeProcs.add(st);
13088                        }
13089                    }
13090                }
13091                if (nativeProcs.size() > 0) {
13092                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13093                            isCompact);
13094                    Debug.MemoryInfo mi = null;
13095                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13096                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13097                        final int pid = r.pid;
13098                        if (!isCheckinRequest && dumpDetails) {
13099                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13100                        }
13101                        if (mi == null) {
13102                            mi = new Debug.MemoryInfo();
13103                        }
13104                        if (dumpDetails || (!brief && !oomOnly)) {
13105                            Debug.getMemoryInfo(pid, mi);
13106                        } else {
13107                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13108                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13109                        }
13110                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13111                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13112                        if (isCheckinRequest) {
13113                            pw.println();
13114                        }
13115                    }
13116                    return;
13117                }
13118            }
13119            pw.println("No process found for: " + args[opti]);
13120            return;
13121        }
13122
13123        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13124            dumpDetails = true;
13125        }
13126
13127        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13128
13129        String[] innerArgs = new String[args.length-opti];
13130        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13131
13132        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13133        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13134        long nativePss=0, dalvikPss=0, otherPss=0;
13135        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13136
13137        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13138        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13139                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13140
13141        long totalPss = 0;
13142        long cachedPss = 0;
13143
13144        Debug.MemoryInfo mi = null;
13145        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13146            final ProcessRecord r = procs.get(i);
13147            final IApplicationThread thread;
13148            final int pid;
13149            final int oomAdj;
13150            final boolean hasActivities;
13151            synchronized (this) {
13152                thread = r.thread;
13153                pid = r.pid;
13154                oomAdj = r.getSetAdjWithServices();
13155                hasActivities = r.activities.size() > 0;
13156            }
13157            if (thread != null) {
13158                if (!isCheckinRequest && dumpDetails) {
13159                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13160                }
13161                if (mi == null) {
13162                    mi = new Debug.MemoryInfo();
13163                }
13164                if (dumpDetails || (!brief && !oomOnly)) {
13165                    Debug.getMemoryInfo(pid, mi);
13166                } else {
13167                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13168                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13169                }
13170                if (dumpDetails) {
13171                    if (localOnly) {
13172                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13173                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13174                        if (isCheckinRequest) {
13175                            pw.println();
13176                        }
13177                    } else {
13178                        try {
13179                            pw.flush();
13180                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13181                                    dumpDalvik, innerArgs);
13182                        } catch (RemoteException e) {
13183                            if (!isCheckinRequest) {
13184                                pw.println("Got RemoteException!");
13185                                pw.flush();
13186                            }
13187                        }
13188                    }
13189                }
13190
13191                final long myTotalPss = mi.getTotalPss();
13192                final long myTotalUss = mi.getTotalUss();
13193
13194                synchronized (this) {
13195                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13196                        // Record this for posterity if the process has been stable.
13197                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13198                    }
13199                }
13200
13201                if (!isCheckinRequest && mi != null) {
13202                    totalPss += myTotalPss;
13203                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13204                            (hasActivities ? " / activities)" : ")"),
13205                            r.processName, myTotalPss, pid, hasActivities);
13206                    procMems.add(pssItem);
13207                    procMemsMap.put(pid, pssItem);
13208
13209                    nativePss += mi.nativePss;
13210                    dalvikPss += mi.dalvikPss;
13211                    otherPss += mi.otherPss;
13212                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13213                        long mem = mi.getOtherPss(j);
13214                        miscPss[j] += mem;
13215                        otherPss -= mem;
13216                    }
13217
13218                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13219                        cachedPss += myTotalPss;
13220                    }
13221
13222                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13223                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13224                                || oomIndex == (oomPss.length-1)) {
13225                            oomPss[oomIndex] += myTotalPss;
13226                            if (oomProcs[oomIndex] == null) {
13227                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13228                            }
13229                            oomProcs[oomIndex].add(pssItem);
13230                            break;
13231                        }
13232                    }
13233                }
13234            }
13235        }
13236
13237        long nativeProcTotalPss = 0;
13238
13239        if (!isCheckinRequest && procs.size() > 1) {
13240            // If we are showing aggregations, also look for native processes to
13241            // include so that our aggregations are more accurate.
13242            updateCpuStatsNow();
13243            synchronized (mProcessCpuThread) {
13244                final int N = mProcessCpuTracker.countStats();
13245                for (int i=0; i<N; i++) {
13246                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13247                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13248                        if (mi == null) {
13249                            mi = new Debug.MemoryInfo();
13250                        }
13251                        if (!brief && !oomOnly) {
13252                            Debug.getMemoryInfo(st.pid, mi);
13253                        } else {
13254                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13255                            mi.nativePrivateDirty = (int)tmpLong[0];
13256                        }
13257
13258                        final long myTotalPss = mi.getTotalPss();
13259                        totalPss += myTotalPss;
13260                        nativeProcTotalPss += myTotalPss;
13261
13262                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13263                                st.name, myTotalPss, st.pid, false);
13264                        procMems.add(pssItem);
13265
13266                        nativePss += mi.nativePss;
13267                        dalvikPss += mi.dalvikPss;
13268                        otherPss += mi.otherPss;
13269                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13270                            long mem = mi.getOtherPss(j);
13271                            miscPss[j] += mem;
13272                            otherPss -= mem;
13273                        }
13274                        oomPss[0] += myTotalPss;
13275                        if (oomProcs[0] == null) {
13276                            oomProcs[0] = new ArrayList<MemItem>();
13277                        }
13278                        oomProcs[0].add(pssItem);
13279                    }
13280                }
13281            }
13282
13283            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13284
13285            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13286            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13287            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13288            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13289                String label = Debug.MemoryInfo.getOtherLabel(j);
13290                catMems.add(new MemItem(label, label, miscPss[j], j));
13291            }
13292
13293            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13294            for (int j=0; j<oomPss.length; j++) {
13295                if (oomPss[j] != 0) {
13296                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13297                            : DUMP_MEM_OOM_LABEL[j];
13298                    MemItem item = new MemItem(label, label, oomPss[j],
13299                            DUMP_MEM_OOM_ADJ[j]);
13300                    item.subitems = oomProcs[j];
13301                    oomMems.add(item);
13302                }
13303            }
13304
13305            if (!brief && !oomOnly && !isCompact) {
13306                pw.println();
13307                pw.println("Total PSS by process:");
13308                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13309                pw.println();
13310            }
13311            if (!isCompact) {
13312                pw.println("Total PSS by OOM adjustment:");
13313            }
13314            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13315            if (!brief && !oomOnly) {
13316                PrintWriter out = categoryPw != null ? categoryPw : pw;
13317                if (!isCompact) {
13318                    out.println();
13319                    out.println("Total PSS by category:");
13320                }
13321                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13322            }
13323            if (!isCompact) {
13324                pw.println();
13325            }
13326            MemInfoReader memInfo = new MemInfoReader();
13327            memInfo.readMemInfo();
13328            if (nativeProcTotalPss > 0) {
13329                synchronized (this) {
13330                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13331                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13332                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13333                            nativeProcTotalPss);
13334                }
13335            }
13336            if (!brief) {
13337                if (!isCompact) {
13338                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13339                    pw.print(" kB (status ");
13340                    switch (mLastMemoryLevel) {
13341                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13342                            pw.println("normal)");
13343                            break;
13344                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13345                            pw.println("moderate)");
13346                            break;
13347                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13348                            pw.println("low)");
13349                            break;
13350                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13351                            pw.println("critical)");
13352                            break;
13353                        default:
13354                            pw.print(mLastMemoryLevel);
13355                            pw.println(")");
13356                            break;
13357                    }
13358                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13359                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13360                            pw.print(cachedPss); pw.print(" cached pss + ");
13361                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13362                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13363                } else {
13364                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13365                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13366                            + memInfo.getFreeSizeKb()); pw.print(",");
13367                    pw.println(totalPss - cachedPss);
13368                }
13369            }
13370            if (!isCompact) {
13371                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13372                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13373                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13374                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13375                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13376                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13377                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13378                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13379                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13380                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13381                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13382            }
13383            if (!brief) {
13384                if (memInfo.getZramTotalSizeKb() != 0) {
13385                    if (!isCompact) {
13386                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13387                                pw.print(" kB physical used for ");
13388                                pw.print(memInfo.getSwapTotalSizeKb()
13389                                        - memInfo.getSwapFreeSizeKb());
13390                                pw.print(" kB in swap (");
13391                                pw.print(memInfo.getSwapTotalSizeKb());
13392                                pw.println(" kB total swap)");
13393                    } else {
13394                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13395                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13396                                pw.println(memInfo.getSwapFreeSizeKb());
13397                    }
13398                }
13399                final int[] SINGLE_LONG_FORMAT = new int[] {
13400                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13401                };
13402                long[] longOut = new long[1];
13403                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13404                        SINGLE_LONG_FORMAT, null, longOut, null);
13405                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13406                longOut[0] = 0;
13407                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13408                        SINGLE_LONG_FORMAT, null, longOut, null);
13409                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13410                longOut[0] = 0;
13411                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13412                        SINGLE_LONG_FORMAT, null, longOut, null);
13413                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13414                longOut[0] = 0;
13415                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13416                        SINGLE_LONG_FORMAT, null, longOut, null);
13417                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13418                if (!isCompact) {
13419                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13420                        pw.print("      KSM: "); pw.print(sharing);
13421                                pw.print(" kB saved from shared ");
13422                                pw.print(shared); pw.println(" kB");
13423                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13424                                pw.print(voltile); pw.println(" kB volatile");
13425                    }
13426                    pw.print("   Tuning: ");
13427                    pw.print(ActivityManager.staticGetMemoryClass());
13428                    pw.print(" (large ");
13429                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13430                    pw.print("), oom ");
13431                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13432                    pw.print(" kB");
13433                    pw.print(", restore limit ");
13434                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13435                    pw.print(" kB");
13436                    if (ActivityManager.isLowRamDeviceStatic()) {
13437                        pw.print(" (low-ram)");
13438                    }
13439                    if (ActivityManager.isHighEndGfx()) {
13440                        pw.print(" (high-end-gfx)");
13441                    }
13442                    pw.println();
13443                } else {
13444                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13445                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13446                    pw.println(voltile);
13447                    pw.print("tuning,");
13448                    pw.print(ActivityManager.staticGetMemoryClass());
13449                    pw.print(',');
13450                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13451                    pw.print(',');
13452                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13453                    if (ActivityManager.isLowRamDeviceStatic()) {
13454                        pw.print(",low-ram");
13455                    }
13456                    if (ActivityManager.isHighEndGfx()) {
13457                        pw.print(",high-end-gfx");
13458                    }
13459                    pw.println();
13460                }
13461            }
13462        }
13463    }
13464
13465    /**
13466     * Searches array of arguments for the specified string
13467     * @param args array of argument strings
13468     * @param value value to search for
13469     * @return true if the value is contained in the array
13470     */
13471    private static boolean scanArgs(String[] args, String value) {
13472        if (args != null) {
13473            for (String arg : args) {
13474                if (value.equals(arg)) {
13475                    return true;
13476                }
13477            }
13478        }
13479        return false;
13480    }
13481
13482    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13483            ContentProviderRecord cpr, boolean always) {
13484        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13485
13486        if (!inLaunching || always) {
13487            synchronized (cpr) {
13488                cpr.launchingApp = null;
13489                cpr.notifyAll();
13490            }
13491            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13492            String names[] = cpr.info.authority.split(";");
13493            for (int j = 0; j < names.length; j++) {
13494                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13495            }
13496        }
13497
13498        for (int i=0; i<cpr.connections.size(); i++) {
13499            ContentProviderConnection conn = cpr.connections.get(i);
13500            if (conn.waiting) {
13501                // If this connection is waiting for the provider, then we don't
13502                // need to mess with its process unless we are always removing
13503                // or for some reason the provider is not currently launching.
13504                if (inLaunching && !always) {
13505                    continue;
13506                }
13507            }
13508            ProcessRecord capp = conn.client;
13509            conn.dead = true;
13510            if (conn.stableCount > 0) {
13511                if (!capp.persistent && capp.thread != null
13512                        && capp.pid != 0
13513                        && capp.pid != MY_PID) {
13514                    killUnneededProcessLocked(capp, "depends on provider "
13515                            + cpr.name.flattenToShortString()
13516                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13517                }
13518            } else if (capp.thread != null && conn.provider.provider != null) {
13519                try {
13520                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13521                } catch (RemoteException e) {
13522                }
13523                // In the protocol here, we don't expect the client to correctly
13524                // clean up this connection, we'll just remove it.
13525                cpr.connections.remove(i);
13526                conn.client.conProviders.remove(conn);
13527            }
13528        }
13529
13530        if (inLaunching && always) {
13531            mLaunchingProviders.remove(cpr);
13532        }
13533        return inLaunching;
13534    }
13535
13536    /**
13537     * Main code for cleaning up a process when it has gone away.  This is
13538     * called both as a result of the process dying, or directly when stopping
13539     * a process when running in single process mode.
13540     */
13541    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13542            boolean restarting, boolean allowRestart, int index) {
13543        if (index >= 0) {
13544            removeLruProcessLocked(app);
13545            ProcessList.remove(app.pid);
13546        }
13547
13548        mProcessesToGc.remove(app);
13549        mPendingPssProcesses.remove(app);
13550
13551        // Dismiss any open dialogs.
13552        if (app.crashDialog != null && !app.forceCrashReport) {
13553            app.crashDialog.dismiss();
13554            app.crashDialog = null;
13555        }
13556        if (app.anrDialog != null) {
13557            app.anrDialog.dismiss();
13558            app.anrDialog = null;
13559        }
13560        if (app.waitDialog != null) {
13561            app.waitDialog.dismiss();
13562            app.waitDialog = null;
13563        }
13564
13565        app.crashing = false;
13566        app.notResponding = false;
13567
13568        app.resetPackageList(mProcessStats);
13569        app.unlinkDeathRecipient();
13570        app.makeInactive(mProcessStats);
13571        app.waitingToKill = null;
13572        app.forcingToForeground = null;
13573        updateProcessForegroundLocked(app, false, false);
13574        app.foregroundActivities = false;
13575        app.hasShownUi = false;
13576        app.treatLikeActivity = false;
13577        app.hasAboveClient = false;
13578        app.hasClientActivities = false;
13579
13580        mServices.killServicesLocked(app, allowRestart);
13581
13582        boolean restart = false;
13583
13584        // Remove published content providers.
13585        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13586            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13587            final boolean always = app.bad || !allowRestart;
13588            if (removeDyingProviderLocked(app, cpr, always) || always) {
13589                // We left the provider in the launching list, need to
13590                // restart it.
13591                restart = true;
13592            }
13593
13594            cpr.provider = null;
13595            cpr.proc = null;
13596        }
13597        app.pubProviders.clear();
13598
13599        // Take care of any launching providers waiting for this process.
13600        if (checkAppInLaunchingProvidersLocked(app, false)) {
13601            restart = true;
13602        }
13603
13604        // Unregister from connected content providers.
13605        if (!app.conProviders.isEmpty()) {
13606            for (int i=0; i<app.conProviders.size(); i++) {
13607                ContentProviderConnection conn = app.conProviders.get(i);
13608                conn.provider.connections.remove(conn);
13609            }
13610            app.conProviders.clear();
13611        }
13612
13613        // At this point there may be remaining entries in mLaunchingProviders
13614        // where we were the only one waiting, so they are no longer of use.
13615        // Look for these and clean up if found.
13616        // XXX Commented out for now.  Trying to figure out a way to reproduce
13617        // the actual situation to identify what is actually going on.
13618        if (false) {
13619            for (int i=0; i<mLaunchingProviders.size(); i++) {
13620                ContentProviderRecord cpr = (ContentProviderRecord)
13621                        mLaunchingProviders.get(i);
13622                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13623                    synchronized (cpr) {
13624                        cpr.launchingApp = null;
13625                        cpr.notifyAll();
13626                    }
13627                }
13628            }
13629        }
13630
13631        skipCurrentReceiverLocked(app);
13632
13633        // Unregister any receivers.
13634        for (int i=app.receivers.size()-1; i>=0; i--) {
13635            removeReceiverLocked(app.receivers.valueAt(i));
13636        }
13637        app.receivers.clear();
13638
13639        // If the app is undergoing backup, tell the backup manager about it
13640        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13641            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13642                    + mBackupTarget.appInfo + " died during backup");
13643            try {
13644                IBackupManager bm = IBackupManager.Stub.asInterface(
13645                        ServiceManager.getService(Context.BACKUP_SERVICE));
13646                bm.agentDisconnected(app.info.packageName);
13647            } catch (RemoteException e) {
13648                // can't happen; backup manager is local
13649            }
13650        }
13651
13652        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13653            ProcessChangeItem item = mPendingProcessChanges.get(i);
13654            if (item.pid == app.pid) {
13655                mPendingProcessChanges.remove(i);
13656                mAvailProcessChanges.add(item);
13657            }
13658        }
13659        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13660
13661        // If the caller is restarting this app, then leave it in its
13662        // current lists and let the caller take care of it.
13663        if (restarting) {
13664            return;
13665        }
13666
13667        if (!app.persistent || app.isolated) {
13668            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13669                    "Removing non-persistent process during cleanup: " + app);
13670            mProcessNames.remove(app.processName, app.uid);
13671            mIsolatedProcesses.remove(app.uid);
13672            if (mHeavyWeightProcess == app) {
13673                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13674                        mHeavyWeightProcess.userId, 0));
13675                mHeavyWeightProcess = null;
13676            }
13677        } else if (!app.removed) {
13678            // This app is persistent, so we need to keep its record around.
13679            // If it is not already on the pending app list, add it there
13680            // and start a new process for it.
13681            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13682                mPersistentStartingProcesses.add(app);
13683                restart = true;
13684            }
13685        }
13686        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13687                "Clean-up removing on hold: " + app);
13688        mProcessesOnHold.remove(app);
13689
13690        if (app == mHomeProcess) {
13691            mHomeProcess = null;
13692        }
13693        if (app == mPreviousProcess) {
13694            mPreviousProcess = null;
13695        }
13696
13697        if (restart && !app.isolated) {
13698            // We have components that still need to be running in the
13699            // process, so re-launch it.
13700            mProcessNames.put(app.processName, app.uid, app);
13701            startProcessLocked(app, "restart", app.processName);
13702        } else if (app.pid > 0 && app.pid != MY_PID) {
13703            // Goodbye!
13704            boolean removed;
13705            synchronized (mPidsSelfLocked) {
13706                mPidsSelfLocked.remove(app.pid);
13707                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13708            }
13709            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
13710            if (app.isolated) {
13711                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13712            }
13713            app.setPid(0);
13714        }
13715    }
13716
13717    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13718        // Look through the content providers we are waiting to have launched,
13719        // and if any run in this process then either schedule a restart of
13720        // the process or kill the client waiting for it if this process has
13721        // gone bad.
13722        int NL = mLaunchingProviders.size();
13723        boolean restart = false;
13724        for (int i=0; i<NL; i++) {
13725            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13726            if (cpr.launchingApp == app) {
13727                if (!alwaysBad && !app.bad) {
13728                    restart = true;
13729                } else {
13730                    removeDyingProviderLocked(app, cpr, true);
13731                    // cpr should have been removed from mLaunchingProviders
13732                    NL = mLaunchingProviders.size();
13733                    i--;
13734                }
13735            }
13736        }
13737        return restart;
13738    }
13739
13740    // =========================================================
13741    // SERVICES
13742    // =========================================================
13743
13744    @Override
13745    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13746            int flags) {
13747        enforceNotIsolatedCaller("getServices");
13748        synchronized (this) {
13749            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13750        }
13751    }
13752
13753    @Override
13754    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13755        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13756        synchronized (this) {
13757            return mServices.getRunningServiceControlPanelLocked(name);
13758        }
13759    }
13760
13761    @Override
13762    public ComponentName startService(IApplicationThread caller, Intent service,
13763            String resolvedType, int userId) {
13764        enforceNotIsolatedCaller("startService");
13765        // Refuse possible leaked file descriptors
13766        if (service != null && service.hasFileDescriptors() == true) {
13767            throw new IllegalArgumentException("File descriptors passed in Intent");
13768        }
13769
13770        if (DEBUG_SERVICE)
13771            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13772        synchronized(this) {
13773            final int callingPid = Binder.getCallingPid();
13774            final int callingUid = Binder.getCallingUid();
13775            final long origId = Binder.clearCallingIdentity();
13776            ComponentName res = mServices.startServiceLocked(caller, service,
13777                    resolvedType, callingPid, callingUid, userId);
13778            Binder.restoreCallingIdentity(origId);
13779            return res;
13780        }
13781    }
13782
13783    ComponentName startServiceInPackage(int uid,
13784            Intent service, String resolvedType, int userId) {
13785        synchronized(this) {
13786            if (DEBUG_SERVICE)
13787                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13788            final long origId = Binder.clearCallingIdentity();
13789            ComponentName res = mServices.startServiceLocked(null, service,
13790                    resolvedType, -1, uid, userId);
13791            Binder.restoreCallingIdentity(origId);
13792            return res;
13793        }
13794    }
13795
13796    @Override
13797    public int stopService(IApplicationThread caller, Intent service,
13798            String resolvedType, int userId) {
13799        enforceNotIsolatedCaller("stopService");
13800        // Refuse possible leaked file descriptors
13801        if (service != null && service.hasFileDescriptors() == true) {
13802            throw new IllegalArgumentException("File descriptors passed in Intent");
13803        }
13804
13805        synchronized(this) {
13806            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13807        }
13808    }
13809
13810    @Override
13811    public IBinder peekService(Intent service, String resolvedType) {
13812        enforceNotIsolatedCaller("peekService");
13813        // Refuse possible leaked file descriptors
13814        if (service != null && service.hasFileDescriptors() == true) {
13815            throw new IllegalArgumentException("File descriptors passed in Intent");
13816        }
13817        synchronized(this) {
13818            return mServices.peekServiceLocked(service, resolvedType);
13819        }
13820    }
13821
13822    @Override
13823    public boolean stopServiceToken(ComponentName className, IBinder token,
13824            int startId) {
13825        synchronized(this) {
13826            return mServices.stopServiceTokenLocked(className, token, startId);
13827        }
13828    }
13829
13830    @Override
13831    public void setServiceForeground(ComponentName className, IBinder token,
13832            int id, Notification notification, boolean removeNotification) {
13833        synchronized(this) {
13834            mServices.setServiceForegroundLocked(className, token, id, notification,
13835                    removeNotification);
13836        }
13837    }
13838
13839    @Override
13840    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13841            boolean requireFull, String name, String callerPackage) {
13842        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
13843                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
13844    }
13845
13846    int unsafeConvertIncomingUser(int userId) {
13847        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
13848                ? mCurrentUserId : userId;
13849    }
13850
13851    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13852            int allowMode, String name, String callerPackage) {
13853        final int callingUserId = UserHandle.getUserId(callingUid);
13854        if (callingUserId == userId) {
13855            return userId;
13856        }
13857
13858        // Note that we may be accessing mCurrentUserId outside of a lock...
13859        // shouldn't be a big deal, if this is being called outside
13860        // of a locked context there is intrinsically a race with
13861        // the value the caller will receive and someone else changing it.
13862        // We assume that USER_CURRENT_OR_SELF will use the current user; later
13863        // we will switch to the calling user if access to the current user fails.
13864        int targetUserId = unsafeConvertIncomingUser(userId);
13865
13866        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13867            final boolean allow;
13868            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
13869                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
13870                // If the caller has this permission, they always pass go.  And collect $200.
13871                allow = true;
13872            } else if (allowMode == ALLOW_FULL_ONLY) {
13873                // We require full access, sucks to be you.
13874                allow = false;
13875            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
13876                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
13877                // If the caller does not have either permission, they are always doomed.
13878                allow = false;
13879            } else if (allowMode == ALLOW_NON_FULL) {
13880                // We are blanket allowing non-full access, you lucky caller!
13881                allow = true;
13882            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
13883                // We may or may not allow this depending on whether the two users are
13884                // in the same profile.
13885                synchronized (mUserProfileGroupIdsSelfLocked) {
13886                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
13887                            UserInfo.NO_PROFILE_GROUP_ID);
13888                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
13889                            UserInfo.NO_PROFILE_GROUP_ID);
13890                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
13891                            && callingProfile == targetProfile;
13892                }
13893            } else {
13894                throw new IllegalArgumentException("Unknown mode: " + allowMode);
13895            }
13896            if (!allow) {
13897                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13898                    // In this case, they would like to just execute as their
13899                    // owner user instead of failing.
13900                    targetUserId = callingUserId;
13901                } else {
13902                    StringBuilder builder = new StringBuilder(128);
13903                    builder.append("Permission Denial: ");
13904                    builder.append(name);
13905                    if (callerPackage != null) {
13906                        builder.append(" from ");
13907                        builder.append(callerPackage);
13908                    }
13909                    builder.append(" asks to run as user ");
13910                    builder.append(userId);
13911                    builder.append(" but is calling from user ");
13912                    builder.append(UserHandle.getUserId(callingUid));
13913                    builder.append("; this requires ");
13914                    builder.append(INTERACT_ACROSS_USERS_FULL);
13915                    if (allowMode != ALLOW_FULL_ONLY) {
13916                        builder.append(" or ");
13917                        builder.append(INTERACT_ACROSS_USERS);
13918                    }
13919                    String msg = builder.toString();
13920                    Slog.w(TAG, msg);
13921                    throw new SecurityException(msg);
13922                }
13923            }
13924        }
13925        if (!allowAll && targetUserId < 0) {
13926            throw new IllegalArgumentException(
13927                    "Call does not support special user #" + targetUserId);
13928        }
13929        return targetUserId;
13930    }
13931
13932    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13933            String className, int flags) {
13934        boolean result = false;
13935        // For apps that don't have pre-defined UIDs, check for permission
13936        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13937            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13938                if (ActivityManager.checkUidPermission(
13939                        INTERACT_ACROSS_USERS,
13940                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13941                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13942                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13943                            + " requests FLAG_SINGLE_USER, but app does not hold "
13944                            + INTERACT_ACROSS_USERS;
13945                    Slog.w(TAG, msg);
13946                    throw new SecurityException(msg);
13947                }
13948                // Permission passed
13949                result = true;
13950            }
13951        } else if ("system".equals(componentProcessName)) {
13952            result = true;
13953        } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
13954                && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13955            // Phone app is allowed to export singleuser providers.
13956            result = true;
13957        } else {
13958            // App with pre-defined UID, check if it's a persistent app
13959            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13960        }
13961        if (DEBUG_MU) {
13962            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13963                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13964        }
13965        return result;
13966    }
13967
13968    /**
13969     * Checks to see if the caller is in the same app as the singleton
13970     * component, or the component is in a special app. It allows special apps
13971     * to export singleton components but prevents exporting singleton
13972     * components for regular apps.
13973     */
13974    boolean isValidSingletonCall(int callingUid, int componentUid) {
13975        int componentAppId = UserHandle.getAppId(componentUid);
13976        return UserHandle.isSameApp(callingUid, componentUid)
13977                || componentAppId == Process.SYSTEM_UID
13978                || componentAppId == Process.PHONE_UID
13979                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13980                        == PackageManager.PERMISSION_GRANTED;
13981    }
13982
13983    public int bindService(IApplicationThread caller, IBinder token,
13984            Intent service, String resolvedType,
13985            IServiceConnection connection, int flags, int userId) {
13986        enforceNotIsolatedCaller("bindService");
13987        // Refuse possible leaked file descriptors
13988        if (service != null && service.hasFileDescriptors() == true) {
13989            throw new IllegalArgumentException("File descriptors passed in Intent");
13990        }
13991
13992        synchronized(this) {
13993            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13994                    connection, flags, userId);
13995        }
13996    }
13997
13998    public boolean unbindService(IServiceConnection connection) {
13999        synchronized (this) {
14000            return mServices.unbindServiceLocked(connection);
14001        }
14002    }
14003
14004    public void publishService(IBinder token, Intent intent, IBinder service) {
14005        // Refuse possible leaked file descriptors
14006        if (intent != null && intent.hasFileDescriptors() == true) {
14007            throw new IllegalArgumentException("File descriptors passed in Intent");
14008        }
14009
14010        synchronized(this) {
14011            if (!(token instanceof ServiceRecord)) {
14012                throw new IllegalArgumentException("Invalid service token");
14013            }
14014            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14015        }
14016    }
14017
14018    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14019        // Refuse possible leaked file descriptors
14020        if (intent != null && intent.hasFileDescriptors() == true) {
14021            throw new IllegalArgumentException("File descriptors passed in Intent");
14022        }
14023
14024        synchronized(this) {
14025            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14026        }
14027    }
14028
14029    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14030        synchronized(this) {
14031            if (!(token instanceof ServiceRecord)) {
14032                throw new IllegalArgumentException("Invalid service token");
14033            }
14034            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14035        }
14036    }
14037
14038    // =========================================================
14039    // BACKUP AND RESTORE
14040    // =========================================================
14041
14042    // Cause the target app to be launched if necessary and its backup agent
14043    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14044    // activity manager to announce its creation.
14045    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14046        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14047        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14048
14049        synchronized(this) {
14050            // !!! TODO: currently no check here that we're already bound
14051            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14052            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14053            synchronized (stats) {
14054                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14055            }
14056
14057            // Backup agent is now in use, its package can't be stopped.
14058            try {
14059                AppGlobals.getPackageManager().setPackageStoppedState(
14060                        app.packageName, false, UserHandle.getUserId(app.uid));
14061            } catch (RemoteException e) {
14062            } catch (IllegalArgumentException e) {
14063                Slog.w(TAG, "Failed trying to unstop package "
14064                        + app.packageName + ": " + e);
14065            }
14066
14067            BackupRecord r = new BackupRecord(ss, app, backupMode);
14068            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14069                    ? new ComponentName(app.packageName, app.backupAgentName)
14070                    : new ComponentName("android", "FullBackupAgent");
14071            // startProcessLocked() returns existing proc's record if it's already running
14072            ProcessRecord proc = startProcessLocked(app.processName, app,
14073                    false, 0, "backup", hostingName, false, false, false);
14074            if (proc == null) {
14075                Slog.e(TAG, "Unable to start backup agent process " + r);
14076                return false;
14077            }
14078
14079            r.app = proc;
14080            mBackupTarget = r;
14081            mBackupAppName = app.packageName;
14082
14083            // Try not to kill the process during backup
14084            updateOomAdjLocked(proc);
14085
14086            // If the process is already attached, schedule the creation of the backup agent now.
14087            // If it is not yet live, this will be done when it attaches to the framework.
14088            if (proc.thread != null) {
14089                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14090                try {
14091                    proc.thread.scheduleCreateBackupAgent(app,
14092                            compatibilityInfoForPackageLocked(app), backupMode);
14093                } catch (RemoteException e) {
14094                    // Will time out on the backup manager side
14095                }
14096            } else {
14097                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14098            }
14099            // Invariants: at this point, the target app process exists and the application
14100            // is either already running or in the process of coming up.  mBackupTarget and
14101            // mBackupAppName describe the app, so that when it binds back to the AM we
14102            // know that it's scheduled for a backup-agent operation.
14103        }
14104
14105        return true;
14106    }
14107
14108    @Override
14109    public void clearPendingBackup() {
14110        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14111        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14112
14113        synchronized (this) {
14114            mBackupTarget = null;
14115            mBackupAppName = null;
14116        }
14117    }
14118
14119    // A backup agent has just come up
14120    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14121        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14122                + " = " + agent);
14123
14124        synchronized(this) {
14125            if (!agentPackageName.equals(mBackupAppName)) {
14126                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14127                return;
14128            }
14129        }
14130
14131        long oldIdent = Binder.clearCallingIdentity();
14132        try {
14133            IBackupManager bm = IBackupManager.Stub.asInterface(
14134                    ServiceManager.getService(Context.BACKUP_SERVICE));
14135            bm.agentConnected(agentPackageName, agent);
14136        } catch (RemoteException e) {
14137            // can't happen; the backup manager service is local
14138        } catch (Exception e) {
14139            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14140            e.printStackTrace();
14141        } finally {
14142            Binder.restoreCallingIdentity(oldIdent);
14143        }
14144    }
14145
14146    // done with this agent
14147    public void unbindBackupAgent(ApplicationInfo appInfo) {
14148        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14149        if (appInfo == null) {
14150            Slog.w(TAG, "unbind backup agent for null app");
14151            return;
14152        }
14153
14154        synchronized(this) {
14155            try {
14156                if (mBackupAppName == null) {
14157                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14158                    return;
14159                }
14160
14161                if (!mBackupAppName.equals(appInfo.packageName)) {
14162                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14163                    return;
14164                }
14165
14166                // Not backing this app up any more; reset its OOM adjustment
14167                final ProcessRecord proc = mBackupTarget.app;
14168                updateOomAdjLocked(proc);
14169
14170                // If the app crashed during backup, 'thread' will be null here
14171                if (proc.thread != null) {
14172                    try {
14173                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14174                                compatibilityInfoForPackageLocked(appInfo));
14175                    } catch (Exception e) {
14176                        Slog.e(TAG, "Exception when unbinding backup agent:");
14177                        e.printStackTrace();
14178                    }
14179                }
14180            } finally {
14181                mBackupTarget = null;
14182                mBackupAppName = null;
14183            }
14184        }
14185    }
14186    // =========================================================
14187    // BROADCASTS
14188    // =========================================================
14189
14190    private final List getStickiesLocked(String action, IntentFilter filter,
14191            List cur, int userId) {
14192        final ContentResolver resolver = mContext.getContentResolver();
14193        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14194        if (stickies == null) {
14195            return cur;
14196        }
14197        final ArrayList<Intent> list = stickies.get(action);
14198        if (list == null) {
14199            return cur;
14200        }
14201        int N = list.size();
14202        for (int i=0; i<N; i++) {
14203            Intent intent = list.get(i);
14204            if (filter.match(resolver, intent, true, TAG) >= 0) {
14205                if (cur == null) {
14206                    cur = new ArrayList<Intent>();
14207                }
14208                cur.add(intent);
14209            }
14210        }
14211        return cur;
14212    }
14213
14214    boolean isPendingBroadcastProcessLocked(int pid) {
14215        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14216                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14217    }
14218
14219    void skipPendingBroadcastLocked(int pid) {
14220            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14221            for (BroadcastQueue queue : mBroadcastQueues) {
14222                queue.skipPendingBroadcastLocked(pid);
14223            }
14224    }
14225
14226    // The app just attached; send any pending broadcasts that it should receive
14227    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14228        boolean didSomething = false;
14229        for (BroadcastQueue queue : mBroadcastQueues) {
14230            didSomething |= queue.sendPendingBroadcastsLocked(app);
14231        }
14232        return didSomething;
14233    }
14234
14235    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14236            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14237        enforceNotIsolatedCaller("registerReceiver");
14238        int callingUid;
14239        int callingPid;
14240        synchronized(this) {
14241            ProcessRecord callerApp = null;
14242            if (caller != null) {
14243                callerApp = getRecordForAppLocked(caller);
14244                if (callerApp == null) {
14245                    throw new SecurityException(
14246                            "Unable to find app for caller " + caller
14247                            + " (pid=" + Binder.getCallingPid()
14248                            + ") when registering receiver " + receiver);
14249                }
14250                if (callerApp.info.uid != Process.SYSTEM_UID &&
14251                        !callerApp.pkgList.containsKey(callerPackage) &&
14252                        !"android".equals(callerPackage)) {
14253                    throw new SecurityException("Given caller package " + callerPackage
14254                            + " is not running in process " + callerApp);
14255                }
14256                callingUid = callerApp.info.uid;
14257                callingPid = callerApp.pid;
14258            } else {
14259                callerPackage = null;
14260                callingUid = Binder.getCallingUid();
14261                callingPid = Binder.getCallingPid();
14262            }
14263
14264            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14265                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14266
14267            List allSticky = null;
14268
14269            // Look for any matching sticky broadcasts...
14270            Iterator actions = filter.actionsIterator();
14271            if (actions != null) {
14272                while (actions.hasNext()) {
14273                    String action = (String)actions.next();
14274                    allSticky = getStickiesLocked(action, filter, allSticky,
14275                            UserHandle.USER_ALL);
14276                    allSticky = getStickiesLocked(action, filter, allSticky,
14277                            UserHandle.getUserId(callingUid));
14278                }
14279            } else {
14280                allSticky = getStickiesLocked(null, filter, allSticky,
14281                        UserHandle.USER_ALL);
14282                allSticky = getStickiesLocked(null, filter, allSticky,
14283                        UserHandle.getUserId(callingUid));
14284            }
14285
14286            // The first sticky in the list is returned directly back to
14287            // the client.
14288            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14289
14290            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14291                    + ": " + sticky);
14292
14293            if (receiver == null) {
14294                return sticky;
14295            }
14296
14297            ReceiverList rl
14298                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14299            if (rl == null) {
14300                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14301                        userId, receiver);
14302                if (rl.app != null) {
14303                    rl.app.receivers.add(rl);
14304                } else {
14305                    try {
14306                        receiver.asBinder().linkToDeath(rl, 0);
14307                    } catch (RemoteException e) {
14308                        return sticky;
14309                    }
14310                    rl.linkedToDeath = true;
14311                }
14312                mRegisteredReceivers.put(receiver.asBinder(), rl);
14313            } else if (rl.uid != callingUid) {
14314                throw new IllegalArgumentException(
14315                        "Receiver requested to register for uid " + callingUid
14316                        + " was previously registered for uid " + rl.uid);
14317            } else if (rl.pid != callingPid) {
14318                throw new IllegalArgumentException(
14319                        "Receiver requested to register for pid " + callingPid
14320                        + " was previously registered for pid " + rl.pid);
14321            } else if (rl.userId != userId) {
14322                throw new IllegalArgumentException(
14323                        "Receiver requested to register for user " + userId
14324                        + " was previously registered for user " + rl.userId);
14325            }
14326            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14327                    permission, callingUid, userId);
14328            rl.add(bf);
14329            if (!bf.debugCheck()) {
14330                Slog.w(TAG, "==> For Dynamic broadast");
14331            }
14332            mReceiverResolver.addFilter(bf);
14333
14334            // Enqueue broadcasts for all existing stickies that match
14335            // this filter.
14336            if (allSticky != null) {
14337                ArrayList receivers = new ArrayList();
14338                receivers.add(bf);
14339
14340                int N = allSticky.size();
14341                for (int i=0; i<N; i++) {
14342                    Intent intent = (Intent)allSticky.get(i);
14343                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14344                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14345                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14346                            null, null, false, true, true, -1);
14347                    queue.enqueueParallelBroadcastLocked(r);
14348                    queue.scheduleBroadcastsLocked();
14349                }
14350            }
14351
14352            return sticky;
14353        }
14354    }
14355
14356    public void unregisterReceiver(IIntentReceiver receiver) {
14357        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14358
14359        final long origId = Binder.clearCallingIdentity();
14360        try {
14361            boolean doTrim = false;
14362
14363            synchronized(this) {
14364                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14365                if (rl != null) {
14366                    if (rl.curBroadcast != null) {
14367                        BroadcastRecord r = rl.curBroadcast;
14368                        final boolean doNext = finishReceiverLocked(
14369                                receiver.asBinder(), r.resultCode, r.resultData,
14370                                r.resultExtras, r.resultAbort);
14371                        if (doNext) {
14372                            doTrim = true;
14373                            r.queue.processNextBroadcast(false);
14374                        }
14375                    }
14376
14377                    if (rl.app != null) {
14378                        rl.app.receivers.remove(rl);
14379                    }
14380                    removeReceiverLocked(rl);
14381                    if (rl.linkedToDeath) {
14382                        rl.linkedToDeath = false;
14383                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14384                    }
14385                }
14386            }
14387
14388            // If we actually concluded any broadcasts, we might now be able
14389            // to trim the recipients' apps from our working set
14390            if (doTrim) {
14391                trimApplications();
14392                return;
14393            }
14394
14395        } finally {
14396            Binder.restoreCallingIdentity(origId);
14397        }
14398    }
14399
14400    void removeReceiverLocked(ReceiverList rl) {
14401        mRegisteredReceivers.remove(rl.receiver.asBinder());
14402        int N = rl.size();
14403        for (int i=0; i<N; i++) {
14404            mReceiverResolver.removeFilter(rl.get(i));
14405        }
14406    }
14407
14408    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14409        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14410            ProcessRecord r = mLruProcesses.get(i);
14411            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14412                try {
14413                    r.thread.dispatchPackageBroadcast(cmd, packages);
14414                } catch (RemoteException ex) {
14415                }
14416            }
14417        }
14418    }
14419
14420    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14421            int[] users) {
14422        List<ResolveInfo> receivers = null;
14423        try {
14424            HashSet<ComponentName> singleUserReceivers = null;
14425            boolean scannedFirstReceivers = false;
14426            for (int user : users) {
14427                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14428                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14429                if (user != 0 && newReceivers != null) {
14430                    // If this is not the primary user, we need to check for
14431                    // any receivers that should be filtered out.
14432                    for (int i=0; i<newReceivers.size(); i++) {
14433                        ResolveInfo ri = newReceivers.get(i);
14434                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14435                            newReceivers.remove(i);
14436                            i--;
14437                        }
14438                    }
14439                }
14440                if (newReceivers != null && newReceivers.size() == 0) {
14441                    newReceivers = null;
14442                }
14443                if (receivers == null) {
14444                    receivers = newReceivers;
14445                } else if (newReceivers != null) {
14446                    // We need to concatenate the additional receivers
14447                    // found with what we have do far.  This would be easy,
14448                    // but we also need to de-dup any receivers that are
14449                    // singleUser.
14450                    if (!scannedFirstReceivers) {
14451                        // Collect any single user receivers we had already retrieved.
14452                        scannedFirstReceivers = true;
14453                        for (int i=0; i<receivers.size(); i++) {
14454                            ResolveInfo ri = receivers.get(i);
14455                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14456                                ComponentName cn = new ComponentName(
14457                                        ri.activityInfo.packageName, ri.activityInfo.name);
14458                                if (singleUserReceivers == null) {
14459                                    singleUserReceivers = new HashSet<ComponentName>();
14460                                }
14461                                singleUserReceivers.add(cn);
14462                            }
14463                        }
14464                    }
14465                    // Add the new results to the existing results, tracking
14466                    // and de-dupping single user receivers.
14467                    for (int i=0; i<newReceivers.size(); i++) {
14468                        ResolveInfo ri = newReceivers.get(i);
14469                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14470                            ComponentName cn = new ComponentName(
14471                                    ri.activityInfo.packageName, ri.activityInfo.name);
14472                            if (singleUserReceivers == null) {
14473                                singleUserReceivers = new HashSet<ComponentName>();
14474                            }
14475                            if (!singleUserReceivers.contains(cn)) {
14476                                singleUserReceivers.add(cn);
14477                                receivers.add(ri);
14478                            }
14479                        } else {
14480                            receivers.add(ri);
14481                        }
14482                    }
14483                }
14484            }
14485        } catch (RemoteException ex) {
14486            // pm is in same process, this will never happen.
14487        }
14488        return receivers;
14489    }
14490
14491    private final int broadcastIntentLocked(ProcessRecord callerApp,
14492            String callerPackage, Intent intent, String resolvedType,
14493            IIntentReceiver resultTo, int resultCode, String resultData,
14494            Bundle map, String requiredPermission, int appOp,
14495            boolean ordered, boolean sticky, int callingPid, int callingUid,
14496            int userId) {
14497        intent = new Intent(intent);
14498
14499        // By default broadcasts do not go to stopped apps.
14500        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
14501
14502        if (DEBUG_BROADCAST_LIGHT) Slog.v(
14503            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
14504            + " ordered=" + ordered + " userid=" + userId);
14505        if ((resultTo != null) && !ordered) {
14506            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
14507        }
14508
14509        userId = handleIncomingUser(callingPid, callingUid, userId,
14510                true, ALLOW_NON_FULL, "broadcast", callerPackage);
14511
14512        // Make sure that the user who is receiving this broadcast is started.
14513        // If not, we will just skip it.
14514
14515
14516        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
14517            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14518                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14519                Slog.w(TAG, "Skipping broadcast of " + intent
14520                        + ": user " + userId + " is stopped");
14521                return ActivityManager.BROADCAST_SUCCESS;
14522            }
14523        }
14524
14525        /*
14526         * Prevent non-system code (defined here to be non-persistent
14527         * processes) from sending protected broadcasts.
14528         */
14529        int callingAppId = UserHandle.getAppId(callingUid);
14530        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14531            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14532            || callingAppId == Process.NFC_UID || callingUid == 0) {
14533            // Always okay.
14534        } else if (callerApp == null || !callerApp.persistent) {
14535            try {
14536                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14537                        intent.getAction())) {
14538                    String msg = "Permission Denial: not allowed to send broadcast "
14539                            + intent.getAction() + " from pid="
14540                            + callingPid + ", uid=" + callingUid;
14541                    Slog.w(TAG, msg);
14542                    throw new SecurityException(msg);
14543                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14544                    // Special case for compatibility: we don't want apps to send this,
14545                    // but historically it has not been protected and apps may be using it
14546                    // to poke their own app widget.  So, instead of making it protected,
14547                    // just limit it to the caller.
14548                    if (callerApp == null) {
14549                        String msg = "Permission Denial: not allowed to send broadcast "
14550                                + intent.getAction() + " from unknown caller.";
14551                        Slog.w(TAG, msg);
14552                        throw new SecurityException(msg);
14553                    } else if (intent.getComponent() != null) {
14554                        // They are good enough to send to an explicit component...  verify
14555                        // it is being sent to the calling app.
14556                        if (!intent.getComponent().getPackageName().equals(
14557                                callerApp.info.packageName)) {
14558                            String msg = "Permission Denial: not allowed to send broadcast "
14559                                    + intent.getAction() + " to "
14560                                    + intent.getComponent().getPackageName() + " from "
14561                                    + callerApp.info.packageName;
14562                            Slog.w(TAG, msg);
14563                            throw new SecurityException(msg);
14564                        }
14565                    } else {
14566                        // Limit broadcast to their own package.
14567                        intent.setPackage(callerApp.info.packageName);
14568                    }
14569                }
14570            } catch (RemoteException e) {
14571                Slog.w(TAG, "Remote exception", e);
14572                return ActivityManager.BROADCAST_SUCCESS;
14573            }
14574        }
14575
14576        // Handle special intents: if this broadcast is from the package
14577        // manager about a package being removed, we need to remove all of
14578        // its activities from the history stack.
14579        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14580                intent.getAction());
14581        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14582                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14583                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14584                || uidRemoved) {
14585            if (checkComponentPermission(
14586                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14587                    callingPid, callingUid, -1, true)
14588                    == PackageManager.PERMISSION_GRANTED) {
14589                if (uidRemoved) {
14590                    final Bundle intentExtras = intent.getExtras();
14591                    final int uid = intentExtras != null
14592                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14593                    if (uid >= 0) {
14594                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14595                        synchronized (bs) {
14596                            bs.removeUidStatsLocked(uid);
14597                        }
14598                        mAppOpsService.uidRemoved(uid);
14599                    }
14600                } else {
14601                    // If resources are unavailable just force stop all
14602                    // those packages and flush the attribute cache as well.
14603                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14604                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14605                        if (list != null && (list.length > 0)) {
14606                            for (String pkg : list) {
14607                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14608                                        "storage unmount");
14609                            }
14610                            sendPackageBroadcastLocked(
14611                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14612                        }
14613                    } else {
14614                        Uri data = intent.getData();
14615                        String ssp;
14616                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14617                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14618                                    intent.getAction());
14619                            boolean fullUninstall = removed &&
14620                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14621                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14622                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14623                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14624                                        false, fullUninstall, userId,
14625                                        removed ? "pkg removed" : "pkg changed");
14626                            }
14627                            if (removed) {
14628                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14629                                        new String[] {ssp}, userId);
14630                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14631                                    mAppOpsService.packageRemoved(
14632                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14633
14634                                    // Remove all permissions granted from/to this package
14635                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14636                                }
14637                            }
14638                        }
14639                    }
14640                }
14641            } else {
14642                String msg = "Permission Denial: " + intent.getAction()
14643                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14644                        + ", uid=" + callingUid + ")"
14645                        + " requires "
14646                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14647                Slog.w(TAG, msg);
14648                throw new SecurityException(msg);
14649            }
14650
14651        // Special case for adding a package: by default turn on compatibility
14652        // mode.
14653        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14654            Uri data = intent.getData();
14655            String ssp;
14656            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14657                mCompatModePackages.handlePackageAddedLocked(ssp,
14658                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14659            }
14660        }
14661
14662        /*
14663         * If this is the time zone changed action, queue up a message that will reset the timezone
14664         * of all currently running processes. This message will get queued up before the broadcast
14665         * happens.
14666         */
14667        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14668            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14669        }
14670
14671        /*
14672         * If the user set the time, let all running processes know.
14673         */
14674        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14675            final int is24Hour = intent.getBooleanExtra(
14676                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14677            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14678        }
14679
14680        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14681            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14682        }
14683
14684        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14685            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14686            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14687        }
14688
14689        // Add to the sticky list if requested.
14690        if (sticky) {
14691            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14692                    callingPid, callingUid)
14693                    != PackageManager.PERMISSION_GRANTED) {
14694                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14695                        + callingPid + ", uid=" + callingUid
14696                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14697                Slog.w(TAG, msg);
14698                throw new SecurityException(msg);
14699            }
14700            if (requiredPermission != null) {
14701                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14702                        + " and enforce permission " + requiredPermission);
14703                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14704            }
14705            if (intent.getComponent() != null) {
14706                throw new SecurityException(
14707                        "Sticky broadcasts can't target a specific component");
14708            }
14709            // We use userId directly here, since the "all" target is maintained
14710            // as a separate set of sticky broadcasts.
14711            if (userId != UserHandle.USER_ALL) {
14712                // But first, if this is not a broadcast to all users, then
14713                // make sure it doesn't conflict with an existing broadcast to
14714                // all users.
14715                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14716                        UserHandle.USER_ALL);
14717                if (stickies != null) {
14718                    ArrayList<Intent> list = stickies.get(intent.getAction());
14719                    if (list != null) {
14720                        int N = list.size();
14721                        int i;
14722                        for (i=0; i<N; i++) {
14723                            if (intent.filterEquals(list.get(i))) {
14724                                throw new IllegalArgumentException(
14725                                        "Sticky broadcast " + intent + " for user "
14726                                        + userId + " conflicts with existing global broadcast");
14727                            }
14728                        }
14729                    }
14730                }
14731            }
14732            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14733            if (stickies == null) {
14734                stickies = new ArrayMap<String, ArrayList<Intent>>();
14735                mStickyBroadcasts.put(userId, stickies);
14736            }
14737            ArrayList<Intent> list = stickies.get(intent.getAction());
14738            if (list == null) {
14739                list = new ArrayList<Intent>();
14740                stickies.put(intent.getAction(), list);
14741            }
14742            int N = list.size();
14743            int i;
14744            for (i=0; i<N; i++) {
14745                if (intent.filterEquals(list.get(i))) {
14746                    // This sticky already exists, replace it.
14747                    list.set(i, new Intent(intent));
14748                    break;
14749                }
14750            }
14751            if (i >= N) {
14752                list.add(new Intent(intent));
14753            }
14754        }
14755
14756        int[] users;
14757        if (userId == UserHandle.USER_ALL) {
14758            // Caller wants broadcast to go to all started users.
14759            users = mStartedUserArray;
14760        } else {
14761            // Caller wants broadcast to go to one specific user.
14762            users = new int[] {userId};
14763        }
14764
14765        // Figure out who all will receive this broadcast.
14766        List receivers = null;
14767        List<BroadcastFilter> registeredReceivers = null;
14768        // Need to resolve the intent to interested receivers...
14769        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14770                 == 0) {
14771            receivers = collectReceiverComponents(intent, resolvedType, users);
14772        }
14773        if (intent.getComponent() == null) {
14774            registeredReceivers = mReceiverResolver.queryIntent(intent,
14775                    resolvedType, false, userId);
14776        }
14777
14778        final boolean replacePending =
14779                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14780
14781        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14782                + " replacePending=" + replacePending);
14783
14784        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14785        if (!ordered && NR > 0) {
14786            // If we are not serializing this broadcast, then send the
14787            // registered receivers separately so they don't wait for the
14788            // components to be launched.
14789            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14790            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14791                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14792                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14793                    ordered, sticky, false, userId);
14794            if (DEBUG_BROADCAST) Slog.v(
14795                    TAG, "Enqueueing parallel broadcast " + r);
14796            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14797            if (!replaced) {
14798                queue.enqueueParallelBroadcastLocked(r);
14799                queue.scheduleBroadcastsLocked();
14800            }
14801            registeredReceivers = null;
14802            NR = 0;
14803        }
14804
14805        // Merge into one list.
14806        int ir = 0;
14807        if (receivers != null) {
14808            // A special case for PACKAGE_ADDED: do not allow the package
14809            // being added to see this broadcast.  This prevents them from
14810            // using this as a back door to get run as soon as they are
14811            // installed.  Maybe in the future we want to have a special install
14812            // broadcast or such for apps, but we'd like to deliberately make
14813            // this decision.
14814            String skipPackages[] = null;
14815            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14816                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14817                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14818                Uri data = intent.getData();
14819                if (data != null) {
14820                    String pkgName = data.getSchemeSpecificPart();
14821                    if (pkgName != null) {
14822                        skipPackages = new String[] { pkgName };
14823                    }
14824                }
14825            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14826                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14827            }
14828            if (skipPackages != null && (skipPackages.length > 0)) {
14829                for (String skipPackage : skipPackages) {
14830                    if (skipPackage != null) {
14831                        int NT = receivers.size();
14832                        for (int it=0; it<NT; it++) {
14833                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14834                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14835                                receivers.remove(it);
14836                                it--;
14837                                NT--;
14838                            }
14839                        }
14840                    }
14841                }
14842            }
14843
14844            int NT = receivers != null ? receivers.size() : 0;
14845            int it = 0;
14846            ResolveInfo curt = null;
14847            BroadcastFilter curr = null;
14848            while (it < NT && ir < NR) {
14849                if (curt == null) {
14850                    curt = (ResolveInfo)receivers.get(it);
14851                }
14852                if (curr == null) {
14853                    curr = registeredReceivers.get(ir);
14854                }
14855                if (curr.getPriority() >= curt.priority) {
14856                    // Insert this broadcast record into the final list.
14857                    receivers.add(it, curr);
14858                    ir++;
14859                    curr = null;
14860                    it++;
14861                    NT++;
14862                } else {
14863                    // Skip to the next ResolveInfo in the final list.
14864                    it++;
14865                    curt = null;
14866                }
14867            }
14868        }
14869        while (ir < NR) {
14870            if (receivers == null) {
14871                receivers = new ArrayList();
14872            }
14873            receivers.add(registeredReceivers.get(ir));
14874            ir++;
14875        }
14876
14877        if ((receivers != null && receivers.size() > 0)
14878                || resultTo != null) {
14879            BroadcastQueue queue = broadcastQueueForIntent(intent);
14880            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14881                    callerPackage, callingPid, callingUid, resolvedType,
14882                    requiredPermission, appOp, receivers, resultTo, resultCode,
14883                    resultData, map, ordered, sticky, false, userId);
14884            if (DEBUG_BROADCAST) Slog.v(
14885                    TAG, "Enqueueing ordered broadcast " + r
14886                    + ": prev had " + queue.mOrderedBroadcasts.size());
14887            if (DEBUG_BROADCAST) {
14888                int seq = r.intent.getIntExtra("seq", -1);
14889                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14890            }
14891            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14892            if (!replaced) {
14893                queue.enqueueOrderedBroadcastLocked(r);
14894                queue.scheduleBroadcastsLocked();
14895            }
14896        }
14897
14898        return ActivityManager.BROADCAST_SUCCESS;
14899    }
14900
14901    final Intent verifyBroadcastLocked(Intent intent) {
14902        // Refuse possible leaked file descriptors
14903        if (intent != null && intent.hasFileDescriptors() == true) {
14904            throw new IllegalArgumentException("File descriptors passed in Intent");
14905        }
14906
14907        int flags = intent.getFlags();
14908
14909        if (!mProcessesReady) {
14910            // if the caller really truly claims to know what they're doing, go
14911            // ahead and allow the broadcast without launching any receivers
14912            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14913                intent = new Intent(intent);
14914                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14915            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14916                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14917                        + " before boot completion");
14918                throw new IllegalStateException("Cannot broadcast before boot completed");
14919            }
14920        }
14921
14922        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14923            throw new IllegalArgumentException(
14924                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14925        }
14926
14927        return intent;
14928    }
14929
14930    public final int broadcastIntent(IApplicationThread caller,
14931            Intent intent, String resolvedType, IIntentReceiver resultTo,
14932            int resultCode, String resultData, Bundle map,
14933            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14934        enforceNotIsolatedCaller("broadcastIntent");
14935        synchronized(this) {
14936            intent = verifyBroadcastLocked(intent);
14937
14938            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14939            final int callingPid = Binder.getCallingPid();
14940            final int callingUid = Binder.getCallingUid();
14941            final long origId = Binder.clearCallingIdentity();
14942            int res = broadcastIntentLocked(callerApp,
14943                    callerApp != null ? callerApp.info.packageName : null,
14944                    intent, resolvedType, resultTo,
14945                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14946                    callingPid, callingUid, userId);
14947            Binder.restoreCallingIdentity(origId);
14948            return res;
14949        }
14950    }
14951
14952    int broadcastIntentInPackage(String packageName, int uid,
14953            Intent intent, String resolvedType, IIntentReceiver resultTo,
14954            int resultCode, String resultData, Bundle map,
14955            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14956        synchronized(this) {
14957            intent = verifyBroadcastLocked(intent);
14958
14959            final long origId = Binder.clearCallingIdentity();
14960            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14961                    resultTo, resultCode, resultData, map, requiredPermission,
14962                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14963            Binder.restoreCallingIdentity(origId);
14964            return res;
14965        }
14966    }
14967
14968    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14969        // Refuse possible leaked file descriptors
14970        if (intent != null && intent.hasFileDescriptors() == true) {
14971            throw new IllegalArgumentException("File descriptors passed in Intent");
14972        }
14973
14974        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14975                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
14976
14977        synchronized(this) {
14978            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14979                    != PackageManager.PERMISSION_GRANTED) {
14980                String msg = "Permission Denial: unbroadcastIntent() from pid="
14981                        + Binder.getCallingPid()
14982                        + ", uid=" + Binder.getCallingUid()
14983                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14984                Slog.w(TAG, msg);
14985                throw new SecurityException(msg);
14986            }
14987            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14988            if (stickies != null) {
14989                ArrayList<Intent> list = stickies.get(intent.getAction());
14990                if (list != null) {
14991                    int N = list.size();
14992                    int i;
14993                    for (i=0; i<N; i++) {
14994                        if (intent.filterEquals(list.get(i))) {
14995                            list.remove(i);
14996                            break;
14997                        }
14998                    }
14999                    if (list.size() <= 0) {
15000                        stickies.remove(intent.getAction());
15001                    }
15002                }
15003                if (stickies.size() <= 0) {
15004                    mStickyBroadcasts.remove(userId);
15005                }
15006            }
15007        }
15008    }
15009
15010    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15011            String resultData, Bundle resultExtras, boolean resultAbort) {
15012        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15013        if (r == null) {
15014            Slog.w(TAG, "finishReceiver called but not found on queue");
15015            return false;
15016        }
15017
15018        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15019    }
15020
15021    void backgroundServicesFinishedLocked(int userId) {
15022        for (BroadcastQueue queue : mBroadcastQueues) {
15023            queue.backgroundServicesFinishedLocked(userId);
15024        }
15025    }
15026
15027    public void finishReceiver(IBinder who, int resultCode, String resultData,
15028            Bundle resultExtras, boolean resultAbort) {
15029        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15030
15031        // Refuse possible leaked file descriptors
15032        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15033            throw new IllegalArgumentException("File descriptors passed in Bundle");
15034        }
15035
15036        final long origId = Binder.clearCallingIdentity();
15037        try {
15038            boolean doNext = false;
15039            BroadcastRecord r;
15040
15041            synchronized(this) {
15042                r = broadcastRecordForReceiverLocked(who);
15043                if (r != null) {
15044                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15045                        resultData, resultExtras, resultAbort, true);
15046                }
15047            }
15048
15049            if (doNext) {
15050                r.queue.processNextBroadcast(false);
15051            }
15052            trimApplications();
15053        } finally {
15054            Binder.restoreCallingIdentity(origId);
15055        }
15056    }
15057
15058    // =========================================================
15059    // INSTRUMENTATION
15060    // =========================================================
15061
15062    public boolean startInstrumentation(ComponentName className,
15063            String profileFile, int flags, Bundle arguments,
15064            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15065            int userId, String abiOverride) {
15066        enforceNotIsolatedCaller("startInstrumentation");
15067        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15068                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15069        // Refuse possible leaked file descriptors
15070        if (arguments != null && arguments.hasFileDescriptors()) {
15071            throw new IllegalArgumentException("File descriptors passed in Bundle");
15072        }
15073
15074        synchronized(this) {
15075            InstrumentationInfo ii = null;
15076            ApplicationInfo ai = null;
15077            try {
15078                ii = mContext.getPackageManager().getInstrumentationInfo(
15079                    className, STOCK_PM_FLAGS);
15080                ai = AppGlobals.getPackageManager().getApplicationInfo(
15081                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15082            } catch (PackageManager.NameNotFoundException e) {
15083            } catch (RemoteException e) {
15084            }
15085            if (ii == null) {
15086                reportStartInstrumentationFailure(watcher, className,
15087                        "Unable to find instrumentation info for: " + className);
15088                return false;
15089            }
15090            if (ai == null) {
15091                reportStartInstrumentationFailure(watcher, className,
15092                        "Unable to find instrumentation target package: " + ii.targetPackage);
15093                return false;
15094            }
15095
15096            int match = mContext.getPackageManager().checkSignatures(
15097                    ii.targetPackage, ii.packageName);
15098            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15099                String msg = "Permission Denial: starting instrumentation "
15100                        + className + " from pid="
15101                        + Binder.getCallingPid()
15102                        + ", uid=" + Binder.getCallingPid()
15103                        + " not allowed because package " + ii.packageName
15104                        + " does not have a signature matching the target "
15105                        + ii.targetPackage;
15106                reportStartInstrumentationFailure(watcher, className, msg);
15107                throw new SecurityException(msg);
15108            }
15109
15110            final long origId = Binder.clearCallingIdentity();
15111            // Instrumentation can kill and relaunch even persistent processes
15112            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15113                    "start instr");
15114            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15115            app.instrumentationClass = className;
15116            app.instrumentationInfo = ai;
15117            app.instrumentationProfileFile = profileFile;
15118            app.instrumentationArguments = arguments;
15119            app.instrumentationWatcher = watcher;
15120            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15121            app.instrumentationResultClass = className;
15122            Binder.restoreCallingIdentity(origId);
15123        }
15124
15125        return true;
15126    }
15127
15128    /**
15129     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15130     * error to the logs, but if somebody is watching, send the report there too.  This enables
15131     * the "am" command to report errors with more information.
15132     *
15133     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15134     * @param cn The component name of the instrumentation.
15135     * @param report The error report.
15136     */
15137    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15138            ComponentName cn, String report) {
15139        Slog.w(TAG, report);
15140        try {
15141            if (watcher != null) {
15142                Bundle results = new Bundle();
15143                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15144                results.putString("Error", report);
15145                watcher.instrumentationStatus(cn, -1, results);
15146            }
15147        } catch (RemoteException e) {
15148            Slog.w(TAG, e);
15149        }
15150    }
15151
15152    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15153        if (app.instrumentationWatcher != null) {
15154            try {
15155                // NOTE:  IInstrumentationWatcher *must* be oneway here
15156                app.instrumentationWatcher.instrumentationFinished(
15157                    app.instrumentationClass,
15158                    resultCode,
15159                    results);
15160            } catch (RemoteException e) {
15161            }
15162        }
15163        if (app.instrumentationUiAutomationConnection != null) {
15164            try {
15165                app.instrumentationUiAutomationConnection.shutdown();
15166            } catch (RemoteException re) {
15167                /* ignore */
15168            }
15169            // Only a UiAutomation can set this flag and now that
15170            // it is finished we make sure it is reset to its default.
15171            mUserIsMonkey = false;
15172        }
15173        app.instrumentationWatcher = null;
15174        app.instrumentationUiAutomationConnection = null;
15175        app.instrumentationClass = null;
15176        app.instrumentationInfo = null;
15177        app.instrumentationProfileFile = null;
15178        app.instrumentationArguments = null;
15179
15180        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15181                "finished inst");
15182    }
15183
15184    public void finishInstrumentation(IApplicationThread target,
15185            int resultCode, Bundle results) {
15186        int userId = UserHandle.getCallingUserId();
15187        // Refuse possible leaked file descriptors
15188        if (results != null && results.hasFileDescriptors()) {
15189            throw new IllegalArgumentException("File descriptors passed in Intent");
15190        }
15191
15192        synchronized(this) {
15193            ProcessRecord app = getRecordForAppLocked(target);
15194            if (app == null) {
15195                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15196                return;
15197            }
15198            final long origId = Binder.clearCallingIdentity();
15199            finishInstrumentationLocked(app, resultCode, results);
15200            Binder.restoreCallingIdentity(origId);
15201        }
15202    }
15203
15204    // =========================================================
15205    // CONFIGURATION
15206    // =========================================================
15207
15208    public ConfigurationInfo getDeviceConfigurationInfo() {
15209        ConfigurationInfo config = new ConfigurationInfo();
15210        synchronized (this) {
15211            config.reqTouchScreen = mConfiguration.touchscreen;
15212            config.reqKeyboardType = mConfiguration.keyboard;
15213            config.reqNavigation = mConfiguration.navigation;
15214            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15215                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15216                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15217            }
15218            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15219                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15220                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15221            }
15222            config.reqGlEsVersion = GL_ES_VERSION;
15223        }
15224        return config;
15225    }
15226
15227    ActivityStack getFocusedStack() {
15228        return mStackSupervisor.getFocusedStack();
15229    }
15230
15231    public Configuration getConfiguration() {
15232        Configuration ci;
15233        synchronized(this) {
15234            ci = new Configuration(mConfiguration);
15235        }
15236        return ci;
15237    }
15238
15239    public void updatePersistentConfiguration(Configuration values) {
15240        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15241                "updateConfiguration()");
15242        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15243                "updateConfiguration()");
15244        if (values == null) {
15245            throw new NullPointerException("Configuration must not be null");
15246        }
15247
15248        synchronized(this) {
15249            final long origId = Binder.clearCallingIdentity();
15250            updateConfigurationLocked(values, null, true, false);
15251            Binder.restoreCallingIdentity(origId);
15252        }
15253    }
15254
15255    public void updateConfiguration(Configuration values) {
15256        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15257                "updateConfiguration()");
15258
15259        synchronized(this) {
15260            if (values == null && mWindowManager != null) {
15261                // sentinel: fetch the current configuration from the window manager
15262                values = mWindowManager.computeNewConfiguration();
15263            }
15264
15265            if (mWindowManager != null) {
15266                mProcessList.applyDisplaySize(mWindowManager);
15267            }
15268
15269            final long origId = Binder.clearCallingIdentity();
15270            if (values != null) {
15271                Settings.System.clearConfiguration(values);
15272            }
15273            updateConfigurationLocked(values, null, false, false);
15274            Binder.restoreCallingIdentity(origId);
15275        }
15276    }
15277
15278    /**
15279     * Do either or both things: (1) change the current configuration, and (2)
15280     * make sure the given activity is running with the (now) current
15281     * configuration.  Returns true if the activity has been left running, or
15282     * false if <var>starting</var> is being destroyed to match the new
15283     * configuration.
15284     * @param persistent TODO
15285     */
15286    boolean updateConfigurationLocked(Configuration values,
15287            ActivityRecord starting, boolean persistent, boolean initLocale) {
15288        int changes = 0;
15289
15290        if (values != null) {
15291            Configuration newConfig = new Configuration(mConfiguration);
15292            changes = newConfig.updateFrom(values);
15293            if (changes != 0) {
15294                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15295                    Slog.i(TAG, "Updating configuration to: " + values);
15296                }
15297
15298                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15299
15300                if (values.locale != null && !initLocale) {
15301                    saveLocaleLocked(values.locale,
15302                                     !values.locale.equals(mConfiguration.locale),
15303                                     values.userSetLocale);
15304                }
15305
15306                mConfigurationSeq++;
15307                if (mConfigurationSeq <= 0) {
15308                    mConfigurationSeq = 1;
15309                }
15310                newConfig.seq = mConfigurationSeq;
15311                mConfiguration = newConfig;
15312                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15313                //mUsageStatsService.noteStartConfig(newConfig);
15314
15315                final Configuration configCopy = new Configuration(mConfiguration);
15316
15317                // TODO: If our config changes, should we auto dismiss any currently
15318                // showing dialogs?
15319                mShowDialogs = shouldShowDialogs(newConfig);
15320
15321                AttributeCache ac = AttributeCache.instance();
15322                if (ac != null) {
15323                    ac.updateConfiguration(configCopy);
15324                }
15325
15326                // Make sure all resources in our process are updated
15327                // right now, so that anyone who is going to retrieve
15328                // resource values after we return will be sure to get
15329                // the new ones.  This is especially important during
15330                // boot, where the first config change needs to guarantee
15331                // all resources have that config before following boot
15332                // code is executed.
15333                mSystemThread.applyConfigurationToResources(configCopy);
15334
15335                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15336                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15337                    msg.obj = new Configuration(configCopy);
15338                    mHandler.sendMessage(msg);
15339                }
15340
15341                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15342                    ProcessRecord app = mLruProcesses.get(i);
15343                    try {
15344                        if (app.thread != null) {
15345                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15346                                    + app.processName + " new config " + mConfiguration);
15347                            app.thread.scheduleConfigurationChanged(configCopy);
15348                        }
15349                    } catch (Exception e) {
15350                    }
15351                }
15352                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15353                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15354                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15355                        | Intent.FLAG_RECEIVER_FOREGROUND);
15356                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15357                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15358                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15359                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15360                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15361                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15362                    broadcastIntentLocked(null, null, intent,
15363                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15364                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15365                }
15366            }
15367        }
15368
15369        boolean kept = true;
15370        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15371        // mainStack is null during startup.
15372        if (mainStack != null) {
15373            if (changes != 0 && starting == null) {
15374                // If the configuration changed, and the caller is not already
15375                // in the process of starting an activity, then find the top
15376                // activity to check if its configuration needs to change.
15377                starting = mainStack.topRunningActivityLocked(null);
15378            }
15379
15380            if (starting != null) {
15381                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15382                // And we need to make sure at this point that all other activities
15383                // are made visible with the correct configuration.
15384                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15385            }
15386        }
15387
15388        if (values != null && mWindowManager != null) {
15389            mWindowManager.setNewConfiguration(mConfiguration);
15390        }
15391
15392        return kept;
15393    }
15394
15395    /**
15396     * Decide based on the configuration whether we should shouw the ANR,
15397     * crash, etc dialogs.  The idea is that if there is no affordnace to
15398     * press the on-screen buttons, we shouldn't show the dialog.
15399     *
15400     * A thought: SystemUI might also want to get told about this, the Power
15401     * dialog / global actions also might want different behaviors.
15402     */
15403    private static final boolean shouldShowDialogs(Configuration config) {
15404        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15405                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15406    }
15407
15408    /**
15409     * Save the locale.  You must be inside a synchronized (this) block.
15410     */
15411    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15412        if(isDiff) {
15413            SystemProperties.set("user.language", l.getLanguage());
15414            SystemProperties.set("user.region", l.getCountry());
15415        }
15416
15417        if(isPersist) {
15418            SystemProperties.set("persist.sys.language", l.getLanguage());
15419            SystemProperties.set("persist.sys.country", l.getCountry());
15420            SystemProperties.set("persist.sys.localevar", l.getVariant());
15421        }
15422    }
15423
15424    @Override
15425    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
15426        ActivityRecord srec = ActivityRecord.forToken(token);
15427        return srec != null && srec.task.affinity != null &&
15428                srec.task.affinity.equals(destAffinity);
15429    }
15430
15431    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15432            Intent resultData) {
15433
15434        synchronized (this) {
15435            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15436            if (stack != null) {
15437                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15438            }
15439            return false;
15440        }
15441    }
15442
15443    public int getLaunchedFromUid(IBinder activityToken) {
15444        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15445        if (srec == null) {
15446            return -1;
15447        }
15448        return srec.launchedFromUid;
15449    }
15450
15451    public String getLaunchedFromPackage(IBinder activityToken) {
15452        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15453        if (srec == null) {
15454            return null;
15455        }
15456        return srec.launchedFromPackage;
15457    }
15458
15459    // =========================================================
15460    // LIFETIME MANAGEMENT
15461    // =========================================================
15462
15463    // Returns which broadcast queue the app is the current [or imminent] receiver
15464    // on, or 'null' if the app is not an active broadcast recipient.
15465    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
15466        BroadcastRecord r = app.curReceiver;
15467        if (r != null) {
15468            return r.queue;
15469        }
15470
15471        // It's not the current receiver, but it might be starting up to become one
15472        synchronized (this) {
15473            for (BroadcastQueue queue : mBroadcastQueues) {
15474                r = queue.mPendingBroadcast;
15475                if (r != null && r.curApp == app) {
15476                    // found it; report which queue it's in
15477                    return queue;
15478                }
15479            }
15480        }
15481
15482        return null;
15483    }
15484
15485    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
15486            boolean doingAll, long now) {
15487        if (mAdjSeq == app.adjSeq) {
15488            // This adjustment has already been computed.
15489            return app.curRawAdj;
15490        }
15491
15492        if (app.thread == null) {
15493            app.adjSeq = mAdjSeq;
15494            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15495            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15496            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
15497        }
15498
15499        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
15500        app.adjSource = null;
15501        app.adjTarget = null;
15502        app.empty = false;
15503        app.cached = false;
15504
15505        final int activitiesSize = app.activities.size();
15506
15507        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15508            // The max adjustment doesn't allow this app to be anything
15509            // below foreground, so it is not worth doing work for it.
15510            app.adjType = "fixed";
15511            app.adjSeq = mAdjSeq;
15512            app.curRawAdj = app.maxAdj;
15513            app.foregroundActivities = false;
15514            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
15515            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
15516            // System processes can do UI, and when they do we want to have
15517            // them trim their memory after the user leaves the UI.  To
15518            // facilitate this, here we need to determine whether or not it
15519            // is currently showing UI.
15520            app.systemNoUi = true;
15521            if (app == TOP_APP) {
15522                app.systemNoUi = false;
15523            } else if (activitiesSize > 0) {
15524                for (int j = 0; j < activitiesSize; j++) {
15525                    final ActivityRecord r = app.activities.get(j);
15526                    if (r.visible) {
15527                        app.systemNoUi = false;
15528                    }
15529                }
15530            }
15531            if (!app.systemNoUi) {
15532                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15533            }
15534            return (app.curAdj=app.maxAdj);
15535        }
15536
15537        app.systemNoUi = false;
15538
15539        // Determine the importance of the process, starting with most
15540        // important to least, and assign an appropriate OOM adjustment.
15541        int adj;
15542        int schedGroup;
15543        int procState;
15544        boolean foregroundActivities = false;
15545        BroadcastQueue queue;
15546        if (app == TOP_APP) {
15547            // The last app on the list is the foreground app.
15548            adj = ProcessList.FOREGROUND_APP_ADJ;
15549            schedGroup = Process.THREAD_GROUP_DEFAULT;
15550            app.adjType = "top-activity";
15551            foregroundActivities = true;
15552            procState = ActivityManager.PROCESS_STATE_TOP;
15553        } else if (app.instrumentationClass != null) {
15554            // Don't want to kill running instrumentation.
15555            adj = ProcessList.FOREGROUND_APP_ADJ;
15556            schedGroup = Process.THREAD_GROUP_DEFAULT;
15557            app.adjType = "instrumentation";
15558            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15559        } else if ((queue = isReceivingBroadcast(app)) != null) {
15560            // An app that is currently receiving a broadcast also
15561            // counts as being in the foreground for OOM killer purposes.
15562            // It's placed in a sched group based on the nature of the
15563            // broadcast as reflected by which queue it's active in.
15564            adj = ProcessList.FOREGROUND_APP_ADJ;
15565            schedGroup = (queue == mFgBroadcastQueue)
15566                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15567            app.adjType = "broadcast";
15568            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15569        } else if (app.executingServices.size() > 0) {
15570            // An app that is currently executing a service callback also
15571            // counts as being in the foreground.
15572            adj = ProcessList.FOREGROUND_APP_ADJ;
15573            schedGroup = app.execServicesFg ?
15574                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15575            app.adjType = "exec-service";
15576            procState = ActivityManager.PROCESS_STATE_SERVICE;
15577            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15578        } else {
15579            // As far as we know the process is empty.  We may change our mind later.
15580            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15581            // At this point we don't actually know the adjustment.  Use the cached adj
15582            // value that the caller wants us to.
15583            adj = cachedAdj;
15584            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15585            app.cached = true;
15586            app.empty = true;
15587            app.adjType = "cch-empty";
15588        }
15589
15590        // Examine all activities if not already foreground.
15591        if (!foregroundActivities && activitiesSize > 0) {
15592            for (int j = 0; j < activitiesSize; j++) {
15593                final ActivityRecord r = app.activities.get(j);
15594                if (r.app != app) {
15595                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15596                            + app + "?!?");
15597                    continue;
15598                }
15599                if (r.visible) {
15600                    // App has a visible activity; only upgrade adjustment.
15601                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15602                        adj = ProcessList.VISIBLE_APP_ADJ;
15603                        app.adjType = "visible";
15604                    }
15605                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15606                        procState = ActivityManager.PROCESS_STATE_TOP;
15607                    }
15608                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15609                    app.cached = false;
15610                    app.empty = false;
15611                    foregroundActivities = true;
15612                    break;
15613                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15614                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15615                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15616                        app.adjType = "pausing";
15617                    }
15618                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15619                        procState = ActivityManager.PROCESS_STATE_TOP;
15620                    }
15621                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15622                    app.cached = false;
15623                    app.empty = false;
15624                    foregroundActivities = true;
15625                } else if (r.state == ActivityState.STOPPING) {
15626                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15627                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15628                        app.adjType = "stopping";
15629                    }
15630                    // For the process state, we will at this point consider the
15631                    // process to be cached.  It will be cached either as an activity
15632                    // or empty depending on whether the activity is finishing.  We do
15633                    // this so that we can treat the process as cached for purposes of
15634                    // memory trimming (determing current memory level, trim command to
15635                    // send to process) since there can be an arbitrary number of stopping
15636                    // processes and they should soon all go into the cached state.
15637                    if (!r.finishing) {
15638                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15639                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15640                        }
15641                    }
15642                    app.cached = false;
15643                    app.empty = false;
15644                    foregroundActivities = true;
15645                } else {
15646                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15647                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15648                        app.adjType = "cch-act";
15649                    }
15650                }
15651            }
15652        }
15653
15654        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15655            if (app.foregroundServices) {
15656                // The user is aware of this app, so make it visible.
15657                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15658                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15659                app.cached = false;
15660                app.adjType = "fg-service";
15661                schedGroup = Process.THREAD_GROUP_DEFAULT;
15662            } else if (app.forcingToForeground != null) {
15663                // The user is aware of this app, so make it visible.
15664                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15665                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15666                app.cached = false;
15667                app.adjType = "force-fg";
15668                app.adjSource = app.forcingToForeground;
15669                schedGroup = Process.THREAD_GROUP_DEFAULT;
15670            }
15671        }
15672
15673        if (app == mHeavyWeightProcess) {
15674            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15675                // We don't want to kill the current heavy-weight process.
15676                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15677                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15678                app.cached = false;
15679                app.adjType = "heavy";
15680            }
15681            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15682                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15683            }
15684        }
15685
15686        if (app == mHomeProcess) {
15687            if (adj > ProcessList.HOME_APP_ADJ) {
15688                // This process is hosting what we currently consider to be the
15689                // home app, so we don't want to let it go into the background.
15690                adj = ProcessList.HOME_APP_ADJ;
15691                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15692                app.cached = false;
15693                app.adjType = "home";
15694            }
15695            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15696                procState = ActivityManager.PROCESS_STATE_HOME;
15697            }
15698        }
15699
15700        if (app == mPreviousProcess && app.activities.size() > 0) {
15701            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15702                // This was the previous process that showed UI to the user.
15703                // We want to try to keep it around more aggressively, to give
15704                // a good experience around switching between two apps.
15705                adj = ProcessList.PREVIOUS_APP_ADJ;
15706                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15707                app.cached = false;
15708                app.adjType = "previous";
15709            }
15710            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15711                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15712            }
15713        }
15714
15715        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15716                + " reason=" + app.adjType);
15717
15718        // By default, we use the computed adjustment.  It may be changed if
15719        // there are applications dependent on our services or providers, but
15720        // this gives us a baseline and makes sure we don't get into an
15721        // infinite recursion.
15722        app.adjSeq = mAdjSeq;
15723        app.curRawAdj = adj;
15724        app.hasStartedServices = false;
15725
15726        if (mBackupTarget != null && app == mBackupTarget.app) {
15727            // If possible we want to avoid killing apps while they're being backed up
15728            if (adj > ProcessList.BACKUP_APP_ADJ) {
15729                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15730                adj = ProcessList.BACKUP_APP_ADJ;
15731                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15732                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15733                }
15734                app.adjType = "backup";
15735                app.cached = false;
15736            }
15737            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15738                procState = ActivityManager.PROCESS_STATE_BACKUP;
15739            }
15740        }
15741
15742        boolean mayBeTop = false;
15743
15744        for (int is = app.services.size()-1;
15745                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15746                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15747                        || procState > ActivityManager.PROCESS_STATE_TOP);
15748                is--) {
15749            ServiceRecord s = app.services.valueAt(is);
15750            if (s.startRequested) {
15751                app.hasStartedServices = true;
15752                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15753                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15754                }
15755                if (app.hasShownUi && app != mHomeProcess) {
15756                    // If this process has shown some UI, let it immediately
15757                    // go to the LRU list because it may be pretty heavy with
15758                    // UI stuff.  We'll tag it with a label just to help
15759                    // debug and understand what is going on.
15760                    if (adj > ProcessList.SERVICE_ADJ) {
15761                        app.adjType = "cch-started-ui-services";
15762                    }
15763                } else {
15764                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15765                        // This service has seen some activity within
15766                        // recent memory, so we will keep its process ahead
15767                        // of the background processes.
15768                        if (adj > ProcessList.SERVICE_ADJ) {
15769                            adj = ProcessList.SERVICE_ADJ;
15770                            app.adjType = "started-services";
15771                            app.cached = false;
15772                        }
15773                    }
15774                    // If we have let the service slide into the background
15775                    // state, still have some text describing what it is doing
15776                    // even though the service no longer has an impact.
15777                    if (adj > ProcessList.SERVICE_ADJ) {
15778                        app.adjType = "cch-started-services";
15779                    }
15780                }
15781            }
15782            for (int conni = s.connections.size()-1;
15783                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15784                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15785                            || procState > ActivityManager.PROCESS_STATE_TOP);
15786                    conni--) {
15787                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15788                for (int i = 0;
15789                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15790                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15791                                || procState > ActivityManager.PROCESS_STATE_TOP);
15792                        i++) {
15793                    // XXX should compute this based on the max of
15794                    // all connected clients.
15795                    ConnectionRecord cr = clist.get(i);
15796                    if (cr.binding.client == app) {
15797                        // Binding to ourself is not interesting.
15798                        continue;
15799                    }
15800                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15801                        ProcessRecord client = cr.binding.client;
15802                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15803                                TOP_APP, doingAll, now);
15804                        int clientProcState = client.curProcState;
15805                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15806                            // If the other app is cached for any reason, for purposes here
15807                            // we are going to consider it empty.  The specific cached state
15808                            // doesn't propagate except under certain conditions.
15809                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15810                        }
15811                        String adjType = null;
15812                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15813                            // Not doing bind OOM management, so treat
15814                            // this guy more like a started service.
15815                            if (app.hasShownUi && app != mHomeProcess) {
15816                                // If this process has shown some UI, let it immediately
15817                                // go to the LRU list because it may be pretty heavy with
15818                                // UI stuff.  We'll tag it with a label just to help
15819                                // debug and understand what is going on.
15820                                if (adj > clientAdj) {
15821                                    adjType = "cch-bound-ui-services";
15822                                }
15823                                app.cached = false;
15824                                clientAdj = adj;
15825                                clientProcState = procState;
15826                            } else {
15827                                if (now >= (s.lastActivity
15828                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15829                                    // This service has not seen activity within
15830                                    // recent memory, so allow it to drop to the
15831                                    // LRU list if there is no other reason to keep
15832                                    // it around.  We'll also tag it with a label just
15833                                    // to help debug and undertand what is going on.
15834                                    if (adj > clientAdj) {
15835                                        adjType = "cch-bound-services";
15836                                    }
15837                                    clientAdj = adj;
15838                                }
15839                            }
15840                        }
15841                        if (adj > clientAdj) {
15842                            // If this process has recently shown UI, and
15843                            // the process that is binding to it is less
15844                            // important than being visible, then we don't
15845                            // care about the binding as much as we care
15846                            // about letting this process get into the LRU
15847                            // list to be killed and restarted if needed for
15848                            // memory.
15849                            if (app.hasShownUi && app != mHomeProcess
15850                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15851                                adjType = "cch-bound-ui-services";
15852                            } else {
15853                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15854                                        |Context.BIND_IMPORTANT)) != 0) {
15855                                    adj = clientAdj;
15856                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15857                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15858                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15859                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15860                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15861                                    adj = clientAdj;
15862                                } else {
15863                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15864                                        adj = ProcessList.VISIBLE_APP_ADJ;
15865                                    }
15866                                }
15867                                if (!client.cached) {
15868                                    app.cached = false;
15869                                }
15870                                adjType = "service";
15871                            }
15872                        }
15873                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15874                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15875                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15876                            }
15877                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15878                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15879                                    // Special handling of clients who are in the top state.
15880                                    // We *may* want to consider this process to be in the
15881                                    // top state as well, but only if there is not another
15882                                    // reason for it to be running.  Being on the top is a
15883                                    // special state, meaning you are specifically running
15884                                    // for the current top app.  If the process is already
15885                                    // running in the background for some other reason, it
15886                                    // is more important to continue considering it to be
15887                                    // in the background state.
15888                                    mayBeTop = true;
15889                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15890                                } else {
15891                                    // Special handling for above-top states (persistent
15892                                    // processes).  These should not bring the current process
15893                                    // into the top state, since they are not on top.  Instead
15894                                    // give them the best state after that.
15895                                    clientProcState =
15896                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15897                                }
15898                            }
15899                        } else {
15900                            if (clientProcState <
15901                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15902                                clientProcState =
15903                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15904                            }
15905                        }
15906                        if (procState > clientProcState) {
15907                            procState = clientProcState;
15908                        }
15909                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15910                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15911                            app.pendingUiClean = true;
15912                        }
15913                        if (adjType != null) {
15914                            app.adjType = adjType;
15915                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15916                                    .REASON_SERVICE_IN_USE;
15917                            app.adjSource = cr.binding.client;
15918                            app.adjSourceProcState = clientProcState;
15919                            app.adjTarget = s.name;
15920                        }
15921                    }
15922                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15923                        app.treatLikeActivity = true;
15924                    }
15925                    final ActivityRecord a = cr.activity;
15926                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15927                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15928                                (a.visible || a.state == ActivityState.RESUMED
15929                                 || a.state == ActivityState.PAUSING)) {
15930                            adj = ProcessList.FOREGROUND_APP_ADJ;
15931                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15932                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15933                            }
15934                            app.cached = false;
15935                            app.adjType = "service";
15936                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15937                                    .REASON_SERVICE_IN_USE;
15938                            app.adjSource = a;
15939                            app.adjSourceProcState = procState;
15940                            app.adjTarget = s.name;
15941                        }
15942                    }
15943                }
15944            }
15945        }
15946
15947        for (int provi = app.pubProviders.size()-1;
15948                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15949                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15950                        || procState > ActivityManager.PROCESS_STATE_TOP);
15951                provi--) {
15952            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15953            for (int i = cpr.connections.size()-1;
15954                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15955                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15956                            || procState > ActivityManager.PROCESS_STATE_TOP);
15957                    i--) {
15958                ContentProviderConnection conn = cpr.connections.get(i);
15959                ProcessRecord client = conn.client;
15960                if (client == app) {
15961                    // Being our own client is not interesting.
15962                    continue;
15963                }
15964                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15965                int clientProcState = client.curProcState;
15966                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15967                    // If the other app is cached for any reason, for purposes here
15968                    // we are going to consider it empty.
15969                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15970                }
15971                if (adj > clientAdj) {
15972                    if (app.hasShownUi && app != mHomeProcess
15973                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15974                        app.adjType = "cch-ui-provider";
15975                    } else {
15976                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15977                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15978                        app.adjType = "provider";
15979                    }
15980                    app.cached &= client.cached;
15981                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15982                            .REASON_PROVIDER_IN_USE;
15983                    app.adjSource = client;
15984                    app.adjSourceProcState = clientProcState;
15985                    app.adjTarget = cpr.name;
15986                }
15987                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15988                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15989                        // Special handling of clients who are in the top state.
15990                        // We *may* want to consider this process to be in the
15991                        // top state as well, but only if there is not another
15992                        // reason for it to be running.  Being on the top is a
15993                        // special state, meaning you are specifically running
15994                        // for the current top app.  If the process is already
15995                        // running in the background for some other reason, it
15996                        // is more important to continue considering it to be
15997                        // in the background state.
15998                        mayBeTop = true;
15999                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16000                    } else {
16001                        // Special handling for above-top states (persistent
16002                        // processes).  These should not bring the current process
16003                        // into the top state, since they are not on top.  Instead
16004                        // give them the best state after that.
16005                        clientProcState =
16006                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16007                    }
16008                }
16009                if (procState > clientProcState) {
16010                    procState = clientProcState;
16011                }
16012                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16013                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16014                }
16015            }
16016            // If the provider has external (non-framework) process
16017            // dependencies, ensure that its adjustment is at least
16018            // FOREGROUND_APP_ADJ.
16019            if (cpr.hasExternalProcessHandles()) {
16020                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16021                    adj = ProcessList.FOREGROUND_APP_ADJ;
16022                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16023                    app.cached = false;
16024                    app.adjType = "provider";
16025                    app.adjTarget = cpr.name;
16026                }
16027                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16028                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16029                }
16030            }
16031        }
16032
16033        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16034            // A client of one of our services or providers is in the top state.  We
16035            // *may* want to be in the top state, but not if we are already running in
16036            // the background for some other reason.  For the decision here, we are going
16037            // to pick out a few specific states that we want to remain in when a client
16038            // is top (states that tend to be longer-term) and otherwise allow it to go
16039            // to the top state.
16040            switch (procState) {
16041                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16042                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16043                case ActivityManager.PROCESS_STATE_SERVICE:
16044                    // These all are longer-term states, so pull them up to the top
16045                    // of the background states, but not all the way to the top state.
16046                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16047                    break;
16048                default:
16049                    // Otherwise, top is a better choice, so take it.
16050                    procState = ActivityManager.PROCESS_STATE_TOP;
16051                    break;
16052            }
16053        }
16054
16055        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16056            if (app.hasClientActivities) {
16057                // This is a cached process, but with client activities.  Mark it so.
16058                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16059                app.adjType = "cch-client-act";
16060            } else if (app.treatLikeActivity) {
16061                // This is a cached process, but somebody wants us to treat it like it has
16062                // an activity, okay!
16063                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16064                app.adjType = "cch-as-act";
16065            }
16066        }
16067
16068        if (adj == ProcessList.SERVICE_ADJ) {
16069            if (doingAll) {
16070                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16071                mNewNumServiceProcs++;
16072                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16073                if (!app.serviceb) {
16074                    // This service isn't far enough down on the LRU list to
16075                    // normally be a B service, but if we are low on RAM and it
16076                    // is large we want to force it down since we would prefer to
16077                    // keep launcher over it.
16078                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16079                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16080                        app.serviceHighRam = true;
16081                        app.serviceb = true;
16082                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16083                    } else {
16084                        mNewNumAServiceProcs++;
16085                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16086                    }
16087                } else {
16088                    app.serviceHighRam = false;
16089                }
16090            }
16091            if (app.serviceb) {
16092                adj = ProcessList.SERVICE_B_ADJ;
16093            }
16094        }
16095
16096        app.curRawAdj = adj;
16097
16098        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16099        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16100        if (adj > app.maxAdj) {
16101            adj = app.maxAdj;
16102            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16103                schedGroup = Process.THREAD_GROUP_DEFAULT;
16104            }
16105        }
16106
16107        // Do final modification to adj.  Everything we do between here and applying
16108        // the final setAdj must be done in this function, because we will also use
16109        // it when computing the final cached adj later.  Note that we don't need to
16110        // worry about this for max adj above, since max adj will always be used to
16111        // keep it out of the cached vaues.
16112        app.curAdj = app.modifyRawOomAdj(adj);
16113        app.curSchedGroup = schedGroup;
16114        app.curProcState = procState;
16115        app.foregroundActivities = foregroundActivities;
16116
16117        return app.curRawAdj;
16118    }
16119
16120    /**
16121     * Schedule PSS collection of a process.
16122     */
16123    void requestPssLocked(ProcessRecord proc, int procState) {
16124        if (mPendingPssProcesses.contains(proc)) {
16125            return;
16126        }
16127        if (mPendingPssProcesses.size() == 0) {
16128            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16129        }
16130        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16131        proc.pssProcState = procState;
16132        mPendingPssProcesses.add(proc);
16133    }
16134
16135    /**
16136     * Schedule PSS collection of all processes.
16137     */
16138    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16139        if (!always) {
16140            if (now < (mLastFullPssTime +
16141                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16142                return;
16143            }
16144        }
16145        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16146        mLastFullPssTime = now;
16147        mFullPssPending = true;
16148        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16149        mPendingPssProcesses.clear();
16150        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16151            ProcessRecord app = mLruProcesses.get(i);
16152            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16153                app.pssProcState = app.setProcState;
16154                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16155                        isSleeping(), now);
16156                mPendingPssProcesses.add(app);
16157            }
16158        }
16159        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16160    }
16161
16162    /**
16163     * Ask a given process to GC right now.
16164     */
16165    final void performAppGcLocked(ProcessRecord app) {
16166        try {
16167            app.lastRequestedGc = SystemClock.uptimeMillis();
16168            if (app.thread != null) {
16169                if (app.reportLowMemory) {
16170                    app.reportLowMemory = false;
16171                    app.thread.scheduleLowMemory();
16172                } else {
16173                    app.thread.processInBackground();
16174                }
16175            }
16176        } catch (Exception e) {
16177            // whatever.
16178        }
16179    }
16180
16181    /**
16182     * Returns true if things are idle enough to perform GCs.
16183     */
16184    private final boolean canGcNowLocked() {
16185        boolean processingBroadcasts = false;
16186        for (BroadcastQueue q : mBroadcastQueues) {
16187            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16188                processingBroadcasts = true;
16189            }
16190        }
16191        return !processingBroadcasts
16192                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16193    }
16194
16195    /**
16196     * Perform GCs on all processes that are waiting for it, but only
16197     * if things are idle.
16198     */
16199    final void performAppGcsLocked() {
16200        final int N = mProcessesToGc.size();
16201        if (N <= 0) {
16202            return;
16203        }
16204        if (canGcNowLocked()) {
16205            while (mProcessesToGc.size() > 0) {
16206                ProcessRecord proc = mProcessesToGc.remove(0);
16207                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
16208                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
16209                            <= SystemClock.uptimeMillis()) {
16210                        // To avoid spamming the system, we will GC processes one
16211                        // at a time, waiting a few seconds between each.
16212                        performAppGcLocked(proc);
16213                        scheduleAppGcsLocked();
16214                        return;
16215                    } else {
16216                        // It hasn't been long enough since we last GCed this
16217                        // process...  put it in the list to wait for its time.
16218                        addProcessToGcListLocked(proc);
16219                        break;
16220                    }
16221                }
16222            }
16223
16224            scheduleAppGcsLocked();
16225        }
16226    }
16227
16228    /**
16229     * If all looks good, perform GCs on all processes waiting for them.
16230     */
16231    final void performAppGcsIfAppropriateLocked() {
16232        if (canGcNowLocked()) {
16233            performAppGcsLocked();
16234            return;
16235        }
16236        // Still not idle, wait some more.
16237        scheduleAppGcsLocked();
16238    }
16239
16240    /**
16241     * Schedule the execution of all pending app GCs.
16242     */
16243    final void scheduleAppGcsLocked() {
16244        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16245
16246        if (mProcessesToGc.size() > 0) {
16247            // Schedule a GC for the time to the next process.
16248            ProcessRecord proc = mProcessesToGc.get(0);
16249            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16250
16251            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16252            long now = SystemClock.uptimeMillis();
16253            if (when < (now+GC_TIMEOUT)) {
16254                when = now + GC_TIMEOUT;
16255            }
16256            mHandler.sendMessageAtTime(msg, when);
16257        }
16258    }
16259
16260    /**
16261     * Add a process to the array of processes waiting to be GCed.  Keeps the
16262     * list in sorted order by the last GC time.  The process can't already be
16263     * on the list.
16264     */
16265    final void addProcessToGcListLocked(ProcessRecord proc) {
16266        boolean added = false;
16267        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16268            if (mProcessesToGc.get(i).lastRequestedGc <
16269                    proc.lastRequestedGc) {
16270                added = true;
16271                mProcessesToGc.add(i+1, proc);
16272                break;
16273            }
16274        }
16275        if (!added) {
16276            mProcessesToGc.add(0, proc);
16277        }
16278    }
16279
16280    /**
16281     * Set up to ask a process to GC itself.  This will either do it
16282     * immediately, or put it on the list of processes to gc the next
16283     * time things are idle.
16284     */
16285    final void scheduleAppGcLocked(ProcessRecord app) {
16286        long now = SystemClock.uptimeMillis();
16287        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16288            return;
16289        }
16290        if (!mProcessesToGc.contains(app)) {
16291            addProcessToGcListLocked(app);
16292            scheduleAppGcsLocked();
16293        }
16294    }
16295
16296    final void checkExcessivePowerUsageLocked(boolean doKills) {
16297        updateCpuStatsNow();
16298
16299        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16300        boolean doWakeKills = doKills;
16301        boolean doCpuKills = doKills;
16302        if (mLastPowerCheckRealtime == 0) {
16303            doWakeKills = false;
16304        }
16305        if (mLastPowerCheckUptime == 0) {
16306            doCpuKills = false;
16307        }
16308        if (stats.isScreenOn()) {
16309            doWakeKills = false;
16310        }
16311        final long curRealtime = SystemClock.elapsedRealtime();
16312        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16313        final long curUptime = SystemClock.uptimeMillis();
16314        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16315        mLastPowerCheckRealtime = curRealtime;
16316        mLastPowerCheckUptime = curUptime;
16317        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16318            doWakeKills = false;
16319        }
16320        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16321            doCpuKills = false;
16322        }
16323        int i = mLruProcesses.size();
16324        while (i > 0) {
16325            i--;
16326            ProcessRecord app = mLruProcesses.get(i);
16327            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16328                long wtime;
16329                synchronized (stats) {
16330                    wtime = stats.getProcessWakeTime(app.info.uid,
16331                            app.pid, curRealtime);
16332                }
16333                long wtimeUsed = wtime - app.lastWakeTime;
16334                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16335                if (DEBUG_POWER) {
16336                    StringBuilder sb = new StringBuilder(128);
16337                    sb.append("Wake for ");
16338                    app.toShortString(sb);
16339                    sb.append(": over ");
16340                    TimeUtils.formatDuration(realtimeSince, sb);
16341                    sb.append(" used ");
16342                    TimeUtils.formatDuration(wtimeUsed, sb);
16343                    sb.append(" (");
16344                    sb.append((wtimeUsed*100)/realtimeSince);
16345                    sb.append("%)");
16346                    Slog.i(TAG, sb.toString());
16347                    sb.setLength(0);
16348                    sb.append("CPU for ");
16349                    app.toShortString(sb);
16350                    sb.append(": over ");
16351                    TimeUtils.formatDuration(uptimeSince, sb);
16352                    sb.append(" used ");
16353                    TimeUtils.formatDuration(cputimeUsed, sb);
16354                    sb.append(" (");
16355                    sb.append((cputimeUsed*100)/uptimeSince);
16356                    sb.append("%)");
16357                    Slog.i(TAG, sb.toString());
16358                }
16359                // If a process has held a wake lock for more
16360                // than 50% of the time during this period,
16361                // that sounds bad.  Kill!
16362                if (doWakeKills && realtimeSince > 0
16363                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16364                    synchronized (stats) {
16365                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16366                                realtimeSince, wtimeUsed);
16367                    }
16368                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
16369                            + " during " + realtimeSince);
16370                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16371                } else if (doCpuKills && uptimeSince > 0
16372                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16373                    synchronized (stats) {
16374                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16375                                uptimeSince, cputimeUsed);
16376                    }
16377                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
16378                            + " during " + uptimeSince);
16379                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16380                } else {
16381                    app.lastWakeTime = wtime;
16382                    app.lastCpuTime = app.curCpuTime;
16383                }
16384            }
16385        }
16386    }
16387
16388    private final boolean applyOomAdjLocked(ProcessRecord app,
16389            ProcessRecord TOP_APP, boolean doingAll, long now) {
16390        boolean success = true;
16391
16392        if (app.curRawAdj != app.setRawAdj) {
16393            app.setRawAdj = app.curRawAdj;
16394        }
16395
16396        int changes = 0;
16397
16398        if (app.curAdj != app.setAdj) {
16399            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16400            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16401                TAG, "Set " + app.pid + " " + app.processName +
16402                " adj " + app.curAdj + ": " + app.adjType);
16403            app.setAdj = app.curAdj;
16404        }
16405
16406        if (app.setSchedGroup != app.curSchedGroup) {
16407            app.setSchedGroup = app.curSchedGroup;
16408            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16409                    "Setting process group of " + app.processName
16410                    + " to " + app.curSchedGroup);
16411            if (app.waitingToKill != null &&
16412                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16413                killUnneededProcessLocked(app, app.waitingToKill);
16414                success = false;
16415            } else {
16416                if (true) {
16417                    long oldId = Binder.clearCallingIdentity();
16418                    try {
16419                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16420                    } catch (Exception e) {
16421                        Slog.w(TAG, "Failed setting process group of " + app.pid
16422                                + " to " + app.curSchedGroup);
16423                        e.printStackTrace();
16424                    } finally {
16425                        Binder.restoreCallingIdentity(oldId);
16426                    }
16427                } else {
16428                    if (app.thread != null) {
16429                        try {
16430                            app.thread.setSchedulingGroup(app.curSchedGroup);
16431                        } catch (RemoteException e) {
16432                        }
16433                    }
16434                }
16435                Process.setSwappiness(app.pid,
16436                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16437            }
16438        }
16439        if (app.repForegroundActivities != app.foregroundActivities) {
16440            app.repForegroundActivities = app.foregroundActivities;
16441            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16442        }
16443        if (app.repProcState != app.curProcState) {
16444            app.repProcState = app.curProcState;
16445            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16446            if (app.thread != null) {
16447                try {
16448                    if (false) {
16449                        //RuntimeException h = new RuntimeException("here");
16450                        Slog.i(TAG, "Sending new process state " + app.repProcState
16451                                + " to " + app /*, h*/);
16452                    }
16453                    app.thread.setProcessState(app.repProcState);
16454                } catch (RemoteException e) {
16455                }
16456            }
16457        }
16458        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16459                app.setProcState)) {
16460            app.lastStateTime = now;
16461            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16462                    isSleeping(), now);
16463            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16464                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16465                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16466                    + (app.nextPssTime-now) + ": " + app);
16467        } else {
16468            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16469                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16470                requestPssLocked(app, app.setProcState);
16471                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16472                        isSleeping(), now);
16473            } else if (false && DEBUG_PSS) {
16474                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16475            }
16476        }
16477        if (app.setProcState != app.curProcState) {
16478            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16479                    "Proc state change of " + app.processName
16480                    + " to " + app.curProcState);
16481            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
16482            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
16483            if (setImportant && !curImportant) {
16484                // This app is no longer something we consider important enough to allow to
16485                // use arbitrary amounts of battery power.  Note
16486                // its current wake lock time to later know to kill it if
16487                // it is not behaving well.
16488                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16489                synchronized (stats) {
16490                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
16491                            app.pid, SystemClock.elapsedRealtime());
16492                }
16493                app.lastCpuTime = app.curCpuTime;
16494
16495            }
16496            app.setProcState = app.curProcState;
16497            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16498                app.notCachedSinceIdle = false;
16499            }
16500            if (!doingAll) {
16501                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
16502            } else {
16503                app.procStateChanged = true;
16504            }
16505        }
16506
16507        if (changes != 0) {
16508            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16509            int i = mPendingProcessChanges.size()-1;
16510            ProcessChangeItem item = null;
16511            while (i >= 0) {
16512                item = mPendingProcessChanges.get(i);
16513                if (item.pid == app.pid) {
16514                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16515                    break;
16516                }
16517                i--;
16518            }
16519            if (i < 0) {
16520                // No existing item in pending changes; need a new one.
16521                final int NA = mAvailProcessChanges.size();
16522                if (NA > 0) {
16523                    item = mAvailProcessChanges.remove(NA-1);
16524                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16525                } else {
16526                    item = new ProcessChangeItem();
16527                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16528                }
16529                item.changes = 0;
16530                item.pid = app.pid;
16531                item.uid = app.info.uid;
16532                if (mPendingProcessChanges.size() == 0) {
16533                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16534                            "*** Enqueueing dispatch processes changed!");
16535                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16536                }
16537                mPendingProcessChanges.add(item);
16538            }
16539            item.changes |= changes;
16540            item.processState = app.repProcState;
16541            item.foregroundActivities = app.repForegroundActivities;
16542            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16543                    + Integer.toHexString(System.identityHashCode(item))
16544                    + " " + app.toShortString() + ": changes=" + item.changes
16545                    + " procState=" + item.processState
16546                    + " foreground=" + item.foregroundActivities
16547                    + " type=" + app.adjType + " source=" + app.adjSource
16548                    + " target=" + app.adjTarget);
16549        }
16550
16551        return success;
16552    }
16553
16554    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
16555        if (proc.thread != null) {
16556            if (proc.baseProcessTracker != null) {
16557                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16558            }
16559            if (proc.repProcState >= 0) {
16560                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
16561                        proc.repProcState);
16562            }
16563        }
16564    }
16565
16566    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16567            ProcessRecord TOP_APP, boolean doingAll, long now) {
16568        if (app.thread == null) {
16569            return false;
16570        }
16571
16572        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16573
16574        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
16575    }
16576
16577    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16578            boolean oomAdj) {
16579        if (isForeground != proc.foregroundServices) {
16580            proc.foregroundServices = isForeground;
16581            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16582                    proc.info.uid);
16583            if (isForeground) {
16584                if (curProcs == null) {
16585                    curProcs = new ArrayList<ProcessRecord>();
16586                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16587                }
16588                if (!curProcs.contains(proc)) {
16589                    curProcs.add(proc);
16590                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16591                            proc.info.packageName, proc.info.uid);
16592                }
16593            } else {
16594                if (curProcs != null) {
16595                    if (curProcs.remove(proc)) {
16596                        mBatteryStatsService.noteEvent(
16597                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16598                                proc.info.packageName, proc.info.uid);
16599                        if (curProcs.size() <= 0) {
16600                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16601                        }
16602                    }
16603                }
16604            }
16605            if (oomAdj) {
16606                updateOomAdjLocked();
16607            }
16608        }
16609    }
16610
16611    private final ActivityRecord resumedAppLocked() {
16612        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16613        String pkg;
16614        int uid;
16615        if (act != null) {
16616            pkg = act.packageName;
16617            uid = act.info.applicationInfo.uid;
16618        } else {
16619            pkg = null;
16620            uid = -1;
16621        }
16622        // Has the UID or resumed package name changed?
16623        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16624                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16625            if (mCurResumedPackage != null) {
16626                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16627                        mCurResumedPackage, mCurResumedUid);
16628            }
16629            mCurResumedPackage = pkg;
16630            mCurResumedUid = uid;
16631            if (mCurResumedPackage != null) {
16632                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16633                        mCurResumedPackage, mCurResumedUid);
16634            }
16635        }
16636        return act;
16637    }
16638
16639    final boolean updateOomAdjLocked(ProcessRecord app) {
16640        final ActivityRecord TOP_ACT = resumedAppLocked();
16641        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16642        final boolean wasCached = app.cached;
16643
16644        mAdjSeq++;
16645
16646        // This is the desired cached adjusment we want to tell it to use.
16647        // If our app is currently cached, we know it, and that is it.  Otherwise,
16648        // we don't know it yet, and it needs to now be cached we will then
16649        // need to do a complete oom adj.
16650        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16651                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16652        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16653                SystemClock.uptimeMillis());
16654        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16655            // Changed to/from cached state, so apps after it in the LRU
16656            // list may also be changed.
16657            updateOomAdjLocked();
16658        }
16659        return success;
16660    }
16661
16662    final void updateOomAdjLocked() {
16663        final ActivityRecord TOP_ACT = resumedAppLocked();
16664        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16665        final long now = SystemClock.uptimeMillis();
16666        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16667        final int N = mLruProcesses.size();
16668
16669        if (false) {
16670            RuntimeException e = new RuntimeException();
16671            e.fillInStackTrace();
16672            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16673        }
16674
16675        mAdjSeq++;
16676        mNewNumServiceProcs = 0;
16677        mNewNumAServiceProcs = 0;
16678
16679        final int emptyProcessLimit;
16680        final int cachedProcessLimit;
16681        if (mProcessLimit <= 0) {
16682            emptyProcessLimit = cachedProcessLimit = 0;
16683        } else if (mProcessLimit == 1) {
16684            emptyProcessLimit = 1;
16685            cachedProcessLimit = 0;
16686        } else {
16687            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16688            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16689        }
16690
16691        // Let's determine how many processes we have running vs.
16692        // how many slots we have for background processes; we may want
16693        // to put multiple processes in a slot of there are enough of
16694        // them.
16695        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16696                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16697        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16698        if (numEmptyProcs > cachedProcessLimit) {
16699            // If there are more empty processes than our limit on cached
16700            // processes, then use the cached process limit for the factor.
16701            // This ensures that the really old empty processes get pushed
16702            // down to the bottom, so if we are running low on memory we will
16703            // have a better chance at keeping around more cached processes
16704            // instead of a gazillion empty processes.
16705            numEmptyProcs = cachedProcessLimit;
16706        }
16707        int emptyFactor = numEmptyProcs/numSlots;
16708        if (emptyFactor < 1) emptyFactor = 1;
16709        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16710        if (cachedFactor < 1) cachedFactor = 1;
16711        int stepCached = 0;
16712        int stepEmpty = 0;
16713        int numCached = 0;
16714        int numEmpty = 0;
16715        int numTrimming = 0;
16716
16717        mNumNonCachedProcs = 0;
16718        mNumCachedHiddenProcs = 0;
16719
16720        // First update the OOM adjustment for each of the
16721        // application processes based on their current state.
16722        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16723        int nextCachedAdj = curCachedAdj+1;
16724        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16725        int nextEmptyAdj = curEmptyAdj+2;
16726        for (int i=N-1; i>=0; i--) {
16727            ProcessRecord app = mLruProcesses.get(i);
16728            if (!app.killedByAm && app.thread != null) {
16729                app.procStateChanged = false;
16730                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16731
16732                // If we haven't yet assigned the final cached adj
16733                // to the process, do that now.
16734                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16735                    switch (app.curProcState) {
16736                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16737                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16738                            // This process is a cached process holding activities...
16739                            // assign it the next cached value for that type, and then
16740                            // step that cached level.
16741                            app.curRawAdj = curCachedAdj;
16742                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16743                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16744                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16745                                    + ")");
16746                            if (curCachedAdj != nextCachedAdj) {
16747                                stepCached++;
16748                                if (stepCached >= cachedFactor) {
16749                                    stepCached = 0;
16750                                    curCachedAdj = nextCachedAdj;
16751                                    nextCachedAdj += 2;
16752                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16753                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16754                                    }
16755                                }
16756                            }
16757                            break;
16758                        default:
16759                            // For everything else, assign next empty cached process
16760                            // level and bump that up.  Note that this means that
16761                            // long-running services that have dropped down to the
16762                            // cached level will be treated as empty (since their process
16763                            // state is still as a service), which is what we want.
16764                            app.curRawAdj = curEmptyAdj;
16765                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16766                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16767                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16768                                    + ")");
16769                            if (curEmptyAdj != nextEmptyAdj) {
16770                                stepEmpty++;
16771                                if (stepEmpty >= emptyFactor) {
16772                                    stepEmpty = 0;
16773                                    curEmptyAdj = nextEmptyAdj;
16774                                    nextEmptyAdj += 2;
16775                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16776                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16777                                    }
16778                                }
16779                            }
16780                            break;
16781                    }
16782                }
16783
16784                applyOomAdjLocked(app, TOP_APP, true, now);
16785
16786                // Count the number of process types.
16787                switch (app.curProcState) {
16788                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16789                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16790                        mNumCachedHiddenProcs++;
16791                        numCached++;
16792                        if (numCached > cachedProcessLimit) {
16793                            killUnneededProcessLocked(app, "cached #" + numCached);
16794                        }
16795                        break;
16796                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16797                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16798                                && app.lastActivityTime < oldTime) {
16799                            killUnneededProcessLocked(app, "empty for "
16800                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16801                                    / 1000) + "s");
16802                        } else {
16803                            numEmpty++;
16804                            if (numEmpty > emptyProcessLimit) {
16805                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16806                            }
16807                        }
16808                        break;
16809                    default:
16810                        mNumNonCachedProcs++;
16811                        break;
16812                }
16813
16814                if (app.isolated && app.services.size() <= 0) {
16815                    // If this is an isolated process, and there are no
16816                    // services running in it, then the process is no longer
16817                    // needed.  We agressively kill these because we can by
16818                    // definition not re-use the same process again, and it is
16819                    // good to avoid having whatever code was running in them
16820                    // left sitting around after no longer needed.
16821                    killUnneededProcessLocked(app, "isolated not needed");
16822                }
16823
16824                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16825                        && !app.killedByAm) {
16826                    numTrimming++;
16827                }
16828            }
16829        }
16830
16831        mNumServiceProcs = mNewNumServiceProcs;
16832
16833        // Now determine the memory trimming level of background processes.
16834        // Unfortunately we need to start at the back of the list to do this
16835        // properly.  We only do this if the number of background apps we
16836        // are managing to keep around is less than half the maximum we desire;
16837        // if we are keeping a good number around, we'll let them use whatever
16838        // memory they want.
16839        final int numCachedAndEmpty = numCached + numEmpty;
16840        int memFactor;
16841        if (numCached <= ProcessList.TRIM_CACHED_APPS
16842                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16843            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16844                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16845            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16846                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16847            } else {
16848                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16849            }
16850        } else {
16851            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16852        }
16853        // We always allow the memory level to go up (better).  We only allow it to go
16854        // down if we are in a state where that is allowed, *and* the total number of processes
16855        // has gone down since last time.
16856        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16857                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16858                + " last=" + mLastNumProcesses);
16859        if (memFactor > mLastMemoryLevel) {
16860            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16861                memFactor = mLastMemoryLevel;
16862                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16863            }
16864        }
16865        mLastMemoryLevel = memFactor;
16866        mLastNumProcesses = mLruProcesses.size();
16867        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16868        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16869        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16870            if (mLowRamStartTime == 0) {
16871                mLowRamStartTime = now;
16872            }
16873            int step = 0;
16874            int fgTrimLevel;
16875            switch (memFactor) {
16876                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16877                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16878                    break;
16879                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16880                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16881                    break;
16882                default:
16883                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16884                    break;
16885            }
16886            int factor = numTrimming/3;
16887            int minFactor = 2;
16888            if (mHomeProcess != null) minFactor++;
16889            if (mPreviousProcess != null) minFactor++;
16890            if (factor < minFactor) factor = minFactor;
16891            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16892            for (int i=N-1; i>=0; i--) {
16893                ProcessRecord app = mLruProcesses.get(i);
16894                if (allChanged || app.procStateChanged) {
16895                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16896                    app.procStateChanged = false;
16897                }
16898                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16899                        && !app.killedByAm) {
16900                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16901                        try {
16902                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16903                                    "Trimming memory of " + app.processName
16904                                    + " to " + curLevel);
16905                            app.thread.scheduleTrimMemory(curLevel);
16906                        } catch (RemoteException e) {
16907                        }
16908                        if (false) {
16909                            // For now we won't do this; our memory trimming seems
16910                            // to be good enough at this point that destroying
16911                            // activities causes more harm than good.
16912                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16913                                    && app != mHomeProcess && app != mPreviousProcess) {
16914                                // Need to do this on its own message because the stack may not
16915                                // be in a consistent state at this point.
16916                                // For these apps we will also finish their activities
16917                                // to help them free memory.
16918                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16919                            }
16920                        }
16921                    }
16922                    app.trimMemoryLevel = curLevel;
16923                    step++;
16924                    if (step >= factor) {
16925                        step = 0;
16926                        switch (curLevel) {
16927                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16928                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16929                                break;
16930                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16931                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16932                                break;
16933                        }
16934                    }
16935                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16936                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16937                            && app.thread != null) {
16938                        try {
16939                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16940                                    "Trimming memory of heavy-weight " + app.processName
16941                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16942                            app.thread.scheduleTrimMemory(
16943                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16944                        } catch (RemoteException e) {
16945                        }
16946                    }
16947                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16948                } else {
16949                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16950                            || app.systemNoUi) && app.pendingUiClean) {
16951                        // If this application is now in the background and it
16952                        // had done UI, then give it the special trim level to
16953                        // have it free UI resources.
16954                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16955                        if (app.trimMemoryLevel < level && app.thread != null) {
16956                            try {
16957                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16958                                        "Trimming memory of bg-ui " + app.processName
16959                                        + " to " + level);
16960                                app.thread.scheduleTrimMemory(level);
16961                            } catch (RemoteException e) {
16962                            }
16963                        }
16964                        app.pendingUiClean = false;
16965                    }
16966                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16967                        try {
16968                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16969                                    "Trimming memory of fg " + app.processName
16970                                    + " to " + fgTrimLevel);
16971                            app.thread.scheduleTrimMemory(fgTrimLevel);
16972                        } catch (RemoteException e) {
16973                        }
16974                    }
16975                    app.trimMemoryLevel = fgTrimLevel;
16976                }
16977            }
16978        } else {
16979            if (mLowRamStartTime != 0) {
16980                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16981                mLowRamStartTime = 0;
16982            }
16983            for (int i=N-1; i>=0; i--) {
16984                ProcessRecord app = mLruProcesses.get(i);
16985                if (allChanged || app.procStateChanged) {
16986                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16987                    app.procStateChanged = false;
16988                }
16989                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16990                        || app.systemNoUi) && app.pendingUiClean) {
16991                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16992                            && app.thread != null) {
16993                        try {
16994                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16995                                    "Trimming memory of ui hidden " + app.processName
16996                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16997                            app.thread.scheduleTrimMemory(
16998                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16999                        } catch (RemoteException e) {
17000                        }
17001                    }
17002                    app.pendingUiClean = false;
17003                }
17004                app.trimMemoryLevel = 0;
17005            }
17006        }
17007
17008        if (mAlwaysFinishActivities) {
17009            // Need to do this on its own message because the stack may not
17010            // be in a consistent state at this point.
17011            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17012        }
17013
17014        if (allChanged) {
17015            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17016        }
17017
17018        if (mProcessStats.shouldWriteNowLocked(now)) {
17019            mHandler.post(new Runnable() {
17020                @Override public void run() {
17021                    synchronized (ActivityManagerService.this) {
17022                        mProcessStats.writeStateAsyncLocked();
17023                    }
17024                }
17025            });
17026        }
17027
17028        if (DEBUG_OOM_ADJ) {
17029            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17030        }
17031    }
17032
17033    final void trimApplications() {
17034        synchronized (this) {
17035            int i;
17036
17037            // First remove any unused application processes whose package
17038            // has been removed.
17039            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17040                final ProcessRecord app = mRemovedProcesses.get(i);
17041                if (app.activities.size() == 0
17042                        && app.curReceiver == null && app.services.size() == 0) {
17043                    Slog.i(
17044                        TAG, "Exiting empty application process "
17045                        + app.processName + " ("
17046                        + (app.thread != null ? app.thread.asBinder() : null)
17047                        + ")\n");
17048                    if (app.pid > 0 && app.pid != MY_PID) {
17049                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
17050                                app.processName, app.setAdj, "empty");
17051                        app.killedByAm = true;
17052                        Process.killProcessQuiet(app.pid);
17053                        Process.killProcessGroup(app.info.uid, app.pid);
17054                    } else {
17055                        try {
17056                            app.thread.scheduleExit();
17057                        } catch (Exception e) {
17058                            // Ignore exceptions.
17059                        }
17060                    }
17061                    cleanUpApplicationRecordLocked(app, false, true, -1);
17062                    mRemovedProcesses.remove(i);
17063
17064                    if (app.persistent) {
17065                        addAppLocked(app.info, false, null /* ABI override */);
17066                    }
17067                }
17068            }
17069
17070            // Now update the oom adj for all processes.
17071            updateOomAdjLocked();
17072        }
17073    }
17074
17075    /** This method sends the specified signal to each of the persistent apps */
17076    public void signalPersistentProcesses(int sig) throws RemoteException {
17077        if (sig != Process.SIGNAL_USR1) {
17078            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17079        }
17080
17081        synchronized (this) {
17082            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17083                    != PackageManager.PERMISSION_GRANTED) {
17084                throw new SecurityException("Requires permission "
17085                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17086            }
17087
17088            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17089                ProcessRecord r = mLruProcesses.get(i);
17090                if (r.thread != null && r.persistent) {
17091                    Process.sendSignal(r.pid, sig);
17092                }
17093            }
17094        }
17095    }
17096
17097    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
17098        if (proc == null || proc == mProfileProc) {
17099            proc = mProfileProc;
17100            path = mProfileFile;
17101            profileType = mProfileType;
17102            clearProfilerLocked();
17103        }
17104        if (proc == null) {
17105            return;
17106        }
17107        try {
17108            proc.thread.profilerControl(false, path, null, profileType);
17109        } catch (RemoteException e) {
17110            throw new IllegalStateException("Process disappeared");
17111        }
17112    }
17113
17114    private void clearProfilerLocked() {
17115        if (mProfileFd != null) {
17116            try {
17117                mProfileFd.close();
17118            } catch (IOException e) {
17119            }
17120        }
17121        mProfileApp = null;
17122        mProfileProc = null;
17123        mProfileFile = null;
17124        mProfileType = 0;
17125        mAutoStopProfiler = false;
17126    }
17127
17128    public boolean profileControl(String process, int userId, boolean start,
17129            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
17130
17131        try {
17132            synchronized (this) {
17133                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17134                // its own permission.
17135                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17136                        != PackageManager.PERMISSION_GRANTED) {
17137                    throw new SecurityException("Requires permission "
17138                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17139                }
17140
17141                if (start && fd == null) {
17142                    throw new IllegalArgumentException("null fd");
17143                }
17144
17145                ProcessRecord proc = null;
17146                if (process != null) {
17147                    proc = findProcessLocked(process, userId, "profileControl");
17148                }
17149
17150                if (start && (proc == null || proc.thread == null)) {
17151                    throw new IllegalArgumentException("Unknown process: " + process);
17152                }
17153
17154                if (start) {
17155                    stopProfilerLocked(null, null, 0);
17156                    setProfileApp(proc.info, proc.processName, path, fd, false);
17157                    mProfileProc = proc;
17158                    mProfileType = profileType;
17159                    try {
17160                        fd = fd.dup();
17161                    } catch (IOException e) {
17162                        fd = null;
17163                    }
17164                    proc.thread.profilerControl(start, path, fd, profileType);
17165                    fd = null;
17166                    mProfileFd = null;
17167                } else {
17168                    stopProfilerLocked(proc, path, profileType);
17169                    if (fd != null) {
17170                        try {
17171                            fd.close();
17172                        } catch (IOException e) {
17173                        }
17174                    }
17175                }
17176
17177                return true;
17178            }
17179        } catch (RemoteException e) {
17180            throw new IllegalStateException("Process disappeared");
17181        } finally {
17182            if (fd != null) {
17183                try {
17184                    fd.close();
17185                } catch (IOException e) {
17186                }
17187            }
17188        }
17189    }
17190
17191    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17192        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17193                userId, true, ALLOW_FULL_ONLY, callName, null);
17194        ProcessRecord proc = null;
17195        try {
17196            int pid = Integer.parseInt(process);
17197            synchronized (mPidsSelfLocked) {
17198                proc = mPidsSelfLocked.get(pid);
17199            }
17200        } catch (NumberFormatException e) {
17201        }
17202
17203        if (proc == null) {
17204            ArrayMap<String, SparseArray<ProcessRecord>> all
17205                    = mProcessNames.getMap();
17206            SparseArray<ProcessRecord> procs = all.get(process);
17207            if (procs != null && procs.size() > 0) {
17208                proc = procs.valueAt(0);
17209                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17210                    for (int i=1; i<procs.size(); i++) {
17211                        ProcessRecord thisProc = procs.valueAt(i);
17212                        if (thisProc.userId == userId) {
17213                            proc = thisProc;
17214                            break;
17215                        }
17216                    }
17217                }
17218            }
17219        }
17220
17221        return proc;
17222    }
17223
17224    public boolean dumpHeap(String process, int userId, boolean managed,
17225            String path, ParcelFileDescriptor fd) throws RemoteException {
17226
17227        try {
17228            synchronized (this) {
17229                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17230                // its own permission (same as profileControl).
17231                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17232                        != PackageManager.PERMISSION_GRANTED) {
17233                    throw new SecurityException("Requires permission "
17234                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17235                }
17236
17237                if (fd == null) {
17238                    throw new IllegalArgumentException("null fd");
17239                }
17240
17241                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17242                if (proc == null || proc.thread == null) {
17243                    throw new IllegalArgumentException("Unknown process: " + process);
17244                }
17245
17246                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17247                if (!isDebuggable) {
17248                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17249                        throw new SecurityException("Process not debuggable: " + proc);
17250                    }
17251                }
17252
17253                proc.thread.dumpHeap(managed, path, fd);
17254                fd = null;
17255                return true;
17256            }
17257        } catch (RemoteException e) {
17258            throw new IllegalStateException("Process disappeared");
17259        } finally {
17260            if (fd != null) {
17261                try {
17262                    fd.close();
17263                } catch (IOException e) {
17264                }
17265            }
17266        }
17267    }
17268
17269    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17270    public void monitor() {
17271        synchronized (this) { }
17272    }
17273
17274    void onCoreSettingsChange(Bundle settings) {
17275        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17276            ProcessRecord processRecord = mLruProcesses.get(i);
17277            try {
17278                if (processRecord.thread != null) {
17279                    processRecord.thread.setCoreSettings(settings);
17280                }
17281            } catch (RemoteException re) {
17282                /* ignore */
17283            }
17284        }
17285    }
17286
17287    // Multi-user methods
17288
17289    /**
17290     * Start user, if its not already running, but don't bring it to foreground.
17291     */
17292    @Override
17293    public boolean startUserInBackground(final int userId) {
17294        return startUser(userId, /* foreground */ false);
17295    }
17296
17297    /**
17298     * Refreshes the list of users related to the current user when either a
17299     * user switch happens or when a new related user is started in the
17300     * background.
17301     */
17302    private void updateCurrentProfileIdsLocked() {
17303        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17304                mCurrentUserId, false /* enabledOnly */);
17305        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17306        for (int i = 0; i < currentProfileIds.length; i++) {
17307            currentProfileIds[i] = profiles.get(i).id;
17308        }
17309        mCurrentProfileIds = currentProfileIds;
17310
17311        synchronized (mUserProfileGroupIdsSelfLocked) {
17312            mUserProfileGroupIdsSelfLocked.clear();
17313            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17314            for (int i = 0; i < users.size(); i++) {
17315                UserInfo user = users.get(i);
17316                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17317                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17318                }
17319            }
17320        }
17321    }
17322
17323    private Set getProfileIdsLocked(int userId) {
17324        Set userIds = new HashSet<Integer>();
17325        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17326                userId, false /* enabledOnly */);
17327        for (UserInfo user : profiles) {
17328            userIds.add(Integer.valueOf(user.id));
17329        }
17330        return userIds;
17331    }
17332
17333    @Override
17334    public boolean switchUser(final int userId) {
17335        return startUser(userId, /* foregound */ true);
17336    }
17337
17338    private boolean startUser(final int userId, boolean foreground) {
17339        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17340                != PackageManager.PERMISSION_GRANTED) {
17341            String msg = "Permission Denial: switchUser() from pid="
17342                    + Binder.getCallingPid()
17343                    + ", uid=" + Binder.getCallingUid()
17344                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17345            Slog.w(TAG, msg);
17346            throw new SecurityException(msg);
17347        }
17348
17349        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17350
17351        final long ident = Binder.clearCallingIdentity();
17352        try {
17353            synchronized (this) {
17354                final int oldUserId = mCurrentUserId;
17355                if (oldUserId == userId) {
17356                    return true;
17357                }
17358
17359                mStackSupervisor.setLockTaskModeLocked(null, false);
17360
17361                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17362                if (userInfo == null) {
17363                    Slog.w(TAG, "No user info for user #" + userId);
17364                    return false;
17365                }
17366                if (foreground && userInfo.isManagedProfile()) {
17367                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
17368                    return false;
17369                }
17370
17371                if (foreground) {
17372                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17373                            R.anim.screen_user_enter);
17374                }
17375
17376                boolean needStart = false;
17377
17378                // If the user we are switching to is not currently started, then
17379                // we need to start it now.
17380                if (mStartedUsers.get(userId) == null) {
17381                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17382                    updateStartedUserArrayLocked();
17383                    needStart = true;
17384                }
17385
17386                final Integer userIdInt = Integer.valueOf(userId);
17387                mUserLru.remove(userIdInt);
17388                mUserLru.add(userIdInt);
17389
17390                if (foreground) {
17391                    mCurrentUserId = userId;
17392                    updateCurrentProfileIdsLocked();
17393                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17394                    // Once the internal notion of the active user has switched, we lock the device
17395                    // with the option to show the user switcher on the keyguard.
17396                    mWindowManager.lockNow(null);
17397                } else {
17398                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17399                    updateCurrentProfileIdsLocked();
17400                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17401                    mUserLru.remove(currentUserIdInt);
17402                    mUserLru.add(currentUserIdInt);
17403                }
17404
17405                final UserStartedState uss = mStartedUsers.get(userId);
17406
17407                // Make sure user is in the started state.  If it is currently
17408                // stopping, we need to knock that off.
17409                if (uss.mState == UserStartedState.STATE_STOPPING) {
17410                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17411                    // so we can just fairly silently bring the user back from
17412                    // the almost-dead.
17413                    uss.mState = UserStartedState.STATE_RUNNING;
17414                    updateStartedUserArrayLocked();
17415                    needStart = true;
17416                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17417                    // This means ACTION_SHUTDOWN has been sent, so we will
17418                    // need to treat this as a new boot of the user.
17419                    uss.mState = UserStartedState.STATE_BOOTING;
17420                    updateStartedUserArrayLocked();
17421                    needStart = true;
17422                }
17423
17424                if (uss.mState == UserStartedState.STATE_BOOTING) {
17425                    // Booting up a new user, need to tell system services about it.
17426                    // Note that this is on the same handler as scheduling of broadcasts,
17427                    // which is important because it needs to go first.
17428                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
17429                }
17430
17431                if (foreground) {
17432                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
17433                            oldUserId));
17434                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17435                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17436                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
17437                            oldUserId, userId, uss));
17438                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
17439                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
17440                }
17441
17442                if (needStart) {
17443                    // Send USER_STARTED broadcast
17444                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
17445                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17446                            | Intent.FLAG_RECEIVER_FOREGROUND);
17447                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17448                    broadcastIntentLocked(null, null, intent,
17449                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17450                            false, false, MY_PID, Process.SYSTEM_UID, userId);
17451                }
17452
17453                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
17454                    if (userId != UserHandle.USER_OWNER) {
17455                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
17456                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17457                        broadcastIntentLocked(null, null, intent, null,
17458                                new IIntentReceiver.Stub() {
17459                                    public void performReceive(Intent intent, int resultCode,
17460                                            String data, Bundle extras, boolean ordered,
17461                                            boolean sticky, int sendingUser) {
17462                                        userInitialized(uss, userId);
17463                                    }
17464                                }, 0, null, null, null, AppOpsManager.OP_NONE,
17465                                true, false, MY_PID, Process.SYSTEM_UID,
17466                                userId);
17467                        uss.initializing = true;
17468                    } else {
17469                        getUserManagerLocked().makeInitialized(userInfo.id);
17470                    }
17471                }
17472
17473                if (foreground) {
17474                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
17475                    if (homeInFront) {
17476                        startHomeActivityLocked(userId);
17477                    } else {
17478                        mStackSupervisor.resumeTopActivitiesLocked();
17479                    }
17480                    EventLogTags.writeAmSwitchUser(userId);
17481                    getUserManagerLocked().userForeground(userId);
17482                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
17483                } else {
17484                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
17485                }
17486
17487                if (needStart) {
17488                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
17489                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17490                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17491                    broadcastIntentLocked(null, null, intent,
17492                            null, new IIntentReceiver.Stub() {
17493                                @Override
17494                                public void performReceive(Intent intent, int resultCode, String data,
17495                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
17496                                        throws RemoteException {
17497                                }
17498                            }, 0, null, null,
17499                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17500                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17501                }
17502            }
17503        } finally {
17504            Binder.restoreCallingIdentity(ident);
17505        }
17506
17507        return true;
17508    }
17509
17510    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
17511        long ident = Binder.clearCallingIdentity();
17512        try {
17513            Intent intent;
17514            if (oldUserId >= 0) {
17515                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
17516                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
17517                int count = profiles.size();
17518                for (int i = 0; i < count; i++) {
17519                    int profileUserId = profiles.get(i).id;
17520                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
17521                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17522                            | Intent.FLAG_RECEIVER_FOREGROUND);
17523                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17524                    broadcastIntentLocked(null, null, intent,
17525                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17526                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17527                }
17528            }
17529            if (newUserId >= 0) {
17530                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
17531                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
17532                int count = profiles.size();
17533                for (int i = 0; i < count; i++) {
17534                    int profileUserId = profiles.get(i).id;
17535                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
17536                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17537                            | Intent.FLAG_RECEIVER_FOREGROUND);
17538                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17539                    broadcastIntentLocked(null, null, intent,
17540                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17541                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17542                }
17543                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17544                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17545                        | Intent.FLAG_RECEIVER_FOREGROUND);
17546                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17547                broadcastIntentLocked(null, null, intent,
17548                        null, null, 0, null, null,
17549                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17550                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17551            }
17552        } finally {
17553            Binder.restoreCallingIdentity(ident);
17554        }
17555    }
17556
17557    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17558            final int newUserId) {
17559        final int N = mUserSwitchObservers.beginBroadcast();
17560        if (N > 0) {
17561            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17562                int mCount = 0;
17563                @Override
17564                public void sendResult(Bundle data) throws RemoteException {
17565                    synchronized (ActivityManagerService.this) {
17566                        if (mCurUserSwitchCallback == this) {
17567                            mCount++;
17568                            if (mCount == N) {
17569                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17570                            }
17571                        }
17572                    }
17573                }
17574            };
17575            synchronized (this) {
17576                uss.switching = true;
17577                mCurUserSwitchCallback = callback;
17578            }
17579            for (int i=0; i<N; i++) {
17580                try {
17581                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17582                            newUserId, callback);
17583                } catch (RemoteException e) {
17584                }
17585            }
17586        } else {
17587            synchronized (this) {
17588                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17589            }
17590        }
17591        mUserSwitchObservers.finishBroadcast();
17592    }
17593
17594    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17595        synchronized (this) {
17596            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17597            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17598        }
17599    }
17600
17601    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17602        mCurUserSwitchCallback = null;
17603        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17604        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17605                oldUserId, newUserId, uss));
17606    }
17607
17608    void userInitialized(UserStartedState uss, int newUserId) {
17609        completeSwitchAndInitalize(uss, newUserId, true, false);
17610    }
17611
17612    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17613        completeSwitchAndInitalize(uss, newUserId, false, true);
17614    }
17615
17616    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17617            boolean clearInitializing, boolean clearSwitching) {
17618        boolean unfrozen = false;
17619        synchronized (this) {
17620            if (clearInitializing) {
17621                uss.initializing = false;
17622                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17623            }
17624            if (clearSwitching) {
17625                uss.switching = false;
17626            }
17627            if (!uss.switching && !uss.initializing) {
17628                mWindowManager.stopFreezingScreen();
17629                unfrozen = true;
17630            }
17631        }
17632        if (unfrozen) {
17633            final int N = mUserSwitchObservers.beginBroadcast();
17634            for (int i=0; i<N; i++) {
17635                try {
17636                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17637                } catch (RemoteException e) {
17638                }
17639            }
17640            mUserSwitchObservers.finishBroadcast();
17641        }
17642    }
17643
17644    void scheduleStartProfilesLocked() {
17645        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17646            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17647                    DateUtils.SECOND_IN_MILLIS);
17648        }
17649    }
17650
17651    void startProfilesLocked() {
17652        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17653        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17654                mCurrentUserId, false /* enabledOnly */);
17655        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17656        for (UserInfo user : profiles) {
17657            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17658                    && user.id != mCurrentUserId) {
17659                toStart.add(user);
17660            }
17661        }
17662        final int n = toStart.size();
17663        int i = 0;
17664        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17665            startUserInBackground(toStart.get(i).id);
17666        }
17667        if (i < n) {
17668            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17669        }
17670    }
17671
17672    void finishUserBoot(UserStartedState uss) {
17673        synchronized (this) {
17674            if (uss.mState == UserStartedState.STATE_BOOTING
17675                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17676                uss.mState = UserStartedState.STATE_RUNNING;
17677                final int userId = uss.mHandle.getIdentifier();
17678                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17679                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17680                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17681                broadcastIntentLocked(null, null, intent,
17682                        null, null, 0, null, null,
17683                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17684                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17685            }
17686        }
17687    }
17688
17689    void finishUserSwitch(UserStartedState uss) {
17690        synchronized (this) {
17691            finishUserBoot(uss);
17692
17693            startProfilesLocked();
17694
17695            int num = mUserLru.size();
17696            int i = 0;
17697            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17698                Integer oldUserId = mUserLru.get(i);
17699                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17700                if (oldUss == null) {
17701                    // Shouldn't happen, but be sane if it does.
17702                    mUserLru.remove(i);
17703                    num--;
17704                    continue;
17705                }
17706                if (oldUss.mState == UserStartedState.STATE_STOPPING
17707                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17708                    // This user is already stopping, doesn't count.
17709                    num--;
17710                    i++;
17711                    continue;
17712                }
17713                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17714                    // Owner and current can't be stopped, but count as running.
17715                    i++;
17716                    continue;
17717                }
17718                // This is a user to be stopped.
17719                stopUserLocked(oldUserId, null);
17720                num--;
17721                i++;
17722            }
17723        }
17724    }
17725
17726    @Override
17727    public int stopUser(final int userId, final IStopUserCallback callback) {
17728        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17729                != PackageManager.PERMISSION_GRANTED) {
17730            String msg = "Permission Denial: switchUser() from pid="
17731                    + Binder.getCallingPid()
17732                    + ", uid=" + Binder.getCallingUid()
17733                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17734            Slog.w(TAG, msg);
17735            throw new SecurityException(msg);
17736        }
17737        if (userId <= 0) {
17738            throw new IllegalArgumentException("Can't stop primary user " + userId);
17739        }
17740        synchronized (this) {
17741            return stopUserLocked(userId, callback);
17742        }
17743    }
17744
17745    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17746        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17747        if (mCurrentUserId == userId) {
17748            return ActivityManager.USER_OP_IS_CURRENT;
17749        }
17750
17751        final UserStartedState uss = mStartedUsers.get(userId);
17752        if (uss == null) {
17753            // User is not started, nothing to do...  but we do need to
17754            // callback if requested.
17755            if (callback != null) {
17756                mHandler.post(new Runnable() {
17757                    @Override
17758                    public void run() {
17759                        try {
17760                            callback.userStopped(userId);
17761                        } catch (RemoteException e) {
17762                        }
17763                    }
17764                });
17765            }
17766            return ActivityManager.USER_OP_SUCCESS;
17767        }
17768
17769        if (callback != null) {
17770            uss.mStopCallbacks.add(callback);
17771        }
17772
17773        if (uss.mState != UserStartedState.STATE_STOPPING
17774                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17775            uss.mState = UserStartedState.STATE_STOPPING;
17776            updateStartedUserArrayLocked();
17777
17778            long ident = Binder.clearCallingIdentity();
17779            try {
17780                // We are going to broadcast ACTION_USER_STOPPING and then
17781                // once that is done send a final ACTION_SHUTDOWN and then
17782                // stop the user.
17783                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17784                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17785                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17786                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17787                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17788                // This is the result receiver for the final shutdown broadcast.
17789                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17790                    @Override
17791                    public void performReceive(Intent intent, int resultCode, String data,
17792                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17793                        finishUserStop(uss);
17794                    }
17795                };
17796                // This is the result receiver for the initial stopping broadcast.
17797                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17798                    @Override
17799                    public void performReceive(Intent intent, int resultCode, String data,
17800                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17801                        // On to the next.
17802                        synchronized (ActivityManagerService.this) {
17803                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17804                                // Whoops, we are being started back up.  Abort, abort!
17805                                return;
17806                            }
17807                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17808                        }
17809                        mBatteryStatsService.noteEvent(
17810                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
17811                                Integer.toString(userId), userId);
17812                        mSystemServiceManager.stopUser(userId);
17813                        broadcastIntentLocked(null, null, shutdownIntent,
17814                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17815                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17816                    }
17817                };
17818                // Kick things off.
17819                broadcastIntentLocked(null, null, stoppingIntent,
17820                        null, stoppingReceiver, 0, null, null,
17821                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17822                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17823            } finally {
17824                Binder.restoreCallingIdentity(ident);
17825            }
17826        }
17827
17828        return ActivityManager.USER_OP_SUCCESS;
17829    }
17830
17831    void finishUserStop(UserStartedState uss) {
17832        final int userId = uss.mHandle.getIdentifier();
17833        boolean stopped;
17834        ArrayList<IStopUserCallback> callbacks;
17835        synchronized (this) {
17836            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17837            if (mStartedUsers.get(userId) != uss) {
17838                stopped = false;
17839            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17840                stopped = false;
17841            } else {
17842                stopped = true;
17843                // User can no longer run.
17844                mStartedUsers.remove(userId);
17845                mUserLru.remove(Integer.valueOf(userId));
17846                updateStartedUserArrayLocked();
17847
17848                // Clean up all state and processes associated with the user.
17849                // Kill all the processes for the user.
17850                forceStopUserLocked(userId, "finish user");
17851            }
17852
17853            // Explicitly remove the old information in mRecentTasks.
17854            removeRecentTasksForUserLocked(userId);
17855        }
17856
17857        for (int i=0; i<callbacks.size(); i++) {
17858            try {
17859                if (stopped) callbacks.get(i).userStopped(userId);
17860                else callbacks.get(i).userStopAborted(userId);
17861            } catch (RemoteException e) {
17862            }
17863        }
17864
17865        if (stopped) {
17866            mSystemServiceManager.cleanupUser(userId);
17867            synchronized (this) {
17868                mStackSupervisor.removeUserLocked(userId);
17869            }
17870        }
17871    }
17872
17873    @Override
17874    public UserInfo getCurrentUser() {
17875        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
17876                != PackageManager.PERMISSION_GRANTED) && (
17877                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17878                != PackageManager.PERMISSION_GRANTED)) {
17879            String msg = "Permission Denial: getCurrentUser() from pid="
17880                    + Binder.getCallingPid()
17881                    + ", uid=" + Binder.getCallingUid()
17882                    + " requires " + INTERACT_ACROSS_USERS;
17883            Slog.w(TAG, msg);
17884            throw new SecurityException(msg);
17885        }
17886        synchronized (this) {
17887            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17888        }
17889    }
17890
17891    int getCurrentUserIdLocked() {
17892        return mCurrentUserId;
17893    }
17894
17895    @Override
17896    public boolean isUserRunning(int userId, boolean orStopped) {
17897        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17898                != PackageManager.PERMISSION_GRANTED) {
17899            String msg = "Permission Denial: isUserRunning() from pid="
17900                    + Binder.getCallingPid()
17901                    + ", uid=" + Binder.getCallingUid()
17902                    + " requires " + INTERACT_ACROSS_USERS;
17903            Slog.w(TAG, msg);
17904            throw new SecurityException(msg);
17905        }
17906        synchronized (this) {
17907            return isUserRunningLocked(userId, orStopped);
17908        }
17909    }
17910
17911    boolean isUserRunningLocked(int userId, boolean orStopped) {
17912        UserStartedState state = mStartedUsers.get(userId);
17913        if (state == null) {
17914            return false;
17915        }
17916        if (orStopped) {
17917            return true;
17918        }
17919        return state.mState != UserStartedState.STATE_STOPPING
17920                && state.mState != UserStartedState.STATE_SHUTDOWN;
17921    }
17922
17923    @Override
17924    public int[] getRunningUserIds() {
17925        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17926                != PackageManager.PERMISSION_GRANTED) {
17927            String msg = "Permission Denial: isUserRunning() from pid="
17928                    + Binder.getCallingPid()
17929                    + ", uid=" + Binder.getCallingUid()
17930                    + " requires " + INTERACT_ACROSS_USERS;
17931            Slog.w(TAG, msg);
17932            throw new SecurityException(msg);
17933        }
17934        synchronized (this) {
17935            return mStartedUserArray;
17936        }
17937    }
17938
17939    private void updateStartedUserArrayLocked() {
17940        int num = 0;
17941        for (int i=0; i<mStartedUsers.size();  i++) {
17942            UserStartedState uss = mStartedUsers.valueAt(i);
17943            // This list does not include stopping users.
17944            if (uss.mState != UserStartedState.STATE_STOPPING
17945                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17946                num++;
17947            }
17948        }
17949        mStartedUserArray = new int[num];
17950        num = 0;
17951        for (int i=0; i<mStartedUsers.size();  i++) {
17952            UserStartedState uss = mStartedUsers.valueAt(i);
17953            if (uss.mState != UserStartedState.STATE_STOPPING
17954                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17955                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17956                num++;
17957            }
17958        }
17959    }
17960
17961    @Override
17962    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17963        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17964                != PackageManager.PERMISSION_GRANTED) {
17965            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17966                    + Binder.getCallingPid()
17967                    + ", uid=" + Binder.getCallingUid()
17968                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17969            Slog.w(TAG, msg);
17970            throw new SecurityException(msg);
17971        }
17972
17973        mUserSwitchObservers.register(observer);
17974    }
17975
17976    @Override
17977    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17978        mUserSwitchObservers.unregister(observer);
17979    }
17980
17981    private boolean userExists(int userId) {
17982        if (userId == 0) {
17983            return true;
17984        }
17985        UserManagerService ums = getUserManagerLocked();
17986        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17987    }
17988
17989    int[] getUsersLocked() {
17990        UserManagerService ums = getUserManagerLocked();
17991        return ums != null ? ums.getUserIds() : new int[] { 0 };
17992    }
17993
17994    UserManagerService getUserManagerLocked() {
17995        if (mUserManager == null) {
17996            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17997            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17998        }
17999        return mUserManager;
18000    }
18001
18002    private int applyUserId(int uid, int userId) {
18003        return UserHandle.getUid(userId, uid);
18004    }
18005
18006    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18007        if (info == null) return null;
18008        ApplicationInfo newInfo = new ApplicationInfo(info);
18009        newInfo.uid = applyUserId(info.uid, userId);
18010        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18011                + info.packageName;
18012        return newInfo;
18013    }
18014
18015    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18016        if (aInfo == null
18017                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18018            return aInfo;
18019        }
18020
18021        ActivityInfo info = new ActivityInfo(aInfo);
18022        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18023        return info;
18024    }
18025
18026    private final class LocalService extends ActivityManagerInternal {
18027        @Override
18028        public void goingToSleep() {
18029            ActivityManagerService.this.goingToSleep();
18030        }
18031
18032        @Override
18033        public void wakingUp() {
18034            ActivityManagerService.this.wakingUp();
18035        }
18036
18037        @Override
18038        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18039                String processName, String abiOverride, int uid, Runnable crashHandler) {
18040            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18041                    processName, abiOverride, uid, crashHandler);
18042        }
18043    }
18044
18045    /**
18046     * An implementation of IAppTask, that allows an app to manage its own tasks via
18047     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18048     * only the process that calls getAppTasks() can call the AppTask methods.
18049     */
18050    class AppTaskImpl extends IAppTask.Stub {
18051        private int mTaskId;
18052        private int mCallingUid;
18053
18054        public AppTaskImpl(int taskId, int callingUid) {
18055            mTaskId = taskId;
18056            mCallingUid = callingUid;
18057        }
18058
18059        @Override
18060        public void finishAndRemoveTask() {
18061            // Ensure that we are called from the same process that created this AppTask
18062            if (mCallingUid != Binder.getCallingUid()) {
18063                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
18064                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18065                return;
18066            }
18067
18068            synchronized (ActivityManagerService.this) {
18069                long origId = Binder.clearCallingIdentity();
18070                try {
18071                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18072                    if (tr != null) {
18073                        // Only kill the process if we are not a new document
18074                        int flags = tr.getBaseIntent().getFlags();
18075                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
18076                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
18077                        removeTaskByIdLocked(mTaskId,
18078                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
18079                    }
18080                } finally {
18081                    Binder.restoreCallingIdentity(origId);
18082                }
18083            }
18084        }
18085
18086        @Override
18087        public ActivityManager.RecentTaskInfo getTaskInfo() {
18088            // Ensure that we are called from the same process that created this AppTask
18089            if (mCallingUid != Binder.getCallingUid()) {
18090                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
18091                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18092                return null;
18093            }
18094
18095            synchronized (ActivityManagerService.this) {
18096                long origId = Binder.clearCallingIdentity();
18097                try {
18098                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18099                    if (tr != null) {
18100                        return createRecentTaskInfoFromTaskRecord(tr);
18101                    }
18102                } finally {
18103                    Binder.restoreCallingIdentity(origId);
18104                }
18105                return null;
18106            }
18107        }
18108    }
18109}
18110