ActivityManagerService.java revision a228ae95ea2f842c0e84f237c64bf032689410dd
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.content.pm.PackageManager.PERMISSION_GRANTED;
22import static com.android.internal.util.XmlUtils.readBooleanAttribute;
23import static com.android.internal.util.XmlUtils.readIntAttribute;
24import static com.android.internal.util.XmlUtils.readLongAttribute;
25import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
26import static com.android.internal.util.XmlUtils.writeIntAttribute;
27import static com.android.internal.util.XmlUtils.writeLongAttribute;
28import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
29import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
30import static org.xmlpull.v1.XmlPullParser.START_TAG;
31import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
32
33import android.Manifest;
34import android.app.AppOpsManager;
35import android.app.IActivityContainer;
36import android.app.IActivityContainerCallback;
37import android.app.IAppTask;
38import android.app.admin.DevicePolicyManager;
39import android.appwidget.AppWidgetManager;
40import android.graphics.Rect;
41import android.os.BatteryStats;
42import android.os.PersistableBundle;
43import android.service.voice.IVoiceInteractionSession;
44import android.util.ArrayMap;
45import android.util.ArraySet;
46
47import android.util.SparseIntArray;
48import com.android.internal.R;
49import com.android.internal.annotations.GuardedBy;
50import com.android.internal.app.IAppOpsService;
51import com.android.internal.app.IVoiceInteractor;
52import com.android.internal.app.ProcessMap;
53import com.android.internal.app.ProcessStats;
54import com.android.internal.content.PackageMonitor;
55import com.android.internal.os.BackgroundThread;
56import com.android.internal.os.BatteryStatsImpl;
57import com.android.internal.os.ProcessCpuTracker;
58import com.android.internal.os.TransferPipe;
59import com.android.internal.os.Zygote;
60import com.android.internal.util.FastPrintWriter;
61import com.android.internal.util.FastXmlSerializer;
62import com.android.internal.util.MemInfoReader;
63import com.android.internal.util.Preconditions;
64import com.android.server.AppOpsService;
65import com.android.server.AttributeCache;
66import com.android.server.IntentResolver;
67import com.android.server.LocalServices;
68import com.android.server.ServiceThread;
69import com.android.server.SystemService;
70import com.android.server.SystemServiceManager;
71import com.android.server.Watchdog;
72import com.android.server.am.ActivityStack.ActivityState;
73import com.android.server.firewall.IntentFirewall;
74import com.android.server.pm.UserManagerService;
75import com.android.server.wm.AppTransition;
76import com.android.server.wm.WindowManagerService;
77import com.google.android.collect.Lists;
78import com.google.android.collect.Maps;
79
80import libcore.io.IoUtils;
81
82import org.xmlpull.v1.XmlPullParser;
83import org.xmlpull.v1.XmlPullParserException;
84import org.xmlpull.v1.XmlSerializer;
85
86import android.app.Activity;
87import android.app.ActivityManager;
88import android.app.ActivityManager.RunningTaskInfo;
89import android.app.ActivityManager.StackInfo;
90import android.app.ActivityManagerInternal;
91import android.app.ActivityManagerNative;
92import android.app.ActivityOptions;
93import android.app.ActivityThread;
94import android.app.AlertDialog;
95import android.app.AppGlobals;
96import android.app.ApplicationErrorReport;
97import android.app.Dialog;
98import android.app.IActivityController;
99import android.app.IApplicationThread;
100import android.app.IInstrumentationWatcher;
101import android.app.INotificationManager;
102import android.app.IProcessObserver;
103import android.app.IServiceConnection;
104import android.app.IStopUserCallback;
105import android.app.IUiAutomationConnection;
106import android.app.IUserSwitchObserver;
107import android.app.Instrumentation;
108import android.app.Notification;
109import android.app.NotificationManager;
110import android.app.PendingIntent;
111import android.app.backup.IBackupManager;
112import android.content.ActivityNotFoundException;
113import android.content.BroadcastReceiver;
114import android.content.ClipData;
115import android.content.ComponentCallbacks2;
116import android.content.ComponentName;
117import android.content.ContentProvider;
118import android.content.ContentResolver;
119import android.content.Context;
120import android.content.DialogInterface;
121import android.content.IContentProvider;
122import android.content.IIntentReceiver;
123import android.content.IIntentSender;
124import android.content.Intent;
125import android.content.IntentFilter;
126import android.content.IntentSender;
127import android.content.pm.ActivityInfo;
128import android.content.pm.ApplicationInfo;
129import android.content.pm.ConfigurationInfo;
130import android.content.pm.IPackageDataObserver;
131import android.content.pm.IPackageManager;
132import android.content.pm.InstrumentationInfo;
133import android.content.pm.PackageInfo;
134import android.content.pm.PackageManager;
135import android.content.pm.ParceledListSlice;
136import android.content.pm.UserInfo;
137import android.content.pm.PackageManager.NameNotFoundException;
138import android.content.pm.PathPermission;
139import android.content.pm.ProviderInfo;
140import android.content.pm.ResolveInfo;
141import android.content.pm.ServiceInfo;
142import android.content.res.CompatibilityInfo;
143import android.content.res.Configuration;
144import android.net.Proxy;
145import android.net.ProxyInfo;
146import android.net.Uri;
147import android.os.Binder;
148import android.os.Build;
149import android.os.Bundle;
150import android.os.Debug;
151import android.os.DropBoxManager;
152import android.os.Environment;
153import android.os.FactoryTest;
154import android.os.FileObserver;
155import android.os.FileUtils;
156import android.os.Handler;
157import android.os.IBinder;
158import android.os.IPermissionController;
159import android.os.IRemoteCallback;
160import android.os.IUserManager;
161import android.os.Looper;
162import android.os.Message;
163import android.os.Parcel;
164import android.os.ParcelFileDescriptor;
165import android.os.Process;
166import android.os.RemoteCallbackList;
167import android.os.RemoteException;
168import android.os.SELinux;
169import android.os.ServiceManager;
170import android.os.StrictMode;
171import android.os.SystemClock;
172import android.os.SystemProperties;
173import android.os.UpdateLock;
174import android.os.UserHandle;
175import android.provider.Settings;
176import android.text.format.DateUtils;
177import android.text.format.Time;
178import android.util.AtomicFile;
179import android.util.EventLog;
180import android.util.Log;
181import android.util.Pair;
182import android.util.PrintWriterPrinter;
183import android.util.Slog;
184import android.util.SparseArray;
185import android.util.TimeUtils;
186import android.util.Xml;
187import android.view.Gravity;
188import android.view.LayoutInflater;
189import android.view.View;
190import android.view.WindowManager;
191
192import java.io.BufferedInputStream;
193import java.io.BufferedOutputStream;
194import java.io.DataInputStream;
195import java.io.DataOutputStream;
196import java.io.File;
197import java.io.FileDescriptor;
198import java.io.FileInputStream;
199import java.io.FileNotFoundException;
200import java.io.FileOutputStream;
201import java.io.IOException;
202import java.io.InputStreamReader;
203import java.io.PrintWriter;
204import java.io.StringWriter;
205import java.lang.ref.WeakReference;
206import java.util.ArrayList;
207import java.util.Arrays;
208import java.util.Collections;
209import java.util.Comparator;
210import java.util.HashMap;
211import java.util.HashSet;
212import java.util.Iterator;
213import java.util.List;
214import java.util.Locale;
215import java.util.Map;
216import java.util.Set;
217import java.util.concurrent.atomic.AtomicBoolean;
218import java.util.concurrent.atomic.AtomicLong;
219
220public final class ActivityManagerService extends ActivityManagerNative
221        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
222    private static final String USER_DATA_DIR = "/data/user/";
223    static final String TAG = "ActivityManager";
224    static final String TAG_MU = "ActivityManagerServiceMU";
225    static final boolean DEBUG = false;
226    static final boolean localLOGV = DEBUG;
227    static final boolean DEBUG_BACKUP = localLOGV || false;
228    static final boolean DEBUG_BROADCAST = localLOGV || false;
229    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
230    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
231    static final boolean DEBUG_CLEANUP = localLOGV || false;
232    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
233    static final boolean DEBUG_FOCUS = false;
234    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
235    static final boolean DEBUG_MU = localLOGV || false;
236    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
237    static final boolean DEBUG_LRU = localLOGV || false;
238    static final boolean DEBUG_PAUSE = localLOGV || false;
239    static final boolean DEBUG_POWER = localLOGV || false;
240    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
241    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
242    static final boolean DEBUG_PROCESSES = localLOGV || false;
243    static final boolean DEBUG_PROVIDER = localLOGV || false;
244    static final boolean DEBUG_RESULTS = localLOGV || false;
245    static final boolean DEBUG_SERVICE = localLOGV || false;
246    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
247    static final boolean DEBUG_STACK = localLOGV || false;
248    static final boolean DEBUG_SWITCH = localLOGV || false;
249    static final boolean DEBUG_TASKS = localLOGV || false;
250    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
251    static final boolean DEBUG_TRANSITION = localLOGV || false;
252    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
253    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
254    static final boolean DEBUG_VISBILITY = localLOGV || false;
255    static final boolean DEBUG_PSS = localLOGV || false;
256    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
257    static final boolean VALIDATE_TOKENS = false;
258    static final boolean SHOW_ACTIVITY_START_TIME = true;
259
260    // Control over CPU and battery monitoring.
261    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
262    static final boolean MONITOR_CPU_USAGE = true;
263    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
264    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
265    static final boolean MONITOR_THREAD_CPU_USAGE = false;
266
267    // The flags that are set for all calls we make to the package manager.
268    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
269
270    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
271
272    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
273
274    // Maximum number of recent tasks that we can remember.
275    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 100 : 200;
276
277    // Maximum number recent bitmaps to keep in memory.
278    static final int MAX_RECENT_BITMAPS = 5;
279
280    // Amount of time after a call to stopAppSwitches() during which we will
281    // prevent further untrusted switches from happening.
282    static final long APP_SWITCH_DELAY_TIME = 5*1000;
283
284    // How long we wait for a launched process to attach to the activity manager
285    // before we decide it's never going to come up for real.
286    static final int PROC_START_TIMEOUT = 10*1000;
287
288    // How long we wait for a launched process to attach to the activity manager
289    // before we decide it's never going to come up for real, when the process was
290    // started with a wrapper for instrumentation (such as Valgrind) because it
291    // could take much longer than usual.
292    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
293
294    // How long to wait after going idle before forcing apps to GC.
295    static final int GC_TIMEOUT = 5*1000;
296
297    // The minimum amount of time between successive GC requests for a process.
298    static final int GC_MIN_INTERVAL = 60*1000;
299
300    // The minimum amount of time between successive PSS requests for a process.
301    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
302
303    // The minimum amount of time between successive PSS requests for a process
304    // when the request is due to the memory state being lowered.
305    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
306
307    // The rate at which we check for apps using excessive power -- 15 mins.
308    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
309
310    // The minimum sample duration we will allow before deciding we have
311    // enough data on wake locks to start killing things.
312    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
313
314    // The minimum sample duration we will allow before deciding we have
315    // enough data on CPU usage to start killing things.
316    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
317
318    // How long we allow a receiver to run before giving up on it.
319    static final int BROADCAST_FG_TIMEOUT = 10*1000;
320    static final int BROADCAST_BG_TIMEOUT = 60*1000;
321
322    // How long we wait until we timeout on key dispatching.
323    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
324
325    // How long we wait until we timeout on key dispatching during instrumentation.
326    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
327
328    // Amount of time we wait for observers to handle a user switch before
329    // giving up on them and unfreezing the screen.
330    static final int USER_SWITCH_TIMEOUT = 2*1000;
331
332    // Maximum number of users we allow to be running at a time.
333    static final int MAX_RUNNING_USERS = 3;
334
335    // How long to wait in getAssistContextExtras for the activity and foreground services
336    // to respond with the result.
337    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
338
339    // Maximum number of persisted Uri grants a package is allowed
340    static final int MAX_PERSISTED_URI_GRANTS = 128;
341
342    static final int MY_PID = Process.myPid();
343
344    static final String[] EMPTY_STRING_ARRAY = new String[0];
345
346    // How many bytes to write into the dropbox log before truncating
347    static final int DROPBOX_MAX_SIZE = 256 * 1024;
348
349    // Access modes for handleIncomingUser.
350    static final int ALLOW_NON_FULL = 0;
351    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
352    static final int ALLOW_FULL_ONLY = 2;
353
354    /** All system services */
355    SystemServiceManager mSystemServiceManager;
356
357    /** Run all ActivityStacks through this */
358    ActivityStackSupervisor mStackSupervisor;
359
360    public IntentFirewall mIntentFirewall;
361
362    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
363    // default actuion automatically.  Important for devices without direct input
364    // devices.
365    private boolean mShowDialogs = true;
366
367    /**
368     * Description of a request to start a new activity, which has been held
369     * due to app switches being disabled.
370     */
371    static class PendingActivityLaunch {
372        final ActivityRecord r;
373        final ActivityRecord sourceRecord;
374        final int startFlags;
375        final ActivityStack stack;
376
377        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
378                int _startFlags, ActivityStack _stack) {
379            r = _r;
380            sourceRecord = _sourceRecord;
381            startFlags = _startFlags;
382            stack = _stack;
383        }
384    }
385
386    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
387            = new ArrayList<PendingActivityLaunch>();
388
389    BroadcastQueue mFgBroadcastQueue;
390    BroadcastQueue mBgBroadcastQueue;
391    // Convenient for easy iteration over the queues. Foreground is first
392    // so that dispatch of foreground broadcasts gets precedence.
393    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
394
395    BroadcastQueue broadcastQueueForIntent(Intent intent) {
396        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
397        if (DEBUG_BACKGROUND_BROADCAST) {
398            Slog.i(TAG, "Broadcast intent " + intent + " on "
399                    + (isFg ? "foreground" : "background")
400                    + " queue");
401        }
402        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
403    }
404
405    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
406        for (BroadcastQueue queue : mBroadcastQueues) {
407            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
408            if (r != null) {
409                return r;
410            }
411        }
412        return null;
413    }
414
415    /**
416     * Activity we have told the window manager to have key focus.
417     */
418    ActivityRecord mFocusedActivity = null;
419
420    /**
421     * List of intents that were used to start the most recent tasks.
422     */
423    ArrayList<TaskRecord> mRecentTasks;
424    ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>();
425
426    public class PendingAssistExtras extends Binder implements Runnable {
427        public final ActivityRecord activity;
428        public boolean haveResult = false;
429        public Bundle result = null;
430        public PendingAssistExtras(ActivityRecord _activity) {
431            activity = _activity;
432        }
433        @Override
434        public void run() {
435            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
436            synchronized (this) {
437                haveResult = true;
438                notifyAll();
439            }
440        }
441    }
442
443    final ArrayList<PendingAssistExtras> mPendingAssistExtras
444            = new ArrayList<PendingAssistExtras>();
445
446    /**
447     * Process management.
448     */
449    final ProcessList mProcessList = new ProcessList();
450
451    /**
452     * All of the applications we currently have running organized by name.
453     * The keys are strings of the application package name (as
454     * returned by the package manager), and the keys are ApplicationRecord
455     * objects.
456     */
457    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
458
459    /**
460     * Tracking long-term execution of processes to look for abuse and other
461     * bad app behavior.
462     */
463    final ProcessStatsService mProcessStats;
464
465    /**
466     * The currently running isolated processes.
467     */
468    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
469
470    /**
471     * Counter for assigning isolated process uids, to avoid frequently reusing the
472     * same ones.
473     */
474    int mNextIsolatedProcessUid = 0;
475
476    /**
477     * The currently running heavy-weight process, if any.
478     */
479    ProcessRecord mHeavyWeightProcess = null;
480
481    /**
482     * The last time that various processes have crashed.
483     */
484    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
485
486    /**
487     * Information about a process that is currently marked as bad.
488     */
489    static final class BadProcessInfo {
490        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
491            this.time = time;
492            this.shortMsg = shortMsg;
493            this.longMsg = longMsg;
494            this.stack = stack;
495        }
496
497        final long time;
498        final String shortMsg;
499        final String longMsg;
500        final String stack;
501    }
502
503    /**
504     * Set of applications that we consider to be bad, and will reject
505     * incoming broadcasts from (which the user has no control over).
506     * Processes are added to this set when they have crashed twice within
507     * a minimum amount of time; they are removed from it when they are
508     * later restarted (hopefully due to some user action).  The value is the
509     * time it was added to the list.
510     */
511    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
512
513    /**
514     * All of the processes we currently have running organized by pid.
515     * The keys are the pid running the application.
516     *
517     * <p>NOTE: This object is protected by its own lock, NOT the global
518     * activity manager lock!
519     */
520    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
521
522    /**
523     * All of the processes that have been forced to be foreground.  The key
524     * is the pid of the caller who requested it (we hold a death
525     * link on it).
526     */
527    abstract class ForegroundToken implements IBinder.DeathRecipient {
528        int pid;
529        IBinder token;
530    }
531    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
532
533    /**
534     * List of records for processes that someone had tried to start before the
535     * system was ready.  We don't start them at that point, but ensure they
536     * are started by the time booting is complete.
537     */
538    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
539
540    /**
541     * List of persistent applications that are in the process
542     * of being started.
543     */
544    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
545
546    /**
547     * Processes that are being forcibly torn down.
548     */
549    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
550
551    /**
552     * List of running applications, sorted by recent usage.
553     * The first entry in the list is the least recently used.
554     */
555    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
556
557    /**
558     * Where in mLruProcesses that the processes hosting activities start.
559     */
560    int mLruProcessActivityStart = 0;
561
562    /**
563     * Where in mLruProcesses that the processes hosting services start.
564     * This is after (lower index) than mLruProcessesActivityStart.
565     */
566    int mLruProcessServiceStart = 0;
567
568    /**
569     * List of processes that should gc as soon as things are idle.
570     */
571    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
572
573    /**
574     * Processes we want to collect PSS data from.
575     */
576    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
577
578    /**
579     * Last time we requested PSS data of all processes.
580     */
581    long mLastFullPssTime = SystemClock.uptimeMillis();
582
583    /**
584     * If set, the next time we collect PSS data we should do a full collection
585     * with data from native processes and the kernel.
586     */
587    boolean mFullPssPending = false;
588
589    /**
590     * This is the process holding what we currently consider to be
591     * the "home" activity.
592     */
593    ProcessRecord mHomeProcess;
594
595    /**
596     * This is the process holding the activity the user last visited that
597     * is in a different process from the one they are currently in.
598     */
599    ProcessRecord mPreviousProcess;
600
601    /**
602     * The time at which the previous process was last visible.
603     */
604    long mPreviousProcessVisibleTime;
605
606    /**
607     * Which uses have been started, so are allowed to run code.
608     */
609    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
610
611    /**
612     * LRU list of history of current users.  Most recently current is at the end.
613     */
614    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
615
616    /**
617     * Constant array of the users that are currently started.
618     */
619    int[] mStartedUserArray = new int[] { 0 };
620
621    /**
622     * Registered observers of the user switching mechanics.
623     */
624    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
625            = new RemoteCallbackList<IUserSwitchObserver>();
626
627    /**
628     * Currently active user switch.
629     */
630    Object mCurUserSwitchCallback;
631
632    /**
633     * Packages that the user has asked to have run in screen size
634     * compatibility mode instead of filling the screen.
635     */
636    final CompatModePackages mCompatModePackages;
637
638    /**
639     * Set of IntentSenderRecord objects that are currently active.
640     */
641    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
642            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
643
644    /**
645     * Fingerprints (hashCode()) of stack traces that we've
646     * already logged DropBox entries for.  Guarded by itself.  If
647     * something (rogue user app) forces this over
648     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
649     */
650    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
651    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
652
653    /**
654     * Strict Mode background batched logging state.
655     *
656     * The string buffer is guarded by itself, and its lock is also
657     * used to determine if another batched write is already
658     * in-flight.
659     */
660    private final StringBuilder mStrictModeBuffer = new StringBuilder();
661
662    /**
663     * Keeps track of all IIntentReceivers that have been registered for
664     * broadcasts.  Hash keys are the receiver IBinder, hash value is
665     * a ReceiverList.
666     */
667    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
668            new HashMap<IBinder, ReceiverList>();
669
670    /**
671     * Resolver for broadcast intents to registered receivers.
672     * Holds BroadcastFilter (subclass of IntentFilter).
673     */
674    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
675            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
676        @Override
677        protected boolean allowFilterResult(
678                BroadcastFilter filter, List<BroadcastFilter> dest) {
679            IBinder target = filter.receiverList.receiver.asBinder();
680            for (int i=dest.size()-1; i>=0; i--) {
681                if (dest.get(i).receiverList.receiver.asBinder() == target) {
682                    return false;
683                }
684            }
685            return true;
686        }
687
688        @Override
689        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
690            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
691                    || userId == filter.owningUserId) {
692                return super.newResult(filter, match, userId);
693            }
694            return null;
695        }
696
697        @Override
698        protected BroadcastFilter[] newArray(int size) {
699            return new BroadcastFilter[size];
700        }
701
702        @Override
703        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
704            return packageName.equals(filter.packageName);
705        }
706    };
707
708    /**
709     * State of all active sticky broadcasts per user.  Keys are the action of the
710     * sticky Intent, values are an ArrayList of all broadcasted intents with
711     * that action (which should usually be one).  The SparseArray is keyed
712     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
713     * for stickies that are sent to all users.
714     */
715    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
716            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
717
718    final ActiveServices mServices;
719
720    /**
721     * Backup/restore process management
722     */
723    String mBackupAppName = null;
724    BackupRecord mBackupTarget = null;
725
726    final ProviderMap mProviderMap;
727
728    /**
729     * List of content providers who have clients waiting for them.  The
730     * application is currently being launched and the provider will be
731     * removed from this list once it is published.
732     */
733    final ArrayList<ContentProviderRecord> mLaunchingProviders
734            = new ArrayList<ContentProviderRecord>();
735
736    /**
737     * File storing persisted {@link #mGrantedUriPermissions}.
738     */
739    private final AtomicFile mGrantFile;
740
741    /** XML constants used in {@link #mGrantFile} */
742    private static final String TAG_URI_GRANTS = "uri-grants";
743    private static final String TAG_URI_GRANT = "uri-grant";
744    private static final String ATTR_USER_HANDLE = "userHandle";
745    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
746    private static final String ATTR_TARGET_USER_ID = "targetUserId";
747    private static final String ATTR_SOURCE_PKG = "sourcePkg";
748    private static final String ATTR_TARGET_PKG = "targetPkg";
749    private static final String ATTR_URI = "uri";
750    private static final String ATTR_MODE_FLAGS = "modeFlags";
751    private static final String ATTR_CREATED_TIME = "createdTime";
752    private static final String ATTR_PREFIX = "prefix";
753
754    /**
755     * Global set of specific {@link Uri} permissions that have been granted.
756     * This optimized lookup structure maps from {@link UriPermission#targetUid}
757     * to {@link UriPermission#uri} to {@link UriPermission}.
758     */
759    @GuardedBy("this")
760    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
761            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
762
763    public static class GrantUri {
764        public final int sourceUserId;
765        public final Uri uri;
766        public boolean prefix;
767
768        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
769            this.sourceUserId = sourceUserId;
770            this.uri = uri;
771            this.prefix = prefix;
772        }
773
774        @Override
775        public int hashCode() {
776            return toString().hashCode();
777        }
778
779        @Override
780        public boolean equals(Object o) {
781            if (o instanceof GrantUri) {
782                GrantUri other = (GrantUri) o;
783                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
784                        && prefix == other.prefix;
785            }
786            return false;
787        }
788
789        @Override
790        public String toString() {
791            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
792            if (prefix) result += " [prefix]";
793            return result;
794        }
795
796        public String toSafeString() {
797            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
798            if (prefix) result += " [prefix]";
799            return result;
800        }
801
802        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
803            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
804                    ContentProvider.getUriWithoutUserId(uri), false);
805        }
806    }
807
808    CoreSettingsObserver mCoreSettingsObserver;
809
810    /**
811     * Thread-local storage used to carry caller permissions over through
812     * indirect content-provider access.
813     */
814    private class Identity {
815        public int pid;
816        public int uid;
817
818        Identity(int _pid, int _uid) {
819            pid = _pid;
820            uid = _uid;
821        }
822    }
823
824    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
825
826    /**
827     * All information we have collected about the runtime performance of
828     * any user id that can impact battery performance.
829     */
830    final BatteryStatsService mBatteryStatsService;
831
832    /**
833     * Information about component usage
834     */
835    final UsageStatsService mUsageStatsService;
836
837    /**
838     * Information about and control over application operations
839     */
840    final AppOpsService mAppOpsService;
841
842    /**
843     * Save recent tasks information across reboots.
844     */
845    final TaskPersister mTaskPersister;
846
847    /**
848     * Current configuration information.  HistoryRecord objects are given
849     * a reference to this object to indicate which configuration they are
850     * currently running in, so this object must be kept immutable.
851     */
852    Configuration mConfiguration = new Configuration();
853
854    /**
855     * Current sequencing integer of the configuration, for skipping old
856     * configurations.
857     */
858    int mConfigurationSeq = 0;
859
860    /**
861     * Hardware-reported OpenGLES version.
862     */
863    final int GL_ES_VERSION;
864
865    /**
866     * List of initialization arguments to pass to all processes when binding applications to them.
867     * For example, references to the commonly used services.
868     */
869    HashMap<String, IBinder> mAppBindArgs;
870
871    /**
872     * Temporary to avoid allocations.  Protected by main lock.
873     */
874    final StringBuilder mStringBuilder = new StringBuilder(256);
875
876    /**
877     * Used to control how we initialize the service.
878     */
879    ComponentName mTopComponent;
880    String mTopAction = Intent.ACTION_MAIN;
881    String mTopData;
882    boolean mProcessesReady = false;
883    boolean mSystemReady = false;
884    boolean mBooting = false;
885    boolean mWaitingUpdate = false;
886    boolean mDidUpdate = false;
887    boolean mOnBattery = false;
888    boolean mLaunchWarningShown = false;
889
890    Context mContext;
891
892    int mFactoryTest;
893
894    boolean mCheckedForSetup;
895
896    /**
897     * The time at which we will allow normal application switches again,
898     * after a call to {@link #stopAppSwitches()}.
899     */
900    long mAppSwitchesAllowedTime;
901
902    /**
903     * This is set to true after the first switch after mAppSwitchesAllowedTime
904     * is set; any switches after that will clear the time.
905     */
906    boolean mDidAppSwitch;
907
908    /**
909     * Last time (in realtime) at which we checked for power usage.
910     */
911    long mLastPowerCheckRealtime;
912
913    /**
914     * Last time (in uptime) at which we checked for power usage.
915     */
916    long mLastPowerCheckUptime;
917
918    /**
919     * Set while we are wanting to sleep, to prevent any
920     * activities from being started/resumed.
921     */
922    private boolean mSleeping = false;
923
924    /**
925     * Set while we are running a voice interaction.  This overrides
926     * sleeping while it is active.
927     */
928    private boolean mRunningVoice = false;
929
930    /**
931     * State of external calls telling us if the device is asleep.
932     */
933    private boolean mWentToSleep = false;
934
935    /**
936     * State of external call telling us if the lock screen is shown.
937     */
938    private boolean mLockScreenShown = false;
939
940    /**
941     * Set if we are shutting down the system, similar to sleeping.
942     */
943    boolean mShuttingDown = false;
944
945    /**
946     * Current sequence id for oom_adj computation traversal.
947     */
948    int mAdjSeq = 0;
949
950    /**
951     * Current sequence id for process LRU updating.
952     */
953    int mLruSeq = 0;
954
955    /**
956     * Keep track of the non-cached/empty process we last found, to help
957     * determine how to distribute cached/empty processes next time.
958     */
959    int mNumNonCachedProcs = 0;
960
961    /**
962     * Keep track of the number of cached hidden procs, to balance oom adj
963     * distribution between those and empty procs.
964     */
965    int mNumCachedHiddenProcs = 0;
966
967    /**
968     * Keep track of the number of service processes we last found, to
969     * determine on the next iteration which should be B services.
970     */
971    int mNumServiceProcs = 0;
972    int mNewNumAServiceProcs = 0;
973    int mNewNumServiceProcs = 0;
974
975    /**
976     * Allow the current computed overall memory level of the system to go down?
977     * This is set to false when we are killing processes for reasons other than
978     * memory management, so that the now smaller process list will not be taken as
979     * an indication that memory is tighter.
980     */
981    boolean mAllowLowerMemLevel = false;
982
983    /**
984     * The last computed memory level, for holding when we are in a state that
985     * processes are going away for other reasons.
986     */
987    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
988
989    /**
990     * The last total number of process we have, to determine if changes actually look
991     * like a shrinking number of process due to lower RAM.
992     */
993    int mLastNumProcesses;
994
995    /**
996     * The uptime of the last time we performed idle maintenance.
997     */
998    long mLastIdleTime = SystemClock.uptimeMillis();
999
1000    /**
1001     * Total time spent with RAM that has been added in the past since the last idle time.
1002     */
1003    long mLowRamTimeSinceLastIdle = 0;
1004
1005    /**
1006     * If RAM is currently low, when that horrible situation started.
1007     */
1008    long mLowRamStartTime = 0;
1009
1010    /**
1011     * For reporting to battery stats the current top application.
1012     */
1013    private String mCurResumedPackage = null;
1014    private int mCurResumedUid = -1;
1015
1016    /**
1017     * For reporting to battery stats the apps currently running foreground
1018     * service.  The ProcessMap is package/uid tuples; each of these contain
1019     * an array of the currently foreground processes.
1020     */
1021    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1022            = new ProcessMap<ArrayList<ProcessRecord>>();
1023
1024    /**
1025     * This is set if we had to do a delayed dexopt of an app before launching
1026     * it, to increase the ANR timeouts in that case.
1027     */
1028    boolean mDidDexOpt;
1029
1030    /**
1031     * Set if the systemServer made a call to enterSafeMode.
1032     */
1033    boolean mSafeMode;
1034
1035    String mDebugApp = null;
1036    boolean mWaitForDebugger = false;
1037    boolean mDebugTransient = false;
1038    String mOrigDebugApp = null;
1039    boolean mOrigWaitForDebugger = false;
1040    boolean mAlwaysFinishActivities = false;
1041    IActivityController mController = null;
1042    String mProfileApp = null;
1043    ProcessRecord mProfileProc = null;
1044    String mProfileFile;
1045    ParcelFileDescriptor mProfileFd;
1046    int mProfileType = 0;
1047    boolean mAutoStopProfiler = false;
1048    String mOpenGlTraceApp = null;
1049
1050    static class ProcessChangeItem {
1051        static final int CHANGE_ACTIVITIES = 1<<0;
1052        static final int CHANGE_PROCESS_STATE = 1<<1;
1053        int changes;
1054        int uid;
1055        int pid;
1056        int processState;
1057        boolean foregroundActivities;
1058    }
1059
1060    final RemoteCallbackList<IProcessObserver> mProcessObservers
1061            = new RemoteCallbackList<IProcessObserver>();
1062    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1063
1064    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1065            = new ArrayList<ProcessChangeItem>();
1066    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1067            = new ArrayList<ProcessChangeItem>();
1068
1069    /**
1070     * Runtime CPU use collection thread.  This object's lock is used to
1071     * protect all related state.
1072     */
1073    final Thread mProcessCpuThread;
1074
1075    /**
1076     * Used to collect process stats when showing not responding dialog.
1077     * Protected by mProcessCpuThread.
1078     */
1079    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1080            MONITOR_THREAD_CPU_USAGE);
1081    final AtomicLong mLastCpuTime = new AtomicLong(0);
1082    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1083
1084    long mLastWriteTime = 0;
1085
1086    /**
1087     * Used to retain an update lock when the foreground activity is in
1088     * immersive mode.
1089     */
1090    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1091
1092    /**
1093     * Set to true after the system has finished booting.
1094     */
1095    boolean mBooted = false;
1096
1097    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1098    int mProcessLimitOverride = -1;
1099
1100    WindowManagerService mWindowManager;
1101
1102    final ActivityThread mSystemThread;
1103
1104    int mCurrentUserId = 0;
1105    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1106
1107    /**
1108     * Mapping from each known user ID to the profile group ID it is associated with.
1109     */
1110    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1111
1112    private UserManagerService mUserManager;
1113
1114    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1115        final ProcessRecord mApp;
1116        final int mPid;
1117        final IApplicationThread mAppThread;
1118
1119        AppDeathRecipient(ProcessRecord app, int pid,
1120                IApplicationThread thread) {
1121            if (localLOGV) Slog.v(
1122                TAG, "New death recipient " + this
1123                + " for thread " + thread.asBinder());
1124            mApp = app;
1125            mPid = pid;
1126            mAppThread = thread;
1127        }
1128
1129        @Override
1130        public void binderDied() {
1131            if (localLOGV) Slog.v(
1132                TAG, "Death received in " + this
1133                + " for thread " + mAppThread.asBinder());
1134            synchronized(ActivityManagerService.this) {
1135                appDiedLocked(mApp, mPid, mAppThread);
1136            }
1137        }
1138    }
1139
1140    static final int SHOW_ERROR_MSG = 1;
1141    static final int SHOW_NOT_RESPONDING_MSG = 2;
1142    static final int SHOW_FACTORY_ERROR_MSG = 3;
1143    static final int UPDATE_CONFIGURATION_MSG = 4;
1144    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1145    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1146    static final int SERVICE_TIMEOUT_MSG = 12;
1147    static final int UPDATE_TIME_ZONE = 13;
1148    static final int SHOW_UID_ERROR_MSG = 14;
1149    static final int IM_FEELING_LUCKY_MSG = 15;
1150    static final int PROC_START_TIMEOUT_MSG = 20;
1151    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1152    static final int KILL_APPLICATION_MSG = 22;
1153    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1154    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1155    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1156    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1157    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1158    static final int CLEAR_DNS_CACHE_MSG = 28;
1159    static final int UPDATE_HTTP_PROXY_MSG = 29;
1160    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1161    static final int DISPATCH_PROCESSES_CHANGED = 31;
1162    static final int DISPATCH_PROCESS_DIED = 32;
1163    static final int REPORT_MEM_USAGE_MSG = 33;
1164    static final int REPORT_USER_SWITCH_MSG = 34;
1165    static final int CONTINUE_USER_SWITCH_MSG = 35;
1166    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1167    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1168    static final int PERSIST_URI_GRANTS_MSG = 38;
1169    static final int REQUEST_ALL_PSS_MSG = 39;
1170    static final int START_PROFILES_MSG = 40;
1171    static final int UPDATE_TIME = 41;
1172    static final int SYSTEM_USER_START_MSG = 42;
1173    static final int SYSTEM_USER_CURRENT_MSG = 43;
1174
1175    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1176    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1177    static final int FIRST_COMPAT_MODE_MSG = 300;
1178    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1179
1180    AlertDialog mUidAlert;
1181    CompatModeDialog mCompatModeDialog;
1182    long mLastMemUsageReportTime = 0;
1183
1184    private LockToAppRequestDialog mLockToAppRequest;
1185
1186    /**
1187     * Flag whether the current user is a "monkey", i.e. whether
1188     * the UI is driven by a UI automation tool.
1189     */
1190    private boolean mUserIsMonkey;
1191
1192    final ServiceThread mHandlerThread;
1193    final MainHandler mHandler;
1194
1195    final class MainHandler extends Handler {
1196        public MainHandler(Looper looper) {
1197            super(looper, null, true);
1198        }
1199
1200        @Override
1201        public void handleMessage(Message msg) {
1202            switch (msg.what) {
1203            case SHOW_ERROR_MSG: {
1204                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1205                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1206                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1207                synchronized (ActivityManagerService.this) {
1208                    ProcessRecord proc = (ProcessRecord)data.get("app");
1209                    AppErrorResult res = (AppErrorResult) data.get("result");
1210                    if (proc != null && proc.crashDialog != null) {
1211                        Slog.e(TAG, "App already has crash dialog: " + proc);
1212                        if (res != null) {
1213                            res.set(0);
1214                        }
1215                        return;
1216                    }
1217                    if (!showBackground && UserHandle.getAppId(proc.uid)
1218                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1219                            && proc.pid != MY_PID) {
1220                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1221                        if (res != null) {
1222                            res.set(0);
1223                        }
1224                        return;
1225                    }
1226                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1227                        Dialog d = new AppErrorDialog(mContext,
1228                                ActivityManagerService.this, res, proc);
1229                        d.show();
1230                        proc.crashDialog = d;
1231                    } else {
1232                        // The device is asleep, so just pretend that the user
1233                        // saw a crash dialog and hit "force quit".
1234                        if (res != null) {
1235                            res.set(0);
1236                        }
1237                    }
1238                }
1239
1240                ensureBootCompleted();
1241            } break;
1242            case SHOW_NOT_RESPONDING_MSG: {
1243                synchronized (ActivityManagerService.this) {
1244                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1245                    ProcessRecord proc = (ProcessRecord)data.get("app");
1246                    if (proc != null && proc.anrDialog != null) {
1247                        Slog.e(TAG, "App already has anr dialog: " + proc);
1248                        return;
1249                    }
1250
1251                    Intent intent = new Intent("android.intent.action.ANR");
1252                    if (!mProcessesReady) {
1253                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1254                                | Intent.FLAG_RECEIVER_FOREGROUND);
1255                    }
1256                    broadcastIntentLocked(null, null, intent,
1257                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1258                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1259
1260                    if (mShowDialogs) {
1261                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1262                                mContext, proc, (ActivityRecord)data.get("activity"),
1263                                msg.arg1 != 0);
1264                        d.show();
1265                        proc.anrDialog = d;
1266                    } else {
1267                        // Just kill the app if there is no dialog to be shown.
1268                        killAppAtUsersRequest(proc, null);
1269                    }
1270                }
1271
1272                ensureBootCompleted();
1273            } break;
1274            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1275                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1276                synchronized (ActivityManagerService.this) {
1277                    ProcessRecord proc = (ProcessRecord) data.get("app");
1278                    if (proc == null) {
1279                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1280                        break;
1281                    }
1282                    if (proc.crashDialog != null) {
1283                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1284                        return;
1285                    }
1286                    AppErrorResult res = (AppErrorResult) data.get("result");
1287                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1288                        Dialog d = new StrictModeViolationDialog(mContext,
1289                                ActivityManagerService.this, res, proc);
1290                        d.show();
1291                        proc.crashDialog = d;
1292                    } else {
1293                        // The device is asleep, so just pretend that the user
1294                        // saw a crash dialog and hit "force quit".
1295                        res.set(0);
1296                    }
1297                }
1298                ensureBootCompleted();
1299            } break;
1300            case SHOW_FACTORY_ERROR_MSG: {
1301                Dialog d = new FactoryErrorDialog(
1302                    mContext, msg.getData().getCharSequence("msg"));
1303                d.show();
1304                ensureBootCompleted();
1305            } break;
1306            case UPDATE_CONFIGURATION_MSG: {
1307                final ContentResolver resolver = mContext.getContentResolver();
1308                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1309            } break;
1310            case GC_BACKGROUND_PROCESSES_MSG: {
1311                synchronized (ActivityManagerService.this) {
1312                    performAppGcsIfAppropriateLocked();
1313                }
1314            } break;
1315            case WAIT_FOR_DEBUGGER_MSG: {
1316                synchronized (ActivityManagerService.this) {
1317                    ProcessRecord app = (ProcessRecord)msg.obj;
1318                    if (msg.arg1 != 0) {
1319                        if (!app.waitedForDebugger) {
1320                            Dialog d = new AppWaitingForDebuggerDialog(
1321                                    ActivityManagerService.this,
1322                                    mContext, app);
1323                            app.waitDialog = d;
1324                            app.waitedForDebugger = true;
1325                            d.show();
1326                        }
1327                    } else {
1328                        if (app.waitDialog != null) {
1329                            app.waitDialog.dismiss();
1330                            app.waitDialog = null;
1331                        }
1332                    }
1333                }
1334            } break;
1335            case SERVICE_TIMEOUT_MSG: {
1336                if (mDidDexOpt) {
1337                    mDidDexOpt = false;
1338                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1339                    nmsg.obj = msg.obj;
1340                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1341                    return;
1342                }
1343                mServices.serviceTimeout((ProcessRecord)msg.obj);
1344            } break;
1345            case UPDATE_TIME_ZONE: {
1346                synchronized (ActivityManagerService.this) {
1347                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1348                        ProcessRecord r = mLruProcesses.get(i);
1349                        if (r.thread != null) {
1350                            try {
1351                                r.thread.updateTimeZone();
1352                            } catch (RemoteException ex) {
1353                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1354                            }
1355                        }
1356                    }
1357                }
1358            } break;
1359            case CLEAR_DNS_CACHE_MSG: {
1360                synchronized (ActivityManagerService.this) {
1361                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1362                        ProcessRecord r = mLruProcesses.get(i);
1363                        if (r.thread != null) {
1364                            try {
1365                                r.thread.clearDnsCache();
1366                            } catch (RemoteException ex) {
1367                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1368                            }
1369                        }
1370                    }
1371                }
1372            } break;
1373            case UPDATE_HTTP_PROXY_MSG: {
1374                ProxyInfo proxy = (ProxyInfo)msg.obj;
1375                String host = "";
1376                String port = "";
1377                String exclList = "";
1378                Uri pacFileUrl = Uri.EMPTY;
1379                if (proxy != null) {
1380                    host = proxy.getHost();
1381                    port = Integer.toString(proxy.getPort());
1382                    exclList = proxy.getExclusionListAsString();
1383                    pacFileUrl = proxy.getPacFileUrl();
1384                }
1385                synchronized (ActivityManagerService.this) {
1386                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1387                        ProcessRecord r = mLruProcesses.get(i);
1388                        if (r.thread != null) {
1389                            try {
1390                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1391                            } catch (RemoteException ex) {
1392                                Slog.w(TAG, "Failed to update http proxy for: " +
1393                                        r.info.processName);
1394                            }
1395                        }
1396                    }
1397                }
1398            } break;
1399            case SHOW_UID_ERROR_MSG: {
1400                String title = "System UIDs Inconsistent";
1401                String text = "UIDs on the system are inconsistent, you need to wipe your"
1402                        + " data partition or your device will be unstable.";
1403                Log.e(TAG, title + ": " + text);
1404                if (mShowDialogs) {
1405                    // XXX This is a temporary dialog, no need to localize.
1406                    AlertDialog d = new BaseErrorDialog(mContext);
1407                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1408                    d.setCancelable(false);
1409                    d.setTitle(title);
1410                    d.setMessage(text);
1411                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1412                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1413                    mUidAlert = d;
1414                    d.show();
1415                }
1416            } break;
1417            case IM_FEELING_LUCKY_MSG: {
1418                if (mUidAlert != null) {
1419                    mUidAlert.dismiss();
1420                    mUidAlert = null;
1421                }
1422            } break;
1423            case PROC_START_TIMEOUT_MSG: {
1424                if (mDidDexOpt) {
1425                    mDidDexOpt = false;
1426                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1427                    nmsg.obj = msg.obj;
1428                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1429                    return;
1430                }
1431                ProcessRecord app = (ProcessRecord)msg.obj;
1432                synchronized (ActivityManagerService.this) {
1433                    processStartTimedOutLocked(app);
1434                }
1435            } break;
1436            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1437                synchronized (ActivityManagerService.this) {
1438                    doPendingActivityLaunchesLocked(true);
1439                }
1440            } break;
1441            case KILL_APPLICATION_MSG: {
1442                synchronized (ActivityManagerService.this) {
1443                    int appid = msg.arg1;
1444                    boolean restart = (msg.arg2 == 1);
1445                    Bundle bundle = (Bundle)msg.obj;
1446                    String pkg = bundle.getString("pkg");
1447                    String reason = bundle.getString("reason");
1448                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1449                            false, UserHandle.USER_ALL, reason);
1450                }
1451            } break;
1452            case FINALIZE_PENDING_INTENT_MSG: {
1453                ((PendingIntentRecord)msg.obj).completeFinalize();
1454            } break;
1455            case POST_HEAVY_NOTIFICATION_MSG: {
1456                INotificationManager inm = NotificationManager.getService();
1457                if (inm == null) {
1458                    return;
1459                }
1460
1461                ActivityRecord root = (ActivityRecord)msg.obj;
1462                ProcessRecord process = root.app;
1463                if (process == null) {
1464                    return;
1465                }
1466
1467                try {
1468                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1469                    String text = mContext.getString(R.string.heavy_weight_notification,
1470                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1471                    Notification notification = new Notification();
1472                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1473                    notification.when = 0;
1474                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1475                    notification.tickerText = text;
1476                    notification.defaults = 0; // please be quiet
1477                    notification.sound = null;
1478                    notification.vibrate = null;
1479                    notification.setLatestEventInfo(context, text,
1480                            mContext.getText(R.string.heavy_weight_notification_detail),
1481                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1482                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1483                                    new UserHandle(root.userId)));
1484
1485                    try {
1486                        int[] outId = new int[1];
1487                        inm.enqueueNotificationWithTag("android", "android", null,
1488                                R.string.heavy_weight_notification,
1489                                notification, outId, root.userId);
1490                    } catch (RuntimeException e) {
1491                        Slog.w(ActivityManagerService.TAG,
1492                                "Error showing notification for heavy-weight app", e);
1493                    } catch (RemoteException e) {
1494                    }
1495                } catch (NameNotFoundException e) {
1496                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1497                }
1498            } break;
1499            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1500                INotificationManager inm = NotificationManager.getService();
1501                if (inm == null) {
1502                    return;
1503                }
1504                try {
1505                    inm.cancelNotificationWithTag("android", null,
1506                            R.string.heavy_weight_notification,  msg.arg1);
1507                } catch (RuntimeException e) {
1508                    Slog.w(ActivityManagerService.TAG,
1509                            "Error canceling notification for service", e);
1510                } catch (RemoteException e) {
1511                }
1512            } break;
1513            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1514                synchronized (ActivityManagerService.this) {
1515                    checkExcessivePowerUsageLocked(true);
1516                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1517                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1518                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1519                }
1520            } break;
1521            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1522                synchronized (ActivityManagerService.this) {
1523                    ActivityRecord ar = (ActivityRecord)msg.obj;
1524                    if (mCompatModeDialog != null) {
1525                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1526                                ar.info.applicationInfo.packageName)) {
1527                            return;
1528                        }
1529                        mCompatModeDialog.dismiss();
1530                        mCompatModeDialog = null;
1531                    }
1532                    if (ar != null && false) {
1533                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1534                                ar.packageName)) {
1535                            int mode = mCompatModePackages.computeCompatModeLocked(
1536                                    ar.info.applicationInfo);
1537                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1538                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1539                                mCompatModeDialog = new CompatModeDialog(
1540                                        ActivityManagerService.this, mContext,
1541                                        ar.info.applicationInfo);
1542                                mCompatModeDialog.show();
1543                            }
1544                        }
1545                    }
1546                }
1547                break;
1548            }
1549            case DISPATCH_PROCESSES_CHANGED: {
1550                dispatchProcessesChanged();
1551                break;
1552            }
1553            case DISPATCH_PROCESS_DIED: {
1554                final int pid = msg.arg1;
1555                final int uid = msg.arg2;
1556                dispatchProcessDied(pid, uid);
1557                break;
1558            }
1559            case REPORT_MEM_USAGE_MSG: {
1560                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1561                Thread thread = new Thread() {
1562                    @Override public void run() {
1563                        final SparseArray<ProcessMemInfo> infoMap
1564                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1565                        for (int i=0, N=memInfos.size(); i<N; i++) {
1566                            ProcessMemInfo mi = memInfos.get(i);
1567                            infoMap.put(mi.pid, mi);
1568                        }
1569                        updateCpuStatsNow();
1570                        synchronized (mProcessCpuThread) {
1571                            final int N = mProcessCpuTracker.countStats();
1572                            for (int i=0; i<N; i++) {
1573                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1574                                if (st.vsize > 0) {
1575                                    long pss = Debug.getPss(st.pid, null);
1576                                    if (pss > 0) {
1577                                        if (infoMap.indexOfKey(st.pid) < 0) {
1578                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1579                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1580                                            mi.pss = pss;
1581                                            memInfos.add(mi);
1582                                        }
1583                                    }
1584                                }
1585                            }
1586                        }
1587
1588                        long totalPss = 0;
1589                        for (int i=0, N=memInfos.size(); i<N; i++) {
1590                            ProcessMemInfo mi = memInfos.get(i);
1591                            if (mi.pss == 0) {
1592                                mi.pss = Debug.getPss(mi.pid, null);
1593                            }
1594                            totalPss += mi.pss;
1595                        }
1596                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1597                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1598                                if (lhs.oomAdj != rhs.oomAdj) {
1599                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1600                                }
1601                                if (lhs.pss != rhs.pss) {
1602                                    return lhs.pss < rhs.pss ? 1 : -1;
1603                                }
1604                                return 0;
1605                            }
1606                        });
1607
1608                        StringBuilder tag = new StringBuilder(128);
1609                        StringBuilder stack = new StringBuilder(128);
1610                        tag.append("Low on memory -- ");
1611                        appendMemBucket(tag, totalPss, "total", false);
1612                        appendMemBucket(stack, totalPss, "total", true);
1613
1614                        StringBuilder logBuilder = new StringBuilder(1024);
1615                        logBuilder.append("Low on memory:\n");
1616
1617                        boolean firstLine = true;
1618                        int lastOomAdj = Integer.MIN_VALUE;
1619                        for (int i=0, N=memInfos.size(); i<N; i++) {
1620                            ProcessMemInfo mi = memInfos.get(i);
1621
1622                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1623                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1624                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1625                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1626                                if (lastOomAdj != mi.oomAdj) {
1627                                    lastOomAdj = mi.oomAdj;
1628                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1629                                        tag.append(" / ");
1630                                    }
1631                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1632                                        if (firstLine) {
1633                                            stack.append(":");
1634                                            firstLine = false;
1635                                        }
1636                                        stack.append("\n\t at ");
1637                                    } else {
1638                                        stack.append("$");
1639                                    }
1640                                } else {
1641                                    tag.append(" ");
1642                                    stack.append("$");
1643                                }
1644                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1645                                    appendMemBucket(tag, mi.pss, mi.name, false);
1646                                }
1647                                appendMemBucket(stack, mi.pss, mi.name, true);
1648                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1649                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1650                                    stack.append("(");
1651                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1652                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1653                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1654                                            stack.append(":");
1655                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1656                                        }
1657                                    }
1658                                    stack.append(")");
1659                                }
1660                            }
1661
1662                            logBuilder.append("  ");
1663                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1664                            logBuilder.append(' ');
1665                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1666                            logBuilder.append(' ');
1667                            ProcessList.appendRamKb(logBuilder, mi.pss);
1668                            logBuilder.append(" kB: ");
1669                            logBuilder.append(mi.name);
1670                            logBuilder.append(" (");
1671                            logBuilder.append(mi.pid);
1672                            logBuilder.append(") ");
1673                            logBuilder.append(mi.adjType);
1674                            logBuilder.append('\n');
1675                            if (mi.adjReason != null) {
1676                                logBuilder.append("                      ");
1677                                logBuilder.append(mi.adjReason);
1678                                logBuilder.append('\n');
1679                            }
1680                        }
1681
1682                        logBuilder.append("           ");
1683                        ProcessList.appendRamKb(logBuilder, totalPss);
1684                        logBuilder.append(" kB: TOTAL\n");
1685
1686                        long[] infos = new long[Debug.MEMINFO_COUNT];
1687                        Debug.getMemInfo(infos);
1688                        logBuilder.append("  MemInfo: ");
1689                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1690                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1691                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1692                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1693                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1694                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1695                            logBuilder.append("  ZRAM: ");
1696                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1697                            logBuilder.append(" kB RAM, ");
1698                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1699                            logBuilder.append(" kB swap total, ");
1700                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1701                            logBuilder.append(" kB swap free\n");
1702                        }
1703                        Slog.i(TAG, logBuilder.toString());
1704
1705                        StringBuilder dropBuilder = new StringBuilder(1024);
1706                        /*
1707                        StringWriter oomSw = new StringWriter();
1708                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1709                        StringWriter catSw = new StringWriter();
1710                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1711                        String[] emptyArgs = new String[] { };
1712                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1713                        oomPw.flush();
1714                        String oomString = oomSw.toString();
1715                        */
1716                        dropBuilder.append(stack);
1717                        dropBuilder.append('\n');
1718                        dropBuilder.append('\n');
1719                        dropBuilder.append(logBuilder);
1720                        dropBuilder.append('\n');
1721                        /*
1722                        dropBuilder.append(oomString);
1723                        dropBuilder.append('\n');
1724                        */
1725                        StringWriter catSw = new StringWriter();
1726                        synchronized (ActivityManagerService.this) {
1727                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1728                            String[] emptyArgs = new String[] { };
1729                            catPw.println();
1730                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1731                            catPw.println();
1732                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1733                                    false, false, null);
1734                            catPw.println();
1735                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1736                            catPw.flush();
1737                        }
1738                        dropBuilder.append(catSw.toString());
1739                        addErrorToDropBox("lowmem", null, "system_server", null,
1740                                null, tag.toString(), dropBuilder.toString(), null, null);
1741                        //Slog.i(TAG, "Sent to dropbox:");
1742                        //Slog.i(TAG, dropBuilder.toString());
1743                        synchronized (ActivityManagerService.this) {
1744                            long now = SystemClock.uptimeMillis();
1745                            if (mLastMemUsageReportTime < now) {
1746                                mLastMemUsageReportTime = now;
1747                            }
1748                        }
1749                    }
1750                };
1751                thread.start();
1752                break;
1753            }
1754            case REPORT_USER_SWITCH_MSG: {
1755                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1756                break;
1757            }
1758            case CONTINUE_USER_SWITCH_MSG: {
1759                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1760                break;
1761            }
1762            case USER_SWITCH_TIMEOUT_MSG: {
1763                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1764                break;
1765            }
1766            case IMMERSIVE_MODE_LOCK_MSG: {
1767                final boolean nextState = (msg.arg1 != 0);
1768                if (mUpdateLock.isHeld() != nextState) {
1769                    if (DEBUG_IMMERSIVE) {
1770                        final ActivityRecord r = (ActivityRecord) msg.obj;
1771                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1772                    }
1773                    if (nextState) {
1774                        mUpdateLock.acquire();
1775                    } else {
1776                        mUpdateLock.release();
1777                    }
1778                }
1779                break;
1780            }
1781            case PERSIST_URI_GRANTS_MSG: {
1782                writeGrantedUriPermissions();
1783                break;
1784            }
1785            case REQUEST_ALL_PSS_MSG: {
1786                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1787                break;
1788            }
1789            case START_PROFILES_MSG: {
1790                synchronized (ActivityManagerService.this) {
1791                    startProfilesLocked();
1792                }
1793                break;
1794            }
1795            case UPDATE_TIME: {
1796                synchronized (ActivityManagerService.this) {
1797                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1798                        ProcessRecord r = mLruProcesses.get(i);
1799                        if (r.thread != null) {
1800                            try {
1801                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1802                            } catch (RemoteException ex) {
1803                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1804                            }
1805                        }
1806                    }
1807                }
1808                break;
1809            }
1810            case SYSTEM_USER_START_MSG: {
1811                mSystemServiceManager.startUser(msg.arg1);
1812                break;
1813            }
1814            case SYSTEM_USER_CURRENT_MSG: {
1815                mSystemServiceManager.switchUser(msg.arg1);
1816                break;
1817            }
1818            }
1819        }
1820    };
1821
1822    static final int COLLECT_PSS_BG_MSG = 1;
1823
1824    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1825        @Override
1826        public void handleMessage(Message msg) {
1827            switch (msg.what) {
1828            case COLLECT_PSS_BG_MSG: {
1829                long start = SystemClock.uptimeMillis();
1830                MemInfoReader memInfo = null;
1831                synchronized (ActivityManagerService.this) {
1832                    if (mFullPssPending) {
1833                        mFullPssPending = false;
1834                        memInfo = new MemInfoReader();
1835                    }
1836                }
1837                if (memInfo != null) {
1838                    updateCpuStatsNow();
1839                    long nativeTotalPss = 0;
1840                    synchronized (mProcessCpuThread) {
1841                        final int N = mProcessCpuTracker.countStats();
1842                        for (int j=0; j<N; j++) {
1843                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1844                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1845                                // This is definitely an application process; skip it.
1846                                continue;
1847                            }
1848                            synchronized (mPidsSelfLocked) {
1849                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1850                                    // This is one of our own processes; skip it.
1851                                    continue;
1852                                }
1853                            }
1854                            nativeTotalPss += Debug.getPss(st.pid, null);
1855                        }
1856                    }
1857                    memInfo.readMemInfo();
1858                    synchronized (this) {
1859                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1860                                + (SystemClock.uptimeMillis()-start) + "ms");
1861                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1862                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1863                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1864                                        +memInfo.getSlabSizeKb(),
1865                                nativeTotalPss);
1866                    }
1867                }
1868
1869                int i=0, num=0;
1870                long[] tmp = new long[1];
1871                do {
1872                    ProcessRecord proc;
1873                    int procState;
1874                    int pid;
1875                    synchronized (ActivityManagerService.this) {
1876                        if (i >= mPendingPssProcesses.size()) {
1877                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1878                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1879                            mPendingPssProcesses.clear();
1880                            return;
1881                        }
1882                        proc = mPendingPssProcesses.get(i);
1883                        procState = proc.pssProcState;
1884                        if (proc.thread != null && procState == proc.setProcState) {
1885                            pid = proc.pid;
1886                        } else {
1887                            proc = null;
1888                            pid = 0;
1889                        }
1890                        i++;
1891                    }
1892                    if (proc != null) {
1893                        long pss = Debug.getPss(pid, tmp);
1894                        synchronized (ActivityManagerService.this) {
1895                            if (proc.thread != null && proc.setProcState == procState
1896                                    && proc.pid == pid) {
1897                                num++;
1898                                proc.lastPssTime = SystemClock.uptimeMillis();
1899                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1900                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1901                                        + ": " + pss + " lastPss=" + proc.lastPss
1902                                        + " state=" + ProcessList.makeProcStateString(procState));
1903                                if (proc.initialIdlePss == 0) {
1904                                    proc.initialIdlePss = pss;
1905                                }
1906                                proc.lastPss = pss;
1907                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1908                                    proc.lastCachedPss = pss;
1909                                }
1910                            }
1911                        }
1912                    }
1913                } while (true);
1914            }
1915            }
1916        }
1917    };
1918
1919    /**
1920     * Monitor for package changes and update our internal state.
1921     */
1922    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1923        @Override
1924        public void onPackageRemoved(String packageName, int uid) {
1925            // Remove all tasks with activities in the specified package from the list of recent tasks
1926            synchronized (ActivityManagerService.this) {
1927                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1928                    TaskRecord tr = mRecentTasks.get(i);
1929                    ComponentName cn = tr.intent.getComponent();
1930                    if (cn != null && cn.getPackageName().equals(packageName)) {
1931                        // If the package name matches, remove the task and kill the process
1932                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1933                    }
1934                }
1935            }
1936        }
1937
1938        @Override
1939        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1940            onPackageModified(packageName);
1941            return true;
1942        }
1943
1944        @Override
1945        public void onPackageModified(String packageName) {
1946            final PackageManager pm = mContext.getPackageManager();
1947            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1948                    new ArrayList<Pair<Intent, Integer>>();
1949            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1950            // Copy the list of recent tasks so that we don't hold onto the lock on
1951            // ActivityManagerService for long periods while checking if components exist.
1952            synchronized (ActivityManagerService.this) {
1953                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1954                    TaskRecord tr = mRecentTasks.get(i);
1955                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1956                }
1957            }
1958            // Check the recent tasks and filter out all tasks with components that no longer exist.
1959            Intent tmpI = new Intent();
1960            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1961                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1962                ComponentName cn = p.first.getComponent();
1963                if (cn != null && cn.getPackageName().equals(packageName)) {
1964                    try {
1965                        // Add the task to the list to remove if the component no longer exists
1966                        tmpI.setComponent(cn);
1967                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1968                            tasksToRemove.add(p.second);
1969                        }
1970                    } catch (Exception e) {}
1971                }
1972            }
1973            // Prune all the tasks with removed components from the list of recent tasks
1974            synchronized (ActivityManagerService.this) {
1975                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1976                    // Remove the task but don't kill the process (since other components in that
1977                    // package may still be running and in the background)
1978                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1979                }
1980            }
1981        }
1982
1983        @Override
1984        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1985            // Force stop the specified packages
1986            if (packages != null) {
1987                for (String pkg : packages) {
1988                    synchronized (ActivityManagerService.this) {
1989                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
1990                                "finished booting")) {
1991                            return true;
1992                        }
1993                    }
1994                }
1995            }
1996            return false;
1997        }
1998    };
1999
2000    public void setSystemProcess() {
2001        try {
2002            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2003            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2004            ServiceManager.addService("meminfo", new MemBinder(this));
2005            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2006            ServiceManager.addService("dbinfo", new DbBinder(this));
2007            if (MONITOR_CPU_USAGE) {
2008                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2009            }
2010            ServiceManager.addService("permission", new PermissionController(this));
2011
2012            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2013                    "android", STOCK_PM_FLAGS);
2014            mSystemThread.installSystemApplicationInfo(info);
2015
2016            synchronized (this) {
2017                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
2018                app.persistent = true;
2019                app.pid = MY_PID;
2020                app.maxAdj = ProcessList.SYSTEM_ADJ;
2021                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2022                mProcessNames.put(app.processName, app.uid, app);
2023                synchronized (mPidsSelfLocked) {
2024                    mPidsSelfLocked.put(app.pid, app);
2025                }
2026                updateLruProcessLocked(app, false, null);
2027                updateOomAdjLocked();
2028            }
2029        } catch (PackageManager.NameNotFoundException e) {
2030            throw new RuntimeException(
2031                    "Unable to find android system package", e);
2032        }
2033    }
2034
2035    public void setWindowManager(WindowManagerService wm) {
2036        mWindowManager = wm;
2037        mStackSupervisor.setWindowManager(wm);
2038    }
2039
2040    public void startObservingNativeCrashes() {
2041        final NativeCrashListener ncl = new NativeCrashListener(this);
2042        ncl.start();
2043    }
2044
2045    public IAppOpsService getAppOpsService() {
2046        return mAppOpsService;
2047    }
2048
2049    static class MemBinder extends Binder {
2050        ActivityManagerService mActivityManagerService;
2051        MemBinder(ActivityManagerService activityManagerService) {
2052            mActivityManagerService = activityManagerService;
2053        }
2054
2055        @Override
2056        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2057            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2058                    != PackageManager.PERMISSION_GRANTED) {
2059                pw.println("Permission Denial: can't dump meminfo from from pid="
2060                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2061                        + " without permission " + android.Manifest.permission.DUMP);
2062                return;
2063            }
2064
2065            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2066        }
2067    }
2068
2069    static class GraphicsBinder extends Binder {
2070        ActivityManagerService mActivityManagerService;
2071        GraphicsBinder(ActivityManagerService activityManagerService) {
2072            mActivityManagerService = activityManagerService;
2073        }
2074
2075        @Override
2076        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2077            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2078                    != PackageManager.PERMISSION_GRANTED) {
2079                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2080                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2081                        + " without permission " + android.Manifest.permission.DUMP);
2082                return;
2083            }
2084
2085            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2086        }
2087    }
2088
2089    static class DbBinder extends Binder {
2090        ActivityManagerService mActivityManagerService;
2091        DbBinder(ActivityManagerService activityManagerService) {
2092            mActivityManagerService = activityManagerService;
2093        }
2094
2095        @Override
2096        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2097            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2098                    != PackageManager.PERMISSION_GRANTED) {
2099                pw.println("Permission Denial: can't dump dbinfo from from pid="
2100                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2101                        + " without permission " + android.Manifest.permission.DUMP);
2102                return;
2103            }
2104
2105            mActivityManagerService.dumpDbInfo(fd, pw, args);
2106        }
2107    }
2108
2109    static class CpuBinder extends Binder {
2110        ActivityManagerService mActivityManagerService;
2111        CpuBinder(ActivityManagerService activityManagerService) {
2112            mActivityManagerService = activityManagerService;
2113        }
2114
2115        @Override
2116        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2117            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2118                    != PackageManager.PERMISSION_GRANTED) {
2119                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2120                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2121                        + " without permission " + android.Manifest.permission.DUMP);
2122                return;
2123            }
2124
2125            synchronized (mActivityManagerService.mProcessCpuThread) {
2126                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2127                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2128                        SystemClock.uptimeMillis()));
2129            }
2130        }
2131    }
2132
2133    public static final class Lifecycle extends SystemService {
2134        private final ActivityManagerService mService;
2135
2136        public Lifecycle(Context context) {
2137            super(context);
2138            mService = new ActivityManagerService(context);
2139        }
2140
2141        @Override
2142        public void onStart() {
2143            mService.start();
2144        }
2145
2146        public ActivityManagerService getService() {
2147            return mService;
2148        }
2149    }
2150
2151    // Note: This method is invoked on the main thread but may need to attach various
2152    // handlers to other threads.  So take care to be explicit about the looper.
2153    public ActivityManagerService(Context systemContext) {
2154        mContext = systemContext;
2155        mFactoryTest = FactoryTest.getMode();
2156        mSystemThread = ActivityThread.currentActivityThread();
2157
2158        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2159
2160        mHandlerThread = new ServiceThread(TAG,
2161                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2162        mHandlerThread.start();
2163        mHandler = new MainHandler(mHandlerThread.getLooper());
2164
2165        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2166                "foreground", BROADCAST_FG_TIMEOUT, false);
2167        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2168                "background", BROADCAST_BG_TIMEOUT, true);
2169        mBroadcastQueues[0] = mFgBroadcastQueue;
2170        mBroadcastQueues[1] = mBgBroadcastQueue;
2171
2172        mServices = new ActiveServices(this);
2173        mProviderMap = new ProviderMap(this);
2174
2175        // TODO: Move creation of battery stats service outside of activity manager service.
2176        File dataDir = Environment.getDataDirectory();
2177        File systemDir = new File(dataDir, "system");
2178        systemDir.mkdirs();
2179        mBatteryStatsService = new BatteryStatsService(new File(
2180                systemDir, "batterystats.bin").toString(), mHandler);
2181        mBatteryStatsService.getActiveStatistics().readLocked();
2182        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2183        mOnBattery = DEBUG_POWER ? true
2184                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2185        mBatteryStatsService.getActiveStatistics().setCallback(this);
2186
2187        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2188
2189        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
2190        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2191
2192        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2193
2194        // User 0 is the first and only user that runs at boot.
2195        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2196        mUserLru.add(Integer.valueOf(0));
2197        updateStartedUserArrayLocked();
2198
2199        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2200            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2201
2202        mConfiguration.setToDefaults();
2203        mConfiguration.setLocale(Locale.getDefault());
2204
2205        mConfigurationSeq = mConfiguration.seq = 1;
2206        mProcessCpuTracker.init();
2207
2208        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2209        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2210        mStackSupervisor = new ActivityStackSupervisor(this);
2211        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2212
2213        mProcessCpuThread = new Thread("CpuTracker") {
2214            @Override
2215            public void run() {
2216                while (true) {
2217                    try {
2218                        try {
2219                            synchronized(this) {
2220                                final long now = SystemClock.uptimeMillis();
2221                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2222                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2223                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2224                                //        + ", write delay=" + nextWriteDelay);
2225                                if (nextWriteDelay < nextCpuDelay) {
2226                                    nextCpuDelay = nextWriteDelay;
2227                                }
2228                                if (nextCpuDelay > 0) {
2229                                    mProcessCpuMutexFree.set(true);
2230                                    this.wait(nextCpuDelay);
2231                                }
2232                            }
2233                        } catch (InterruptedException e) {
2234                        }
2235                        updateCpuStatsNow();
2236                    } catch (Exception e) {
2237                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2238                    }
2239                }
2240            }
2241        };
2242
2243        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2244
2245        Watchdog.getInstance().addMonitor(this);
2246        Watchdog.getInstance().addThread(mHandler);
2247    }
2248
2249    public void setSystemServiceManager(SystemServiceManager mgr) {
2250        mSystemServiceManager = mgr;
2251    }
2252
2253    private void start() {
2254        Process.removeAllProcessGroups();
2255        mProcessCpuThread.start();
2256
2257        mBatteryStatsService.publish(mContext);
2258        mUsageStatsService.publish(mContext);
2259        mAppOpsService.publish(mContext);
2260        Slog.d("AppOps", "AppOpsService published");
2261        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2262    }
2263
2264    public void initPowerManagement() {
2265        mStackSupervisor.initPowerManagement();
2266        mBatteryStatsService.initPowerManagement();
2267    }
2268
2269    @Override
2270    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2271            throws RemoteException {
2272        if (code == SYSPROPS_TRANSACTION) {
2273            // We need to tell all apps about the system property change.
2274            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2275            synchronized(this) {
2276                final int NP = mProcessNames.getMap().size();
2277                for (int ip=0; ip<NP; ip++) {
2278                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2279                    final int NA = apps.size();
2280                    for (int ia=0; ia<NA; ia++) {
2281                        ProcessRecord app = apps.valueAt(ia);
2282                        if (app.thread != null) {
2283                            procs.add(app.thread.asBinder());
2284                        }
2285                    }
2286                }
2287            }
2288
2289            int N = procs.size();
2290            for (int i=0; i<N; i++) {
2291                Parcel data2 = Parcel.obtain();
2292                try {
2293                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2294                } catch (RemoteException e) {
2295                }
2296                data2.recycle();
2297            }
2298        }
2299        try {
2300            return super.onTransact(code, data, reply, flags);
2301        } catch (RuntimeException e) {
2302            // The activity manager only throws security exceptions, so let's
2303            // log all others.
2304            if (!(e instanceof SecurityException)) {
2305                Slog.wtf(TAG, "Activity Manager Crash", e);
2306            }
2307            throw e;
2308        }
2309    }
2310
2311    void updateCpuStats() {
2312        final long now = SystemClock.uptimeMillis();
2313        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2314            return;
2315        }
2316        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2317            synchronized (mProcessCpuThread) {
2318                mProcessCpuThread.notify();
2319            }
2320        }
2321    }
2322
2323    void updateCpuStatsNow() {
2324        synchronized (mProcessCpuThread) {
2325            mProcessCpuMutexFree.set(false);
2326            final long now = SystemClock.uptimeMillis();
2327            boolean haveNewCpuStats = false;
2328
2329            if (MONITOR_CPU_USAGE &&
2330                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2331                mLastCpuTime.set(now);
2332                haveNewCpuStats = true;
2333                mProcessCpuTracker.update();
2334                //Slog.i(TAG, mProcessCpu.printCurrentState());
2335                //Slog.i(TAG, "Total CPU usage: "
2336                //        + mProcessCpu.getTotalCpuPercent() + "%");
2337
2338                // Slog the cpu usage if the property is set.
2339                if ("true".equals(SystemProperties.get("events.cpu"))) {
2340                    int user = mProcessCpuTracker.getLastUserTime();
2341                    int system = mProcessCpuTracker.getLastSystemTime();
2342                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2343                    int irq = mProcessCpuTracker.getLastIrqTime();
2344                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2345                    int idle = mProcessCpuTracker.getLastIdleTime();
2346
2347                    int total = user + system + iowait + irq + softIrq + idle;
2348                    if (total == 0) total = 1;
2349
2350                    EventLog.writeEvent(EventLogTags.CPU,
2351                            ((user+system+iowait+irq+softIrq) * 100) / total,
2352                            (user * 100) / total,
2353                            (system * 100) / total,
2354                            (iowait * 100) / total,
2355                            (irq * 100) / total,
2356                            (softIrq * 100) / total);
2357                }
2358            }
2359
2360            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2361            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2362            synchronized(bstats) {
2363                synchronized(mPidsSelfLocked) {
2364                    if (haveNewCpuStats) {
2365                        if (mOnBattery) {
2366                            int perc = bstats.startAddingCpuLocked();
2367                            int totalUTime = 0;
2368                            int totalSTime = 0;
2369                            final int N = mProcessCpuTracker.countStats();
2370                            for (int i=0; i<N; i++) {
2371                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2372                                if (!st.working) {
2373                                    continue;
2374                                }
2375                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2376                                int otherUTime = (st.rel_utime*perc)/100;
2377                                int otherSTime = (st.rel_stime*perc)/100;
2378                                totalUTime += otherUTime;
2379                                totalSTime += otherSTime;
2380                                if (pr != null) {
2381                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2382                                    if (ps == null || !ps.isActive()) {
2383                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2384                                                pr.info.uid, pr.processName);
2385                                    }
2386                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2387                                            st.rel_stime-otherSTime);
2388                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2389                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2390                                } else {
2391                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2392                                    if (ps == null || !ps.isActive()) {
2393                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2394                                                bstats.mapUid(st.uid), st.name);
2395                                    }
2396                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2397                                            st.rel_stime-otherSTime);
2398                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2399                                }
2400                            }
2401                            bstats.finishAddingCpuLocked(perc, totalUTime,
2402                                    totalSTime, cpuSpeedTimes);
2403                        }
2404                    }
2405                }
2406
2407                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2408                    mLastWriteTime = now;
2409                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2410                }
2411            }
2412        }
2413    }
2414
2415    @Override
2416    public void batteryNeedsCpuUpdate() {
2417        updateCpuStatsNow();
2418    }
2419
2420    @Override
2421    public void batteryPowerChanged(boolean onBattery) {
2422        // When plugging in, update the CPU stats first before changing
2423        // the plug state.
2424        updateCpuStatsNow();
2425        synchronized (this) {
2426            synchronized(mPidsSelfLocked) {
2427                mOnBattery = DEBUG_POWER ? true : onBattery;
2428            }
2429        }
2430    }
2431
2432    /**
2433     * Initialize the application bind args. These are passed to each
2434     * process when the bindApplication() IPC is sent to the process. They're
2435     * lazily setup to make sure the services are running when they're asked for.
2436     */
2437    private HashMap<String, IBinder> getCommonServicesLocked() {
2438        if (mAppBindArgs == null) {
2439            mAppBindArgs = new HashMap<String, IBinder>();
2440
2441            // Setup the application init args
2442            mAppBindArgs.put("package", ServiceManager.getService("package"));
2443            mAppBindArgs.put("window", ServiceManager.getService("window"));
2444            mAppBindArgs.put(Context.ALARM_SERVICE,
2445                    ServiceManager.getService(Context.ALARM_SERVICE));
2446        }
2447        return mAppBindArgs;
2448    }
2449
2450    final void setFocusedActivityLocked(ActivityRecord r) {
2451        if (mFocusedActivity != r) {
2452            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2453            mFocusedActivity = r;
2454            if (r.task != null && r.task.voiceInteractor != null) {
2455                startRunningVoiceLocked();
2456            } else {
2457                finishRunningVoiceLocked();
2458            }
2459            mStackSupervisor.setFocusedStack(r);
2460            if (r != null) {
2461                mWindowManager.setFocusedApp(r.appToken, true);
2462            }
2463            applyUpdateLockStateLocked(r);
2464        }
2465    }
2466
2467    final void clearFocusedActivity(ActivityRecord r) {
2468        if (mFocusedActivity == r) {
2469            mFocusedActivity = null;
2470        }
2471    }
2472
2473    @Override
2474    public void setFocusedStack(int stackId) {
2475        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2476        synchronized (ActivityManagerService.this) {
2477            ActivityStack stack = mStackSupervisor.getStack(stackId);
2478            if (stack != null) {
2479                ActivityRecord r = stack.topRunningActivityLocked(null);
2480                if (r != null) {
2481                    setFocusedActivityLocked(r);
2482                }
2483            }
2484        }
2485    }
2486
2487    @Override
2488    public void notifyActivityDrawn(IBinder token) {
2489        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2490        synchronized (this) {
2491            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2492            if (r != null) {
2493                r.task.stack.notifyActivityDrawnLocked(r);
2494            }
2495        }
2496    }
2497
2498    final void applyUpdateLockStateLocked(ActivityRecord r) {
2499        // Modifications to the UpdateLock state are done on our handler, outside
2500        // the activity manager's locks.  The new state is determined based on the
2501        // state *now* of the relevant activity record.  The object is passed to
2502        // the handler solely for logging detail, not to be consulted/modified.
2503        final boolean nextState = r != null && r.immersive;
2504        mHandler.sendMessage(
2505                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2506    }
2507
2508    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2509        Message msg = Message.obtain();
2510        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2511        msg.obj = r.task.askedCompatMode ? null : r;
2512        mHandler.sendMessage(msg);
2513    }
2514
2515    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2516            String what, Object obj, ProcessRecord srcApp) {
2517        app.lastActivityTime = now;
2518
2519        if (app.activities.size() > 0) {
2520            // Don't want to touch dependent processes that are hosting activities.
2521            return index;
2522        }
2523
2524        int lrui = mLruProcesses.lastIndexOf(app);
2525        if (lrui < 0) {
2526            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2527                    + what + " " + obj + " from " + srcApp);
2528            return index;
2529        }
2530
2531        if (lrui >= index) {
2532            // Don't want to cause this to move dependent processes *back* in the
2533            // list as if they were less frequently used.
2534            return index;
2535        }
2536
2537        if (lrui >= mLruProcessActivityStart) {
2538            // Don't want to touch dependent processes that are hosting activities.
2539            return index;
2540        }
2541
2542        mLruProcesses.remove(lrui);
2543        if (index > 0) {
2544            index--;
2545        }
2546        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2547                + " in LRU list: " + app);
2548        mLruProcesses.add(index, app);
2549        return index;
2550    }
2551
2552    final void removeLruProcessLocked(ProcessRecord app) {
2553        int lrui = mLruProcesses.lastIndexOf(app);
2554        if (lrui >= 0) {
2555            if (lrui <= mLruProcessActivityStart) {
2556                mLruProcessActivityStart--;
2557            }
2558            if (lrui <= mLruProcessServiceStart) {
2559                mLruProcessServiceStart--;
2560            }
2561            mLruProcesses.remove(lrui);
2562        }
2563    }
2564
2565    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2566            ProcessRecord client) {
2567        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2568                || app.treatLikeActivity;
2569        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2570        if (!activityChange && hasActivity) {
2571            // The process has activities, so we are only allowing activity-based adjustments
2572            // to move it.  It should be kept in the front of the list with other
2573            // processes that have activities, and we don't want those to change their
2574            // order except due to activity operations.
2575            return;
2576        }
2577
2578        mLruSeq++;
2579        final long now = SystemClock.uptimeMillis();
2580        app.lastActivityTime = now;
2581
2582        // First a quick reject: if the app is already at the position we will
2583        // put it, then there is nothing to do.
2584        if (hasActivity) {
2585            final int N = mLruProcesses.size();
2586            if (N > 0 && mLruProcesses.get(N-1) == app) {
2587                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2588                return;
2589            }
2590        } else {
2591            if (mLruProcessServiceStart > 0
2592                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2593                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2594                return;
2595            }
2596        }
2597
2598        int lrui = mLruProcesses.lastIndexOf(app);
2599
2600        if (app.persistent && lrui >= 0) {
2601            // We don't care about the position of persistent processes, as long as
2602            // they are in the list.
2603            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2604            return;
2605        }
2606
2607        /* In progress: compute new position first, so we can avoid doing work
2608           if the process is not actually going to move.  Not yet working.
2609        int addIndex;
2610        int nextIndex;
2611        boolean inActivity = false, inService = false;
2612        if (hasActivity) {
2613            // Process has activities, put it at the very tipsy-top.
2614            addIndex = mLruProcesses.size();
2615            nextIndex = mLruProcessServiceStart;
2616            inActivity = true;
2617        } else if (hasService) {
2618            // Process has services, put it at the top of the service list.
2619            addIndex = mLruProcessActivityStart;
2620            nextIndex = mLruProcessServiceStart;
2621            inActivity = true;
2622            inService = true;
2623        } else  {
2624            // Process not otherwise of interest, it goes to the top of the non-service area.
2625            addIndex = mLruProcessServiceStart;
2626            if (client != null) {
2627                int clientIndex = mLruProcesses.lastIndexOf(client);
2628                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2629                        + app);
2630                if (clientIndex >= 0 && addIndex > clientIndex) {
2631                    addIndex = clientIndex;
2632                }
2633            }
2634            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2635        }
2636
2637        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2638                + mLruProcessActivityStart + "): " + app);
2639        */
2640
2641        if (lrui >= 0) {
2642            if (lrui < mLruProcessActivityStart) {
2643                mLruProcessActivityStart--;
2644            }
2645            if (lrui < mLruProcessServiceStart) {
2646                mLruProcessServiceStart--;
2647            }
2648            /*
2649            if (addIndex > lrui) {
2650                addIndex--;
2651            }
2652            if (nextIndex > lrui) {
2653                nextIndex--;
2654            }
2655            */
2656            mLruProcesses.remove(lrui);
2657        }
2658
2659        /*
2660        mLruProcesses.add(addIndex, app);
2661        if (inActivity) {
2662            mLruProcessActivityStart++;
2663        }
2664        if (inService) {
2665            mLruProcessActivityStart++;
2666        }
2667        */
2668
2669        int nextIndex;
2670        if (hasActivity) {
2671            final int N = mLruProcesses.size();
2672            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2673                // Process doesn't have activities, but has clients with
2674                // activities...  move it up, but one below the top (the top
2675                // should always have a real activity).
2676                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2677                mLruProcesses.add(N-1, app);
2678                // To keep it from spamming the LRU list (by making a bunch of clients),
2679                // we will push down any other entries owned by the app.
2680                final int uid = app.info.uid;
2681                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2682                    ProcessRecord subProc = mLruProcesses.get(i);
2683                    if (subProc.info.uid == uid) {
2684                        // We want to push this one down the list.  If the process after
2685                        // it is for the same uid, however, don't do so, because we don't
2686                        // want them internally to be re-ordered.
2687                        if (mLruProcesses.get(i-1).info.uid != uid) {
2688                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2689                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2690                            ProcessRecord tmp = mLruProcesses.get(i);
2691                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2692                            mLruProcesses.set(i-1, tmp);
2693                            i--;
2694                        }
2695                    } else {
2696                        // A gap, we can stop here.
2697                        break;
2698                    }
2699                }
2700            } else {
2701                // Process has activities, put it at the very tipsy-top.
2702                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2703                mLruProcesses.add(app);
2704            }
2705            nextIndex = mLruProcessServiceStart;
2706        } else if (hasService) {
2707            // Process has services, put it at the top of the service list.
2708            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2709            mLruProcesses.add(mLruProcessActivityStart, app);
2710            nextIndex = mLruProcessServiceStart;
2711            mLruProcessActivityStart++;
2712        } else  {
2713            // Process not otherwise of interest, it goes to the top of the non-service area.
2714            int index = mLruProcessServiceStart;
2715            if (client != null) {
2716                // If there is a client, don't allow the process to be moved up higher
2717                // in the list than that client.
2718                int clientIndex = mLruProcesses.lastIndexOf(client);
2719                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2720                        + " when updating " + app);
2721                if (clientIndex <= lrui) {
2722                    // Don't allow the client index restriction to push it down farther in the
2723                    // list than it already is.
2724                    clientIndex = lrui;
2725                }
2726                if (clientIndex >= 0 && index > clientIndex) {
2727                    index = clientIndex;
2728                }
2729            }
2730            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2731            mLruProcesses.add(index, app);
2732            nextIndex = index-1;
2733            mLruProcessActivityStart++;
2734            mLruProcessServiceStart++;
2735        }
2736
2737        // If the app is currently using a content provider or service,
2738        // bump those processes as well.
2739        for (int j=app.connections.size()-1; j>=0; j--) {
2740            ConnectionRecord cr = app.connections.valueAt(j);
2741            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2742                    && cr.binding.service.app != null
2743                    && cr.binding.service.app.lruSeq != mLruSeq
2744                    && !cr.binding.service.app.persistent) {
2745                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2746                        "service connection", cr, app);
2747            }
2748        }
2749        for (int j=app.conProviders.size()-1; j>=0; j--) {
2750            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2751            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2752                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2753                        "provider reference", cpr, app);
2754            }
2755        }
2756    }
2757
2758    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2759        if (uid == Process.SYSTEM_UID) {
2760            // The system gets to run in any process.  If there are multiple
2761            // processes with the same uid, just pick the first (this
2762            // should never happen).
2763            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2764            if (procs == null) return null;
2765            final int N = procs.size();
2766            for (int i = 0; i < N; i++) {
2767                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2768            }
2769        }
2770        ProcessRecord proc = mProcessNames.get(processName, uid);
2771        if (false && proc != null && !keepIfLarge
2772                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2773                && proc.lastCachedPss >= 4000) {
2774            // Turn this condition on to cause killing to happen regularly, for testing.
2775            if (proc.baseProcessTracker != null) {
2776                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2777            }
2778            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2779                    + "k from cached");
2780        } else if (proc != null && !keepIfLarge
2781                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2782                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2783            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2784            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2785                if (proc.baseProcessTracker != null) {
2786                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2787                }
2788                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2789                        + "k from cached");
2790            }
2791        }
2792        return proc;
2793    }
2794
2795    void ensurePackageDexOpt(String packageName) {
2796        IPackageManager pm = AppGlobals.getPackageManager();
2797        try {
2798            if (pm.performDexOpt(packageName)) {
2799                mDidDexOpt = true;
2800            }
2801        } catch (RemoteException e) {
2802        }
2803    }
2804
2805    boolean isNextTransitionForward() {
2806        int transit = mWindowManager.getPendingAppTransition();
2807        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2808                || transit == AppTransition.TRANSIT_TASK_OPEN
2809                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2810    }
2811
2812    final ProcessRecord startProcessLocked(String processName,
2813            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2814            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2815            boolean isolated, boolean keepIfLarge) {
2816        ProcessRecord app;
2817        if (!isolated) {
2818            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2819        } else {
2820            // If this is an isolated process, it can't re-use an existing process.
2821            app = null;
2822        }
2823        // We don't have to do anything more if:
2824        // (1) There is an existing application record; and
2825        // (2) The caller doesn't think it is dead, OR there is no thread
2826        //     object attached to it so we know it couldn't have crashed; and
2827        // (3) There is a pid assigned to it, so it is either starting or
2828        //     already running.
2829        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2830                + " app=" + app + " knownToBeDead=" + knownToBeDead
2831                + " thread=" + (app != null ? app.thread : null)
2832                + " pid=" + (app != null ? app.pid : -1));
2833        if (app != null && app.pid > 0) {
2834            if (!knownToBeDead || app.thread == null) {
2835                // We already have the app running, or are waiting for it to
2836                // come up (we have a pid but not yet its thread), so keep it.
2837                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2838                // If this is a new package in the process, add the package to the list
2839                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2840                return app;
2841            }
2842
2843            // An application record is attached to a previous process,
2844            // clean it up now.
2845            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2846            Process.killProcessGroup(app.info.uid, app.pid);
2847            handleAppDiedLocked(app, true, true);
2848        }
2849
2850        String hostingNameStr = hostingName != null
2851                ? hostingName.flattenToShortString() : null;
2852
2853        if (!isolated) {
2854            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2855                // If we are in the background, then check to see if this process
2856                // is bad.  If so, we will just silently fail.
2857                if (mBadProcesses.get(info.processName, info.uid) != null) {
2858                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2859                            + "/" + info.processName);
2860                    return null;
2861                }
2862            } else {
2863                // When the user is explicitly starting a process, then clear its
2864                // crash count so that we won't make it bad until they see at
2865                // least one crash dialog again, and make the process good again
2866                // if it had been bad.
2867                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2868                        + "/" + info.processName);
2869                mProcessCrashTimes.remove(info.processName, info.uid);
2870                if (mBadProcesses.get(info.processName, info.uid) != null) {
2871                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2872                            UserHandle.getUserId(info.uid), info.uid,
2873                            info.processName);
2874                    mBadProcesses.remove(info.processName, info.uid);
2875                    if (app != null) {
2876                        app.bad = false;
2877                    }
2878                }
2879            }
2880        }
2881
2882        if (app == null) {
2883            app = newProcessRecordLocked(info, processName, isolated);
2884            if (app == null) {
2885                Slog.w(TAG, "Failed making new process record for "
2886                        + processName + "/" + info.uid + " isolated=" + isolated);
2887                return null;
2888            }
2889            mProcessNames.put(processName, app.uid, app);
2890            if (isolated) {
2891                mIsolatedProcesses.put(app.uid, app);
2892            }
2893        } else {
2894            // If this is a new package in the process, add the package to the list
2895            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2896        }
2897
2898        // If the system is not ready yet, then hold off on starting this
2899        // process until it is.
2900        if (!mProcessesReady
2901                && !isAllowedWhileBooting(info)
2902                && !allowWhileBooting) {
2903            if (!mProcessesOnHold.contains(app)) {
2904                mProcessesOnHold.add(app);
2905            }
2906            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2907            return app;
2908        }
2909
2910        startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */);
2911        return (app.pid != 0) ? app : null;
2912    }
2913
2914    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2915        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2916    }
2917
2918    private final void startProcessLocked(ProcessRecord app,
2919            String hostingType, String hostingNameStr, String abiOverride) {
2920        if (app.pid > 0 && app.pid != MY_PID) {
2921            synchronized (mPidsSelfLocked) {
2922                mPidsSelfLocked.remove(app.pid);
2923                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2924            }
2925            app.setPid(0);
2926        }
2927
2928        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2929                "startProcessLocked removing on hold: " + app);
2930        mProcessesOnHold.remove(app);
2931
2932        updateCpuStats();
2933
2934        try {
2935            int uid = app.uid;
2936
2937            int[] gids = null;
2938            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2939            if (!app.isolated) {
2940                int[] permGids = null;
2941                try {
2942                    final PackageManager pm = mContext.getPackageManager();
2943                    permGids = pm.getPackageGids(app.info.packageName);
2944
2945                    if (Environment.isExternalStorageEmulated()) {
2946                        if (pm.checkPermission(
2947                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2948                                app.info.packageName) == PERMISSION_GRANTED) {
2949                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2950                        } else {
2951                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2952                        }
2953                    }
2954                } catch (PackageManager.NameNotFoundException e) {
2955                    Slog.w(TAG, "Unable to retrieve gids", e);
2956                }
2957
2958                /*
2959                 * Add shared application and profile GIDs so applications can share some
2960                 * resources like shared libraries and access user-wide resources
2961                 */
2962                if (permGids == null) {
2963                    gids = new int[2];
2964                } else {
2965                    gids = new int[permGids.length + 2];
2966                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2967                }
2968                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2969                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2970            }
2971            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2972                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2973                        && mTopComponent != null
2974                        && app.processName.equals(mTopComponent.getPackageName())) {
2975                    uid = 0;
2976                }
2977                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2978                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2979                    uid = 0;
2980                }
2981            }
2982            int debugFlags = 0;
2983            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2984                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2985                // Also turn on CheckJNI for debuggable apps. It's quite
2986                // awkward to turn on otherwise.
2987                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2988            }
2989            // Run the app in safe mode if its manifest requests so or the
2990            // system is booted in safe mode.
2991            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2992                mSafeMode == true) {
2993                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2994            }
2995            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2996                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2997            }
2998            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2999                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3000            }
3001            if ("1".equals(SystemProperties.get("debug.assert"))) {
3002                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3003            }
3004
3005            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3006            if (requiredAbi == null) {
3007                requiredAbi = Build.SUPPORTED_ABIS[0];
3008            }
3009
3010            // Start the process.  It will either succeed and return a result containing
3011            // the PID of the new process, or else throw a RuntimeException.
3012            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
3013                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3014                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
3015
3016            if (app.isolated) {
3017                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3018            }
3019            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3020
3021            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3022                    UserHandle.getUserId(uid), startResult.pid, uid,
3023                    app.processName, hostingType,
3024                    hostingNameStr != null ? hostingNameStr : "");
3025
3026            if (app.persistent) {
3027                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3028            }
3029
3030            StringBuilder buf = mStringBuilder;
3031            buf.setLength(0);
3032            buf.append("Start proc ");
3033            buf.append(app.processName);
3034            buf.append(" for ");
3035            buf.append(hostingType);
3036            if (hostingNameStr != null) {
3037                buf.append(" ");
3038                buf.append(hostingNameStr);
3039            }
3040            buf.append(": pid=");
3041            buf.append(startResult.pid);
3042            buf.append(" uid=");
3043            buf.append(uid);
3044            buf.append(" gids={");
3045            if (gids != null) {
3046                for (int gi=0; gi<gids.length; gi++) {
3047                    if (gi != 0) buf.append(", ");
3048                    buf.append(gids[gi]);
3049
3050                }
3051            }
3052            buf.append("}");
3053            if (requiredAbi != null) {
3054                buf.append(" abi=");
3055                buf.append(requiredAbi);
3056            }
3057            Slog.i(TAG, buf.toString());
3058            app.setPid(startResult.pid);
3059            app.usingWrapper = startResult.usingWrapper;
3060            app.removed = false;
3061            app.killedByAm = false;
3062            synchronized (mPidsSelfLocked) {
3063                this.mPidsSelfLocked.put(startResult.pid, app);
3064                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3065                msg.obj = app;
3066                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3067                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3068            }
3069        } catch (RuntimeException e) {
3070            // XXX do better error recovery.
3071            app.setPid(0);
3072            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3073            if (app.isolated) {
3074                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3075            }
3076            Slog.e(TAG, "Failure starting process " + app.processName, e);
3077        }
3078    }
3079
3080    void updateUsageStats(ActivityRecord component, boolean resumed) {
3081        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3082        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3083        if (resumed) {
3084            mUsageStatsService.noteResumeComponent(component.realActivity);
3085            synchronized (stats) {
3086                stats.noteActivityResumedLocked(component.app.uid);
3087            }
3088        } else {
3089            mUsageStatsService.notePauseComponent(component.realActivity);
3090            synchronized (stats) {
3091                stats.noteActivityPausedLocked(component.app.uid);
3092            }
3093        }
3094    }
3095
3096    Intent getHomeIntent() {
3097        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3098        intent.setComponent(mTopComponent);
3099        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3100            intent.addCategory(Intent.CATEGORY_HOME);
3101        }
3102        return intent;
3103    }
3104
3105    boolean startHomeActivityLocked(int userId) {
3106        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3107                && mTopAction == null) {
3108            // We are running in factory test mode, but unable to find
3109            // the factory test app, so just sit around displaying the
3110            // error message and don't try to start anything.
3111            return false;
3112        }
3113        Intent intent = getHomeIntent();
3114        ActivityInfo aInfo =
3115            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3116        if (aInfo != null) {
3117            intent.setComponent(new ComponentName(
3118                    aInfo.applicationInfo.packageName, aInfo.name));
3119            // Don't do this if the home app is currently being
3120            // instrumented.
3121            aInfo = new ActivityInfo(aInfo);
3122            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3123            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3124                    aInfo.applicationInfo.uid, true);
3125            if (app == null || app.instrumentationClass == null) {
3126                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3127                mStackSupervisor.startHomeActivity(intent, aInfo);
3128            }
3129        }
3130
3131        return true;
3132    }
3133
3134    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3135        ActivityInfo ai = null;
3136        ComponentName comp = intent.getComponent();
3137        try {
3138            if (comp != null) {
3139                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3140            } else {
3141                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3142                        intent,
3143                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3144                            flags, userId);
3145
3146                if (info != null) {
3147                    ai = info.activityInfo;
3148                }
3149            }
3150        } catch (RemoteException e) {
3151            // ignore
3152        }
3153
3154        return ai;
3155    }
3156
3157    /**
3158     * Starts the "new version setup screen" if appropriate.
3159     */
3160    void startSetupActivityLocked() {
3161        // Only do this once per boot.
3162        if (mCheckedForSetup) {
3163            return;
3164        }
3165
3166        // We will show this screen if the current one is a different
3167        // version than the last one shown, and we are not running in
3168        // low-level factory test mode.
3169        final ContentResolver resolver = mContext.getContentResolver();
3170        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3171                Settings.Global.getInt(resolver,
3172                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3173            mCheckedForSetup = true;
3174
3175            // See if we should be showing the platform update setup UI.
3176            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3177            List<ResolveInfo> ris = mContext.getPackageManager()
3178                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3179
3180            // We don't allow third party apps to replace this.
3181            ResolveInfo ri = null;
3182            for (int i=0; ris != null && i<ris.size(); i++) {
3183                if ((ris.get(i).activityInfo.applicationInfo.flags
3184                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3185                    ri = ris.get(i);
3186                    break;
3187                }
3188            }
3189
3190            if (ri != null) {
3191                String vers = ri.activityInfo.metaData != null
3192                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3193                        : null;
3194                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3195                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3196                            Intent.METADATA_SETUP_VERSION);
3197                }
3198                String lastVers = Settings.Secure.getString(
3199                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3200                if (vers != null && !vers.equals(lastVers)) {
3201                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3202                    intent.setComponent(new ComponentName(
3203                            ri.activityInfo.packageName, ri.activityInfo.name));
3204                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3205                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3206                }
3207            }
3208        }
3209    }
3210
3211    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3212        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3213    }
3214
3215    void enforceNotIsolatedCaller(String caller) {
3216        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3217            throw new SecurityException("Isolated process not allowed to call " + caller);
3218        }
3219    }
3220
3221    @Override
3222    public int getFrontActivityScreenCompatMode() {
3223        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3224        synchronized (this) {
3225            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3226        }
3227    }
3228
3229    @Override
3230    public void setFrontActivityScreenCompatMode(int mode) {
3231        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3232                "setFrontActivityScreenCompatMode");
3233        synchronized (this) {
3234            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3235        }
3236    }
3237
3238    @Override
3239    public int getPackageScreenCompatMode(String packageName) {
3240        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3241        synchronized (this) {
3242            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3243        }
3244    }
3245
3246    @Override
3247    public void setPackageScreenCompatMode(String packageName, int mode) {
3248        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3249                "setPackageScreenCompatMode");
3250        synchronized (this) {
3251            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3252        }
3253    }
3254
3255    @Override
3256    public boolean getPackageAskScreenCompat(String packageName) {
3257        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3258        synchronized (this) {
3259            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3260        }
3261    }
3262
3263    @Override
3264    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3265        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3266                "setPackageAskScreenCompat");
3267        synchronized (this) {
3268            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3269        }
3270    }
3271
3272    private void dispatchProcessesChanged() {
3273        int N;
3274        synchronized (this) {
3275            N = mPendingProcessChanges.size();
3276            if (mActiveProcessChanges.length < N) {
3277                mActiveProcessChanges = new ProcessChangeItem[N];
3278            }
3279            mPendingProcessChanges.toArray(mActiveProcessChanges);
3280            mAvailProcessChanges.addAll(mPendingProcessChanges);
3281            mPendingProcessChanges.clear();
3282            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3283        }
3284
3285        int i = mProcessObservers.beginBroadcast();
3286        while (i > 0) {
3287            i--;
3288            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3289            if (observer != null) {
3290                try {
3291                    for (int j=0; j<N; j++) {
3292                        ProcessChangeItem item = mActiveProcessChanges[j];
3293                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3294                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3295                                    + item.pid + " uid=" + item.uid + ": "
3296                                    + item.foregroundActivities);
3297                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3298                                    item.foregroundActivities);
3299                        }
3300                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3301                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3302                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3303                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3304                        }
3305                    }
3306                } catch (RemoteException e) {
3307                }
3308            }
3309        }
3310        mProcessObservers.finishBroadcast();
3311    }
3312
3313    private void dispatchProcessDied(int pid, int uid) {
3314        int i = mProcessObservers.beginBroadcast();
3315        while (i > 0) {
3316            i--;
3317            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3318            if (observer != null) {
3319                try {
3320                    observer.onProcessDied(pid, uid);
3321                } catch (RemoteException e) {
3322                }
3323            }
3324        }
3325        mProcessObservers.finishBroadcast();
3326    }
3327
3328    final void doPendingActivityLaunchesLocked(boolean doResume) {
3329        final int N = mPendingActivityLaunches.size();
3330        if (N <= 0) {
3331            return;
3332        }
3333        for (int i=0; i<N; i++) {
3334            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3335            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3336                    doResume && i == (N-1), null);
3337        }
3338        mPendingActivityLaunches.clear();
3339    }
3340
3341    @Override
3342    public final int startActivity(IApplicationThread caller, String callingPackage,
3343            Intent intent, String resolvedType, IBinder resultTo,
3344            String resultWho, int requestCode, int startFlags,
3345            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3346        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3347                resultWho, requestCode,
3348                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3349    }
3350
3351    @Override
3352    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3353            Intent intent, String resolvedType, IBinder resultTo,
3354            String resultWho, int requestCode, int startFlags,
3355            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3356        enforceNotIsolatedCaller("startActivity");
3357        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3358                false, ALLOW_FULL_ONLY, "startActivity", null);
3359        // TODO: Switch to user app stacks here.
3360        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3361                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3362                null, null, options, userId, null);
3363    }
3364
3365    @Override
3366    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3367            Intent intent, String resolvedType, IBinder resultTo,
3368            String resultWho, int requestCode, int startFlags, String profileFile,
3369            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3370        enforceNotIsolatedCaller("startActivityAndWait");
3371        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3372                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3373        WaitResult res = new WaitResult();
3374        // TODO: Switch to user app stacks here.
3375        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3376                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3377                res, null, options, userId, null);
3378        return res;
3379    }
3380
3381    @Override
3382    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3383            Intent intent, String resolvedType, IBinder resultTo,
3384            String resultWho, int requestCode, int startFlags, Configuration config,
3385            Bundle options, int userId) {
3386        enforceNotIsolatedCaller("startActivityWithConfig");
3387        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3388                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3389        // TODO: Switch to user app stacks here.
3390        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3391                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3392                null, null, null, config, options, userId, null);
3393        return ret;
3394    }
3395
3396    @Override
3397    public int startActivityIntentSender(IApplicationThread caller,
3398            IntentSender intent, Intent fillInIntent, String resolvedType,
3399            IBinder resultTo, String resultWho, int requestCode,
3400            int flagsMask, int flagsValues, Bundle options) {
3401        enforceNotIsolatedCaller("startActivityIntentSender");
3402        // Refuse possible leaked file descriptors
3403        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3404            throw new IllegalArgumentException("File descriptors passed in Intent");
3405        }
3406
3407        IIntentSender sender = intent.getTarget();
3408        if (!(sender instanceof PendingIntentRecord)) {
3409            throw new IllegalArgumentException("Bad PendingIntent object");
3410        }
3411
3412        PendingIntentRecord pir = (PendingIntentRecord)sender;
3413
3414        synchronized (this) {
3415            // If this is coming from the currently resumed activity, it is
3416            // effectively saying that app switches are allowed at this point.
3417            final ActivityStack stack = getFocusedStack();
3418            if (stack.mResumedActivity != null &&
3419                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3420                mAppSwitchesAllowedTime = 0;
3421            }
3422        }
3423        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3424                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3425        return ret;
3426    }
3427
3428    @Override
3429    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3430            Intent intent, String resolvedType, IVoiceInteractionSession session,
3431            IVoiceInteractor interactor, int startFlags, String profileFile,
3432            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3433        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3434                != PackageManager.PERMISSION_GRANTED) {
3435            String msg = "Permission Denial: startVoiceActivity() from pid="
3436                    + Binder.getCallingPid()
3437                    + ", uid=" + Binder.getCallingUid()
3438                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3439            Slog.w(TAG, msg);
3440            throw new SecurityException(msg);
3441        }
3442        if (session == null || interactor == null) {
3443            throw new NullPointerException("null session or interactor");
3444        }
3445        userId = handleIncomingUser(callingPid, callingUid, userId,
3446                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3447        // TODO: Switch to user app stacks here.
3448        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3449                resolvedType, session, interactor, null, null, 0, startFlags,
3450                profileFile, profileFd, null, null, options, userId, null);
3451    }
3452
3453    @Override
3454    public boolean startNextMatchingActivity(IBinder callingActivity,
3455            Intent intent, Bundle options) {
3456        // Refuse possible leaked file descriptors
3457        if (intent != null && intent.hasFileDescriptors() == true) {
3458            throw new IllegalArgumentException("File descriptors passed in Intent");
3459        }
3460
3461        synchronized (this) {
3462            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3463            if (r == null) {
3464                ActivityOptions.abort(options);
3465                return false;
3466            }
3467            if (r.app == null || r.app.thread == null) {
3468                // The caller is not running...  d'oh!
3469                ActivityOptions.abort(options);
3470                return false;
3471            }
3472            intent = new Intent(intent);
3473            // The caller is not allowed to change the data.
3474            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3475            // And we are resetting to find the next component...
3476            intent.setComponent(null);
3477
3478            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3479
3480            ActivityInfo aInfo = null;
3481            try {
3482                List<ResolveInfo> resolves =
3483                    AppGlobals.getPackageManager().queryIntentActivities(
3484                            intent, r.resolvedType,
3485                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3486                            UserHandle.getCallingUserId());
3487
3488                // Look for the original activity in the list...
3489                final int N = resolves != null ? resolves.size() : 0;
3490                for (int i=0; i<N; i++) {
3491                    ResolveInfo rInfo = resolves.get(i);
3492                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3493                            && rInfo.activityInfo.name.equals(r.info.name)) {
3494                        // We found the current one...  the next matching is
3495                        // after it.
3496                        i++;
3497                        if (i<N) {
3498                            aInfo = resolves.get(i).activityInfo;
3499                        }
3500                        if (debug) {
3501                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3502                                    + "/" + r.info.name);
3503                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3504                                    + "/" + aInfo.name);
3505                        }
3506                        break;
3507                    }
3508                }
3509            } catch (RemoteException e) {
3510            }
3511
3512            if (aInfo == null) {
3513                // Nobody who is next!
3514                ActivityOptions.abort(options);
3515                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3516                return false;
3517            }
3518
3519            intent.setComponent(new ComponentName(
3520                    aInfo.applicationInfo.packageName, aInfo.name));
3521            intent.setFlags(intent.getFlags()&~(
3522                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3523                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3524                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3525                    Intent.FLAG_ACTIVITY_NEW_TASK));
3526
3527            // Okay now we need to start the new activity, replacing the
3528            // currently running activity.  This is a little tricky because
3529            // we want to start the new one as if the current one is finished,
3530            // but not finish the current one first so that there is no flicker.
3531            // And thus...
3532            final boolean wasFinishing = r.finishing;
3533            r.finishing = true;
3534
3535            // Propagate reply information over to the new activity.
3536            final ActivityRecord resultTo = r.resultTo;
3537            final String resultWho = r.resultWho;
3538            final int requestCode = r.requestCode;
3539            r.resultTo = null;
3540            if (resultTo != null) {
3541                resultTo.removeResultsLocked(r, resultWho, requestCode);
3542            }
3543
3544            final long origId = Binder.clearCallingIdentity();
3545            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3546                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3547                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3548                    options, false, null, null);
3549            Binder.restoreCallingIdentity(origId);
3550
3551            r.finishing = wasFinishing;
3552            if (res != ActivityManager.START_SUCCESS) {
3553                return false;
3554            }
3555            return true;
3556        }
3557    }
3558
3559    final int startActivityInPackage(int uid, String callingPackage,
3560            Intent intent, String resolvedType, IBinder resultTo,
3561            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3562                    IActivityContainer container) {
3563
3564        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3565                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3566
3567        // TODO: Switch to user app stacks here.
3568        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3569                null, null, resultTo, resultWho, requestCode, startFlags,
3570                null, null, null, null, options, userId, container);
3571        return ret;
3572    }
3573
3574    @Override
3575    public final int startActivities(IApplicationThread caller, String callingPackage,
3576            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3577            int userId) {
3578        enforceNotIsolatedCaller("startActivities");
3579        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3580                false, ALLOW_FULL_ONLY, "startActivity", null);
3581        // TODO: Switch to user app stacks here.
3582        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3583                resolvedTypes, resultTo, options, userId);
3584        return ret;
3585    }
3586
3587    final int startActivitiesInPackage(int uid, String callingPackage,
3588            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3589            Bundle options, int userId) {
3590
3591        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3592                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3593        // TODO: Switch to user app stacks here.
3594        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3595                resultTo, options, userId);
3596        return ret;
3597    }
3598
3599    final void addRecentTaskLocked(TaskRecord task) {
3600        int N = mRecentTasks.size();
3601        // Quick case: check if the top-most recent task is the same.
3602        if (N > 0 && mRecentTasks.get(0) == task) {
3603            return;
3604        }
3605        // Another quick case: never add voice sessions.
3606        if (task.voiceSession != null) {
3607            return;
3608        }
3609        // Remove any existing entries that are the same kind of task.
3610        final Intent intent = task.intent;
3611        final boolean document = intent != null && intent.isDocument();
3612        final ComponentName comp = intent.getComponent();
3613
3614        int maxRecents = task.maxRecents - 1;
3615        for (int i=0; i<N; i++) {
3616            final TaskRecord tr = mRecentTasks.get(i);
3617            if (task != tr) {
3618                if (task.userId != tr.userId) {
3619                    continue;
3620                }
3621                if (i > MAX_RECENT_BITMAPS) {
3622                    tr.freeLastThumbnail();
3623                }
3624                final Intent trIntent = tr.intent;
3625                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3626                    (intent == null || !intent.filterEquals(trIntent))) {
3627                    continue;
3628                }
3629                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3630                if (document && trIsDocument) {
3631                    // These are the same document activity (not necessarily the same doc).
3632                    if (maxRecents > 0) {
3633                        --maxRecents;
3634                        continue;
3635                    }
3636                    // Hit the maximum number of documents for this task. Fall through
3637                    // and remove this document from recents.
3638                } else if (document || trIsDocument) {
3639                    // Only one of these is a document. Not the droid we're looking for.
3640                    continue;
3641                }
3642            }
3643
3644            // Either task and tr are the same or, their affinities match or their intents match
3645            // and neither of them is a document, or they are documents using the same activity
3646            // and their maxRecents has been reached.
3647            tr.disposeThumbnail();
3648            mRecentTasks.remove(i);
3649            if (task != tr) {
3650                tr.closeRecentsChain();
3651            }
3652            i--;
3653            N--;
3654            if (task.intent == null) {
3655                // If the new recent task we are adding is not fully
3656                // specified, then replace it with the existing recent task.
3657                task = tr;
3658            }
3659            mTaskPersister.notify(tr, false);
3660        }
3661        if (N >= MAX_RECENT_TASKS) {
3662            final TaskRecord tr = mRecentTasks.remove(N - 1);
3663            tr.disposeThumbnail();
3664            tr.closeRecentsChain();
3665        }
3666        mRecentTasks.add(0, task);
3667    }
3668
3669    @Override
3670    public void reportActivityFullyDrawn(IBinder token) {
3671        synchronized (this) {
3672            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3673            if (r == null) {
3674                return;
3675            }
3676            r.reportFullyDrawnLocked();
3677        }
3678    }
3679
3680    @Override
3681    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3682        synchronized (this) {
3683            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3684            if (r == null) {
3685                return;
3686            }
3687            final long origId = Binder.clearCallingIdentity();
3688            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3689            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3690                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3691            if (config != null) {
3692                r.frozenBeforeDestroy = true;
3693                if (!updateConfigurationLocked(config, r, false, false)) {
3694                    mStackSupervisor.resumeTopActivitiesLocked();
3695                }
3696            }
3697            Binder.restoreCallingIdentity(origId);
3698        }
3699    }
3700
3701    @Override
3702    public int getRequestedOrientation(IBinder token) {
3703        synchronized (this) {
3704            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3705            if (r == null) {
3706                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3707            }
3708            return mWindowManager.getAppOrientation(r.appToken);
3709        }
3710    }
3711
3712    /**
3713     * This is the internal entry point for handling Activity.finish().
3714     *
3715     * @param token The Binder token referencing the Activity we want to finish.
3716     * @param resultCode Result code, if any, from this Activity.
3717     * @param resultData Result data (Intent), if any, from this Activity.
3718     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3719     *            the root Activity in the task.
3720     *
3721     * @return Returns true if the activity successfully finished, or false if it is still running.
3722     */
3723    @Override
3724    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3725            boolean finishTask) {
3726        // Refuse possible leaked file descriptors
3727        if (resultData != null && resultData.hasFileDescriptors() == true) {
3728            throw new IllegalArgumentException("File descriptors passed in Intent");
3729        }
3730
3731        synchronized(this) {
3732            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3733            if (r == null) {
3734                return true;
3735            }
3736            // Keep track of the root activity of the task before we finish it
3737            TaskRecord tr = r.task;
3738            ActivityRecord rootR = tr.getRootActivity();
3739            // Do not allow task to finish in Lock Task mode.
3740            if (tr == mStackSupervisor.mLockTaskModeTask) {
3741                if (rootR == r) {
3742                    mStackSupervisor.showLockTaskToast();
3743                    return false;
3744                }
3745            }
3746            if (mController != null) {
3747                // Find the first activity that is not finishing.
3748                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3749                if (next != null) {
3750                    // ask watcher if this is allowed
3751                    boolean resumeOK = true;
3752                    try {
3753                        resumeOK = mController.activityResuming(next.packageName);
3754                    } catch (RemoteException e) {
3755                        mController = null;
3756                        Watchdog.getInstance().setActivityController(null);
3757                    }
3758
3759                    if (!resumeOK) {
3760                        return false;
3761                    }
3762                }
3763            }
3764            final long origId = Binder.clearCallingIdentity();
3765            try {
3766                boolean res;
3767                if (finishTask && r == rootR) {
3768                    // If requested, remove the task that is associated to this activity only if it
3769                    // was the root activity in the task.  The result code and data is ignored because
3770                    // we don't support returning them across task boundaries.
3771                    res = removeTaskByIdLocked(tr.taskId, 0);
3772                } else {
3773                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3774                            resultData, "app-request", true);
3775                }
3776                return res;
3777            } finally {
3778                Binder.restoreCallingIdentity(origId);
3779            }
3780        }
3781    }
3782
3783    @Override
3784    public final void finishHeavyWeightApp() {
3785        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3786                != PackageManager.PERMISSION_GRANTED) {
3787            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3788                    + Binder.getCallingPid()
3789                    + ", uid=" + Binder.getCallingUid()
3790                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3791            Slog.w(TAG, msg);
3792            throw new SecurityException(msg);
3793        }
3794
3795        synchronized(this) {
3796            if (mHeavyWeightProcess == null) {
3797                return;
3798            }
3799
3800            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3801                    mHeavyWeightProcess.activities);
3802            for (int i=0; i<activities.size(); i++) {
3803                ActivityRecord r = activities.get(i);
3804                if (!r.finishing) {
3805                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3806                            null, "finish-heavy", true);
3807                }
3808            }
3809
3810            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3811                    mHeavyWeightProcess.userId, 0));
3812            mHeavyWeightProcess = null;
3813        }
3814    }
3815
3816    @Override
3817    public void crashApplication(int uid, int initialPid, String packageName,
3818            String message) {
3819        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3820                != PackageManager.PERMISSION_GRANTED) {
3821            String msg = "Permission Denial: crashApplication() from pid="
3822                    + Binder.getCallingPid()
3823                    + ", uid=" + Binder.getCallingUid()
3824                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3825            Slog.w(TAG, msg);
3826            throw new SecurityException(msg);
3827        }
3828
3829        synchronized(this) {
3830            ProcessRecord proc = null;
3831
3832            // Figure out which process to kill.  We don't trust that initialPid
3833            // still has any relation to current pids, so must scan through the
3834            // list.
3835            synchronized (mPidsSelfLocked) {
3836                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3837                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3838                    if (p.uid != uid) {
3839                        continue;
3840                    }
3841                    if (p.pid == initialPid) {
3842                        proc = p;
3843                        break;
3844                    }
3845                    if (p.pkgList.containsKey(packageName)) {
3846                        proc = p;
3847                    }
3848                }
3849            }
3850
3851            if (proc == null) {
3852                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3853                        + " initialPid=" + initialPid
3854                        + " packageName=" + packageName);
3855                return;
3856            }
3857
3858            if (proc.thread != null) {
3859                if (proc.pid == Process.myPid()) {
3860                    Log.w(TAG, "crashApplication: trying to crash self!");
3861                    return;
3862                }
3863                long ident = Binder.clearCallingIdentity();
3864                try {
3865                    proc.thread.scheduleCrash(message);
3866                } catch (RemoteException e) {
3867                }
3868                Binder.restoreCallingIdentity(ident);
3869            }
3870        }
3871    }
3872
3873    @Override
3874    public final void finishSubActivity(IBinder token, String resultWho,
3875            int requestCode) {
3876        synchronized(this) {
3877            final long origId = Binder.clearCallingIdentity();
3878            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3879            if (r != null) {
3880                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3881            }
3882            Binder.restoreCallingIdentity(origId);
3883        }
3884    }
3885
3886    @Override
3887    public boolean finishActivityAffinity(IBinder token) {
3888        synchronized(this) {
3889            final long origId = Binder.clearCallingIdentity();
3890            try {
3891                ActivityRecord r = ActivityRecord.isInStackLocked(token);
3892
3893                ActivityRecord rootR = r.task.getRootActivity();
3894                // Do not allow task to finish in Lock Task mode.
3895                if (r.task == mStackSupervisor.mLockTaskModeTask) {
3896                    if (rootR == r) {
3897                        mStackSupervisor.showLockTaskToast();
3898                        return false;
3899                    }
3900                }
3901                boolean res = false;
3902                if (r != null) {
3903                    res = r.task.stack.finishActivityAffinityLocked(r);
3904                }
3905                return res;
3906            } finally {
3907                Binder.restoreCallingIdentity(origId);
3908            }
3909        }
3910    }
3911
3912    @Override
3913    public void finishVoiceTask(IVoiceInteractionSession session) {
3914        synchronized(this) {
3915            final long origId = Binder.clearCallingIdentity();
3916            try {
3917                mStackSupervisor.finishVoiceTask(session);
3918            } finally {
3919                Binder.restoreCallingIdentity(origId);
3920            }
3921        }
3922
3923    }
3924
3925    @Override
3926    public boolean willActivityBeVisible(IBinder token) {
3927        synchronized(this) {
3928            ActivityStack stack = ActivityRecord.getStackLocked(token);
3929            if (stack != null) {
3930                return stack.willActivityBeVisibleLocked(token);
3931            }
3932            return false;
3933        }
3934    }
3935
3936    @Override
3937    public void overridePendingTransition(IBinder token, String packageName,
3938            int enterAnim, int exitAnim) {
3939        synchronized(this) {
3940            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3941            if (self == null) {
3942                return;
3943            }
3944
3945            final long origId = Binder.clearCallingIdentity();
3946
3947            if (self.state == ActivityState.RESUMED
3948                    || self.state == ActivityState.PAUSING) {
3949                mWindowManager.overridePendingAppTransition(packageName,
3950                        enterAnim, exitAnim, null);
3951            }
3952
3953            Binder.restoreCallingIdentity(origId);
3954        }
3955    }
3956
3957    /**
3958     * Main function for removing an existing process from the activity manager
3959     * as a result of that process going away.  Clears out all connections
3960     * to the process.
3961     */
3962    private final void handleAppDiedLocked(ProcessRecord app,
3963            boolean restarting, boolean allowRestart) {
3964        int pid = app.pid;
3965        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3966        if (!restarting) {
3967            removeLruProcessLocked(app);
3968            if (pid > 0) {
3969                ProcessList.remove(pid);
3970            }
3971        }
3972
3973        if (mProfileProc == app) {
3974            clearProfilerLocked();
3975        }
3976
3977        // Remove this application's activities from active lists.
3978        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3979
3980        app.activities.clear();
3981
3982        if (app.instrumentationClass != null) {
3983            Slog.w(TAG, "Crash of app " + app.processName
3984                  + " running instrumentation " + app.instrumentationClass);
3985            Bundle info = new Bundle();
3986            info.putString("shortMsg", "Process crashed.");
3987            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3988        }
3989
3990        if (!restarting) {
3991            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3992                // If there was nothing to resume, and we are not already
3993                // restarting this process, but there is a visible activity that
3994                // is hosted by the process...  then make sure all visible
3995                // activities are running, taking care of restarting this
3996                // process.
3997                if (hasVisibleActivities) {
3998                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3999                }
4000            }
4001        }
4002    }
4003
4004    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4005        IBinder threadBinder = thread.asBinder();
4006        // Find the application record.
4007        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4008            ProcessRecord rec = mLruProcesses.get(i);
4009            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4010                return i;
4011            }
4012        }
4013        return -1;
4014    }
4015
4016    final ProcessRecord getRecordForAppLocked(
4017            IApplicationThread thread) {
4018        if (thread == null) {
4019            return null;
4020        }
4021
4022        int appIndex = getLRURecordIndexForAppLocked(thread);
4023        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4024    }
4025
4026    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4027        // If there are no longer any background processes running,
4028        // and the app that died was not running instrumentation,
4029        // then tell everyone we are now low on memory.
4030        boolean haveBg = false;
4031        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4032            ProcessRecord rec = mLruProcesses.get(i);
4033            if (rec.thread != null
4034                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4035                haveBg = true;
4036                break;
4037            }
4038        }
4039
4040        if (!haveBg) {
4041            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4042            if (doReport) {
4043                long now = SystemClock.uptimeMillis();
4044                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4045                    doReport = false;
4046                } else {
4047                    mLastMemUsageReportTime = now;
4048                }
4049            }
4050            final ArrayList<ProcessMemInfo> memInfos
4051                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4052            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4053            long now = SystemClock.uptimeMillis();
4054            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4055                ProcessRecord rec = mLruProcesses.get(i);
4056                if (rec == dyingProc || rec.thread == null) {
4057                    continue;
4058                }
4059                if (doReport) {
4060                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4061                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4062                }
4063                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4064                    // The low memory report is overriding any current
4065                    // state for a GC request.  Make sure to do
4066                    // heavy/important/visible/foreground processes first.
4067                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4068                        rec.lastRequestedGc = 0;
4069                    } else {
4070                        rec.lastRequestedGc = rec.lastLowMemory;
4071                    }
4072                    rec.reportLowMemory = true;
4073                    rec.lastLowMemory = now;
4074                    mProcessesToGc.remove(rec);
4075                    addProcessToGcListLocked(rec);
4076                }
4077            }
4078            if (doReport) {
4079                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4080                mHandler.sendMessage(msg);
4081            }
4082            scheduleAppGcsLocked();
4083        }
4084    }
4085
4086    final void appDiedLocked(ProcessRecord app, int pid,
4087            IApplicationThread thread) {
4088
4089        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4090        synchronized (stats) {
4091            stats.noteProcessDiedLocked(app.info.uid, pid);
4092        }
4093
4094        Process.killProcessGroup(app.info.uid, pid);
4095
4096        // Clean up already done if the process has been re-started.
4097        if (app.pid == pid && app.thread != null &&
4098                app.thread.asBinder() == thread.asBinder()) {
4099            boolean doLowMem = app.instrumentationClass == null;
4100            boolean doOomAdj = doLowMem;
4101            if (!app.killedByAm) {
4102                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4103                        + ") has died.");
4104                mAllowLowerMemLevel = true;
4105            } else {
4106                // Note that we always want to do oom adj to update our state with the
4107                // new number of procs.
4108                mAllowLowerMemLevel = false;
4109                doLowMem = false;
4110            }
4111            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4112            if (DEBUG_CLEANUP) Slog.v(
4113                TAG, "Dying app: " + app + ", pid: " + pid
4114                + ", thread: " + thread.asBinder());
4115            handleAppDiedLocked(app, false, true);
4116
4117            if (doOomAdj) {
4118                updateOomAdjLocked();
4119            }
4120            if (doLowMem) {
4121                doLowMemReportIfNeededLocked(app);
4122            }
4123        } else if (app.pid != pid) {
4124            // A new process has already been started.
4125            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4126                    + ") has died and restarted (pid " + app.pid + ").");
4127            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4128        } else if (DEBUG_PROCESSES) {
4129            Slog.d(TAG, "Received spurious death notification for thread "
4130                    + thread.asBinder());
4131        }
4132    }
4133
4134    /**
4135     * If a stack trace dump file is configured, dump process stack traces.
4136     * @param clearTraces causes the dump file to be erased prior to the new
4137     *    traces being written, if true; when false, the new traces will be
4138     *    appended to any existing file content.
4139     * @param firstPids of dalvik VM processes to dump stack traces for first
4140     * @param lastPids of dalvik VM processes to dump stack traces for last
4141     * @param nativeProcs optional list of native process names to dump stack crawls
4142     * @return file containing stack traces, or null if no dump file is configured
4143     */
4144    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4145            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4146        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4147        if (tracesPath == null || tracesPath.length() == 0) {
4148            return null;
4149        }
4150
4151        File tracesFile = new File(tracesPath);
4152        try {
4153            File tracesDir = tracesFile.getParentFile();
4154            if (!tracesDir.exists()) {
4155                tracesFile.mkdirs();
4156                if (!SELinux.restorecon(tracesDir)) {
4157                    return null;
4158                }
4159            }
4160            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4161
4162            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4163            tracesFile.createNewFile();
4164            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4165        } catch (IOException e) {
4166            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4167            return null;
4168        }
4169
4170        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4171        return tracesFile;
4172    }
4173
4174    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4175            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4176        // Use a FileObserver to detect when traces finish writing.
4177        // The order of traces is considered important to maintain for legibility.
4178        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4179            @Override
4180            public synchronized void onEvent(int event, String path) { notify(); }
4181        };
4182
4183        try {
4184            observer.startWatching();
4185
4186            // First collect all of the stacks of the most important pids.
4187            if (firstPids != null) {
4188                try {
4189                    int num = firstPids.size();
4190                    for (int i = 0; i < num; i++) {
4191                        synchronized (observer) {
4192                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4193                            observer.wait(200);  // Wait for write-close, give up after 200msec
4194                        }
4195                    }
4196                } catch (InterruptedException e) {
4197                    Log.wtf(TAG, e);
4198                }
4199            }
4200
4201            // Next collect the stacks of the native pids
4202            if (nativeProcs != null) {
4203                int[] pids = Process.getPidsForCommands(nativeProcs);
4204                if (pids != null) {
4205                    for (int pid : pids) {
4206                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4207                    }
4208                }
4209            }
4210
4211            // Lastly, measure CPU usage.
4212            if (processCpuTracker != null) {
4213                processCpuTracker.init();
4214                System.gc();
4215                processCpuTracker.update();
4216                try {
4217                    synchronized (processCpuTracker) {
4218                        processCpuTracker.wait(500); // measure over 1/2 second.
4219                    }
4220                } catch (InterruptedException e) {
4221                }
4222                processCpuTracker.update();
4223
4224                // We'll take the stack crawls of just the top apps using CPU.
4225                final int N = processCpuTracker.countWorkingStats();
4226                int numProcs = 0;
4227                for (int i=0; i<N && numProcs<5; i++) {
4228                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4229                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4230                        numProcs++;
4231                        try {
4232                            synchronized (observer) {
4233                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4234                                observer.wait(200);  // Wait for write-close, give up after 200msec
4235                            }
4236                        } catch (InterruptedException e) {
4237                            Log.wtf(TAG, e);
4238                        }
4239
4240                    }
4241                }
4242            }
4243        } finally {
4244            observer.stopWatching();
4245        }
4246    }
4247
4248    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4249        if (true || IS_USER_BUILD) {
4250            return;
4251        }
4252        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4253        if (tracesPath == null || tracesPath.length() == 0) {
4254            return;
4255        }
4256
4257        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4258        StrictMode.allowThreadDiskWrites();
4259        try {
4260            final File tracesFile = new File(tracesPath);
4261            final File tracesDir = tracesFile.getParentFile();
4262            final File tracesTmp = new File(tracesDir, "__tmp__");
4263            try {
4264                if (!tracesDir.exists()) {
4265                    tracesFile.mkdirs();
4266                    if (!SELinux.restorecon(tracesDir.getPath())) {
4267                        return;
4268                    }
4269                }
4270                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4271
4272                if (tracesFile.exists()) {
4273                    tracesTmp.delete();
4274                    tracesFile.renameTo(tracesTmp);
4275                }
4276                StringBuilder sb = new StringBuilder();
4277                Time tobj = new Time();
4278                tobj.set(System.currentTimeMillis());
4279                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4280                sb.append(": ");
4281                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4282                sb.append(" since ");
4283                sb.append(msg);
4284                FileOutputStream fos = new FileOutputStream(tracesFile);
4285                fos.write(sb.toString().getBytes());
4286                if (app == null) {
4287                    fos.write("\n*** No application process!".getBytes());
4288                }
4289                fos.close();
4290                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4291            } catch (IOException e) {
4292                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4293                return;
4294            }
4295
4296            if (app != null) {
4297                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4298                firstPids.add(app.pid);
4299                dumpStackTraces(tracesPath, firstPids, null, null, null);
4300            }
4301
4302            File lastTracesFile = null;
4303            File curTracesFile = null;
4304            for (int i=9; i>=0; i--) {
4305                String name = String.format(Locale.US, "slow%02d.txt", i);
4306                curTracesFile = new File(tracesDir, name);
4307                if (curTracesFile.exists()) {
4308                    if (lastTracesFile != null) {
4309                        curTracesFile.renameTo(lastTracesFile);
4310                    } else {
4311                        curTracesFile.delete();
4312                    }
4313                }
4314                lastTracesFile = curTracesFile;
4315            }
4316            tracesFile.renameTo(curTracesFile);
4317            if (tracesTmp.exists()) {
4318                tracesTmp.renameTo(tracesFile);
4319            }
4320        } finally {
4321            StrictMode.setThreadPolicy(oldPolicy);
4322        }
4323    }
4324
4325    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4326            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4327        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4328        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4329
4330        if (mController != null) {
4331            try {
4332                // 0 == continue, -1 = kill process immediately
4333                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4334                if (res < 0 && app.pid != MY_PID) {
4335                    Process.killProcess(app.pid);
4336                    Process.killProcessGroup(app.info.uid, app.pid);
4337                }
4338            } catch (RemoteException e) {
4339                mController = null;
4340                Watchdog.getInstance().setActivityController(null);
4341            }
4342        }
4343
4344        long anrTime = SystemClock.uptimeMillis();
4345        if (MONITOR_CPU_USAGE) {
4346            updateCpuStatsNow();
4347        }
4348
4349        synchronized (this) {
4350            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4351            if (mShuttingDown) {
4352                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4353                return;
4354            } else if (app.notResponding) {
4355                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4356                return;
4357            } else if (app.crashing) {
4358                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4359                return;
4360            }
4361
4362            // In case we come through here for the same app before completing
4363            // this one, mark as anring now so we will bail out.
4364            app.notResponding = true;
4365
4366            // Log the ANR to the event log.
4367            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4368                    app.processName, app.info.flags, annotation);
4369
4370            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4371            firstPids.add(app.pid);
4372
4373            int parentPid = app.pid;
4374            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4375            if (parentPid != app.pid) firstPids.add(parentPid);
4376
4377            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4378
4379            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4380                ProcessRecord r = mLruProcesses.get(i);
4381                if (r != null && r.thread != null) {
4382                    int pid = r.pid;
4383                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4384                        if (r.persistent) {
4385                            firstPids.add(pid);
4386                        } else {
4387                            lastPids.put(pid, Boolean.TRUE);
4388                        }
4389                    }
4390                }
4391            }
4392        }
4393
4394        // Log the ANR to the main log.
4395        StringBuilder info = new StringBuilder();
4396        info.setLength(0);
4397        info.append("ANR in ").append(app.processName);
4398        if (activity != null && activity.shortComponentName != null) {
4399            info.append(" (").append(activity.shortComponentName).append(")");
4400        }
4401        info.append("\n");
4402        info.append("PID: ").append(app.pid).append("\n");
4403        if (annotation != null) {
4404            info.append("Reason: ").append(annotation).append("\n");
4405        }
4406        if (parent != null && parent != activity) {
4407            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4408        }
4409
4410        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4411
4412        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4413                NATIVE_STACKS_OF_INTEREST);
4414
4415        String cpuInfo = null;
4416        if (MONITOR_CPU_USAGE) {
4417            updateCpuStatsNow();
4418            synchronized (mProcessCpuThread) {
4419                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4420            }
4421            info.append(processCpuTracker.printCurrentLoad());
4422            info.append(cpuInfo);
4423        }
4424
4425        info.append(processCpuTracker.printCurrentState(anrTime));
4426
4427        Slog.e(TAG, info.toString());
4428        if (tracesFile == null) {
4429            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4430            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4431        }
4432
4433        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4434                cpuInfo, tracesFile, null);
4435
4436        if (mController != null) {
4437            try {
4438                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4439                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4440                if (res != 0) {
4441                    if (res < 0 && app.pid != MY_PID) {
4442                        Process.killProcess(app.pid);
4443                        Process.killProcessGroup(app.info.uid, app.pid);
4444                    } else {
4445                        synchronized (this) {
4446                            mServices.scheduleServiceTimeoutLocked(app);
4447                        }
4448                    }
4449                    return;
4450                }
4451            } catch (RemoteException e) {
4452                mController = null;
4453                Watchdog.getInstance().setActivityController(null);
4454            }
4455        }
4456
4457        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4458        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4459                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4460
4461        synchronized (this) {
4462            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4463                killUnneededProcessLocked(app, "background ANR");
4464                return;
4465            }
4466
4467            // Set the app's notResponding state, and look up the errorReportReceiver
4468            makeAppNotRespondingLocked(app,
4469                    activity != null ? activity.shortComponentName : null,
4470                    annotation != null ? "ANR " + annotation : "ANR",
4471                    info.toString());
4472
4473            // Bring up the infamous App Not Responding dialog
4474            Message msg = Message.obtain();
4475            HashMap<String, Object> map = new HashMap<String, Object>();
4476            msg.what = SHOW_NOT_RESPONDING_MSG;
4477            msg.obj = map;
4478            msg.arg1 = aboveSystem ? 1 : 0;
4479            map.put("app", app);
4480            if (activity != null) {
4481                map.put("activity", activity);
4482            }
4483
4484            mHandler.sendMessage(msg);
4485        }
4486    }
4487
4488    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4489        if (!mLaunchWarningShown) {
4490            mLaunchWarningShown = true;
4491            mHandler.post(new Runnable() {
4492                @Override
4493                public void run() {
4494                    synchronized (ActivityManagerService.this) {
4495                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4496                        d.show();
4497                        mHandler.postDelayed(new Runnable() {
4498                            @Override
4499                            public void run() {
4500                                synchronized (ActivityManagerService.this) {
4501                                    d.dismiss();
4502                                    mLaunchWarningShown = false;
4503                                }
4504                            }
4505                        }, 4000);
4506                    }
4507                }
4508            });
4509        }
4510    }
4511
4512    @Override
4513    public boolean clearApplicationUserData(final String packageName,
4514            final IPackageDataObserver observer, int userId) {
4515        enforceNotIsolatedCaller("clearApplicationUserData");
4516        int uid = Binder.getCallingUid();
4517        int pid = Binder.getCallingPid();
4518        userId = handleIncomingUser(pid, uid,
4519                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4520        long callingId = Binder.clearCallingIdentity();
4521        try {
4522            IPackageManager pm = AppGlobals.getPackageManager();
4523            int pkgUid = -1;
4524            synchronized(this) {
4525                try {
4526                    pkgUid = pm.getPackageUid(packageName, userId);
4527                } catch (RemoteException e) {
4528                }
4529                if (pkgUid == -1) {
4530                    Slog.w(TAG, "Invalid packageName: " + packageName);
4531                    if (observer != null) {
4532                        try {
4533                            observer.onRemoveCompleted(packageName, false);
4534                        } catch (RemoteException e) {
4535                            Slog.i(TAG, "Observer no longer exists.");
4536                        }
4537                    }
4538                    return false;
4539                }
4540                if (uid == pkgUid || checkComponentPermission(
4541                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4542                        pid, uid, -1, true)
4543                        == PackageManager.PERMISSION_GRANTED) {
4544                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4545                } else {
4546                    throw new SecurityException("PID " + pid + " does not have permission "
4547                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4548                                    + " of package " + packageName);
4549                }
4550            }
4551
4552            try {
4553                // Clear application user data
4554                pm.clearApplicationUserData(packageName, observer, userId);
4555
4556                // Remove all permissions granted from/to this package
4557                removeUriPermissionsForPackageLocked(packageName, userId, true);
4558
4559                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4560                        Uri.fromParts("package", packageName, null));
4561                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4562                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4563                        null, null, 0, null, null, null, false, false, userId);
4564            } catch (RemoteException e) {
4565            }
4566        } finally {
4567            Binder.restoreCallingIdentity(callingId);
4568        }
4569        return true;
4570    }
4571
4572    @Override
4573    public void killBackgroundProcesses(final String packageName, int userId) {
4574        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4575                != PackageManager.PERMISSION_GRANTED &&
4576                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4577                        != PackageManager.PERMISSION_GRANTED) {
4578            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4579                    + Binder.getCallingPid()
4580                    + ", uid=" + Binder.getCallingUid()
4581                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4582            Slog.w(TAG, msg);
4583            throw new SecurityException(msg);
4584        }
4585
4586        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4587                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4588        long callingId = Binder.clearCallingIdentity();
4589        try {
4590            IPackageManager pm = AppGlobals.getPackageManager();
4591            synchronized(this) {
4592                int appId = -1;
4593                try {
4594                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4595                } catch (RemoteException e) {
4596                }
4597                if (appId == -1) {
4598                    Slog.w(TAG, "Invalid packageName: " + packageName);
4599                    return;
4600                }
4601                killPackageProcessesLocked(packageName, appId, userId,
4602                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4603            }
4604        } finally {
4605            Binder.restoreCallingIdentity(callingId);
4606        }
4607    }
4608
4609    @Override
4610    public void killAllBackgroundProcesses() {
4611        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4612                != PackageManager.PERMISSION_GRANTED) {
4613            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4614                    + Binder.getCallingPid()
4615                    + ", uid=" + Binder.getCallingUid()
4616                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4617            Slog.w(TAG, msg);
4618            throw new SecurityException(msg);
4619        }
4620
4621        long callingId = Binder.clearCallingIdentity();
4622        try {
4623            synchronized(this) {
4624                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4625                final int NP = mProcessNames.getMap().size();
4626                for (int ip=0; ip<NP; ip++) {
4627                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4628                    final int NA = apps.size();
4629                    for (int ia=0; ia<NA; ia++) {
4630                        ProcessRecord app = apps.valueAt(ia);
4631                        if (app.persistent) {
4632                            // we don't kill persistent processes
4633                            continue;
4634                        }
4635                        if (app.removed) {
4636                            procs.add(app);
4637                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4638                            app.removed = true;
4639                            procs.add(app);
4640                        }
4641                    }
4642                }
4643
4644                int N = procs.size();
4645                for (int i=0; i<N; i++) {
4646                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4647                }
4648                mAllowLowerMemLevel = true;
4649                updateOomAdjLocked();
4650                doLowMemReportIfNeededLocked(null);
4651            }
4652        } finally {
4653            Binder.restoreCallingIdentity(callingId);
4654        }
4655    }
4656
4657    @Override
4658    public void forceStopPackage(final String packageName, int userId) {
4659        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4660                != PackageManager.PERMISSION_GRANTED) {
4661            String msg = "Permission Denial: forceStopPackage() from pid="
4662                    + Binder.getCallingPid()
4663                    + ", uid=" + Binder.getCallingUid()
4664                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4665            Slog.w(TAG, msg);
4666            throw new SecurityException(msg);
4667        }
4668        final int callingPid = Binder.getCallingPid();
4669        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4670                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4671        long callingId = Binder.clearCallingIdentity();
4672        try {
4673            IPackageManager pm = AppGlobals.getPackageManager();
4674            synchronized(this) {
4675                int[] users = userId == UserHandle.USER_ALL
4676                        ? getUsersLocked() : new int[] { userId };
4677                for (int user : users) {
4678                    int pkgUid = -1;
4679                    try {
4680                        pkgUid = pm.getPackageUid(packageName, user);
4681                    } catch (RemoteException e) {
4682                    }
4683                    if (pkgUid == -1) {
4684                        Slog.w(TAG, "Invalid packageName: " + packageName);
4685                        continue;
4686                    }
4687                    try {
4688                        pm.setPackageStoppedState(packageName, true, user);
4689                    } catch (RemoteException e) {
4690                    } catch (IllegalArgumentException e) {
4691                        Slog.w(TAG, "Failed trying to unstop package "
4692                                + packageName + ": " + e);
4693                    }
4694                    if (isUserRunningLocked(user, false)) {
4695                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4696                    }
4697                }
4698            }
4699        } finally {
4700            Binder.restoreCallingIdentity(callingId);
4701        }
4702    }
4703
4704    /*
4705     * The pkg name and app id have to be specified.
4706     */
4707    @Override
4708    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4709        if (pkg == null) {
4710            return;
4711        }
4712        // Make sure the uid is valid.
4713        if (appid < 0) {
4714            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4715            return;
4716        }
4717        int callerUid = Binder.getCallingUid();
4718        // Only the system server can kill an application
4719        if (callerUid == Process.SYSTEM_UID) {
4720            // Post an aysnc message to kill the application
4721            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4722            msg.arg1 = appid;
4723            msg.arg2 = 0;
4724            Bundle bundle = new Bundle();
4725            bundle.putString("pkg", pkg);
4726            bundle.putString("reason", reason);
4727            msg.obj = bundle;
4728            mHandler.sendMessage(msg);
4729        } else {
4730            throw new SecurityException(callerUid + " cannot kill pkg: " +
4731                    pkg);
4732        }
4733    }
4734
4735    @Override
4736    public void closeSystemDialogs(String reason) {
4737        enforceNotIsolatedCaller("closeSystemDialogs");
4738
4739        final int pid = Binder.getCallingPid();
4740        final int uid = Binder.getCallingUid();
4741        final long origId = Binder.clearCallingIdentity();
4742        try {
4743            synchronized (this) {
4744                // Only allow this from foreground processes, so that background
4745                // applications can't abuse it to prevent system UI from being shown.
4746                if (uid >= Process.FIRST_APPLICATION_UID) {
4747                    ProcessRecord proc;
4748                    synchronized (mPidsSelfLocked) {
4749                        proc = mPidsSelfLocked.get(pid);
4750                    }
4751                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4752                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4753                                + " from background process " + proc);
4754                        return;
4755                    }
4756                }
4757                closeSystemDialogsLocked(reason);
4758            }
4759        } finally {
4760            Binder.restoreCallingIdentity(origId);
4761        }
4762    }
4763
4764    void closeSystemDialogsLocked(String reason) {
4765        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4766        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4767                | Intent.FLAG_RECEIVER_FOREGROUND);
4768        if (reason != null) {
4769            intent.putExtra("reason", reason);
4770        }
4771        mWindowManager.closeSystemDialogs(reason);
4772
4773        mStackSupervisor.closeSystemDialogsLocked();
4774
4775        broadcastIntentLocked(null, null, intent, null,
4776                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4777                Process.SYSTEM_UID, UserHandle.USER_ALL);
4778    }
4779
4780    @Override
4781    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4782        enforceNotIsolatedCaller("getProcessMemoryInfo");
4783        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4784        for (int i=pids.length-1; i>=0; i--) {
4785            ProcessRecord proc;
4786            int oomAdj;
4787            synchronized (this) {
4788                synchronized (mPidsSelfLocked) {
4789                    proc = mPidsSelfLocked.get(pids[i]);
4790                    oomAdj = proc != null ? proc.setAdj : 0;
4791                }
4792            }
4793            infos[i] = new Debug.MemoryInfo();
4794            Debug.getMemoryInfo(pids[i], infos[i]);
4795            if (proc != null) {
4796                synchronized (this) {
4797                    if (proc.thread != null && proc.setAdj == oomAdj) {
4798                        // Record this for posterity if the process has been stable.
4799                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4800                                infos[i].getTotalUss(), false, proc.pkgList);
4801                    }
4802                }
4803            }
4804        }
4805        return infos;
4806    }
4807
4808    @Override
4809    public long[] getProcessPss(int[] pids) {
4810        enforceNotIsolatedCaller("getProcessPss");
4811        long[] pss = new long[pids.length];
4812        for (int i=pids.length-1; i>=0; i--) {
4813            ProcessRecord proc;
4814            int oomAdj;
4815            synchronized (this) {
4816                synchronized (mPidsSelfLocked) {
4817                    proc = mPidsSelfLocked.get(pids[i]);
4818                    oomAdj = proc != null ? proc.setAdj : 0;
4819                }
4820            }
4821            long[] tmpUss = new long[1];
4822            pss[i] = Debug.getPss(pids[i], tmpUss);
4823            if (proc != null) {
4824                synchronized (this) {
4825                    if (proc.thread != null && proc.setAdj == oomAdj) {
4826                        // Record this for posterity if the process has been stable.
4827                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4828                    }
4829                }
4830            }
4831        }
4832        return pss;
4833    }
4834
4835    @Override
4836    public void killApplicationProcess(String processName, int uid) {
4837        if (processName == null) {
4838            return;
4839        }
4840
4841        int callerUid = Binder.getCallingUid();
4842        // Only the system server can kill an application
4843        if (callerUid == Process.SYSTEM_UID) {
4844            synchronized (this) {
4845                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4846                if (app != null && app.thread != null) {
4847                    try {
4848                        app.thread.scheduleSuicide();
4849                    } catch (RemoteException e) {
4850                        // If the other end already died, then our work here is done.
4851                    }
4852                } else {
4853                    Slog.w(TAG, "Process/uid not found attempting kill of "
4854                            + processName + " / " + uid);
4855                }
4856            }
4857        } else {
4858            throw new SecurityException(callerUid + " cannot kill app process: " +
4859                    processName);
4860        }
4861    }
4862
4863    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4864        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4865                false, true, false, false, UserHandle.getUserId(uid), reason);
4866        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4867                Uri.fromParts("package", packageName, null));
4868        if (!mProcessesReady) {
4869            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4870                    | Intent.FLAG_RECEIVER_FOREGROUND);
4871        }
4872        intent.putExtra(Intent.EXTRA_UID, uid);
4873        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4874        broadcastIntentLocked(null, null, intent,
4875                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4876                false, false,
4877                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4878    }
4879
4880    private void forceStopUserLocked(int userId, String reason) {
4881        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4882        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4883        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4884                | Intent.FLAG_RECEIVER_FOREGROUND);
4885        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4886        broadcastIntentLocked(null, null, intent,
4887                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4888                false, false,
4889                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4890    }
4891
4892    private final boolean killPackageProcessesLocked(String packageName, int appId,
4893            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4894            boolean doit, boolean evenPersistent, String reason) {
4895        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4896
4897        // Remove all processes this package may have touched: all with the
4898        // same UID (except for the system or root user), and all whose name
4899        // matches the package name.
4900        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4901        final int NP = mProcessNames.getMap().size();
4902        for (int ip=0; ip<NP; ip++) {
4903            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4904            final int NA = apps.size();
4905            for (int ia=0; ia<NA; ia++) {
4906                ProcessRecord app = apps.valueAt(ia);
4907                if (app.persistent && !evenPersistent) {
4908                    // we don't kill persistent processes
4909                    continue;
4910                }
4911                if (app.removed) {
4912                    if (doit) {
4913                        procs.add(app);
4914                    }
4915                    continue;
4916                }
4917
4918                // Skip process if it doesn't meet our oom adj requirement.
4919                if (app.setAdj < minOomAdj) {
4920                    continue;
4921                }
4922
4923                // If no package is specified, we call all processes under the
4924                // give user id.
4925                if (packageName == null) {
4926                    if (app.userId != userId) {
4927                        continue;
4928                    }
4929                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4930                        continue;
4931                    }
4932                // Package has been specified, we want to hit all processes
4933                // that match it.  We need to qualify this by the processes
4934                // that are running under the specified app and user ID.
4935                } else {
4936                    if (UserHandle.getAppId(app.uid) != appId) {
4937                        continue;
4938                    }
4939                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4940                        continue;
4941                    }
4942                    if (!app.pkgList.containsKey(packageName)) {
4943                        continue;
4944                    }
4945                }
4946
4947                // Process has passed all conditions, kill it!
4948                if (!doit) {
4949                    return true;
4950                }
4951                app.removed = true;
4952                procs.add(app);
4953            }
4954        }
4955
4956        int N = procs.size();
4957        for (int i=0; i<N; i++) {
4958            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4959        }
4960        updateOomAdjLocked();
4961        return N > 0;
4962    }
4963
4964    private final boolean forceStopPackageLocked(String name, int appId,
4965            boolean callerWillRestart, boolean purgeCache, boolean doit,
4966            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4967        int i;
4968        int N;
4969
4970        if (userId == UserHandle.USER_ALL && name == null) {
4971            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4972        }
4973
4974        if (appId < 0 && name != null) {
4975            try {
4976                appId = UserHandle.getAppId(
4977                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4978            } catch (RemoteException e) {
4979            }
4980        }
4981
4982        if (doit) {
4983            if (name != null) {
4984                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4985                        + " user=" + userId + ": " + reason);
4986            } else {
4987                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4988            }
4989
4990            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4991            for (int ip=pmap.size()-1; ip>=0; ip--) {
4992                SparseArray<Long> ba = pmap.valueAt(ip);
4993                for (i=ba.size()-1; i>=0; i--) {
4994                    boolean remove = false;
4995                    final int entUid = ba.keyAt(i);
4996                    if (name != null) {
4997                        if (userId == UserHandle.USER_ALL) {
4998                            if (UserHandle.getAppId(entUid) == appId) {
4999                                remove = true;
5000                            }
5001                        } else {
5002                            if (entUid == UserHandle.getUid(userId, appId)) {
5003                                remove = true;
5004                            }
5005                        }
5006                    } else if (UserHandle.getUserId(entUid) == userId) {
5007                        remove = true;
5008                    }
5009                    if (remove) {
5010                        ba.removeAt(i);
5011                    }
5012                }
5013                if (ba.size() == 0) {
5014                    pmap.removeAt(ip);
5015                }
5016            }
5017        }
5018
5019        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5020                -100, callerWillRestart, true, doit, evenPersistent,
5021                name == null ? ("stop user " + userId) : ("stop " + name));
5022
5023        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5024            if (!doit) {
5025                return true;
5026            }
5027            didSomething = true;
5028        }
5029
5030        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5031            if (!doit) {
5032                return true;
5033            }
5034            didSomething = true;
5035        }
5036
5037        if (name == null) {
5038            // Remove all sticky broadcasts from this user.
5039            mStickyBroadcasts.remove(userId);
5040        }
5041
5042        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5043        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5044                userId, providers)) {
5045            if (!doit) {
5046                return true;
5047            }
5048            didSomething = true;
5049        }
5050        N = providers.size();
5051        for (i=0; i<N; i++) {
5052            removeDyingProviderLocked(null, providers.get(i), true);
5053        }
5054
5055        // Remove transient permissions granted from/to this package/user
5056        removeUriPermissionsForPackageLocked(name, userId, false);
5057
5058        if (name == null || uninstalling) {
5059            // Remove pending intents.  For now we only do this when force
5060            // stopping users, because we have some problems when doing this
5061            // for packages -- app widgets are not currently cleaned up for
5062            // such packages, so they can be left with bad pending intents.
5063            if (mIntentSenderRecords.size() > 0) {
5064                Iterator<WeakReference<PendingIntentRecord>> it
5065                        = mIntentSenderRecords.values().iterator();
5066                while (it.hasNext()) {
5067                    WeakReference<PendingIntentRecord> wpir = it.next();
5068                    if (wpir == null) {
5069                        it.remove();
5070                        continue;
5071                    }
5072                    PendingIntentRecord pir = wpir.get();
5073                    if (pir == null) {
5074                        it.remove();
5075                        continue;
5076                    }
5077                    if (name == null) {
5078                        // Stopping user, remove all objects for the user.
5079                        if (pir.key.userId != userId) {
5080                            // Not the same user, skip it.
5081                            continue;
5082                        }
5083                    } else {
5084                        if (UserHandle.getAppId(pir.uid) != appId) {
5085                            // Different app id, skip it.
5086                            continue;
5087                        }
5088                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5089                            // Different user, skip it.
5090                            continue;
5091                        }
5092                        if (!pir.key.packageName.equals(name)) {
5093                            // Different package, skip it.
5094                            continue;
5095                        }
5096                    }
5097                    if (!doit) {
5098                        return true;
5099                    }
5100                    didSomething = true;
5101                    it.remove();
5102                    pir.canceled = true;
5103                    if (pir.key.activity != null) {
5104                        pir.key.activity.pendingResults.remove(pir.ref);
5105                    }
5106                }
5107            }
5108        }
5109
5110        if (doit) {
5111            if (purgeCache && name != null) {
5112                AttributeCache ac = AttributeCache.instance();
5113                if (ac != null) {
5114                    ac.removePackage(name);
5115                }
5116            }
5117            if (mBooted) {
5118                mStackSupervisor.resumeTopActivitiesLocked();
5119                mStackSupervisor.scheduleIdleLocked();
5120            }
5121        }
5122
5123        return didSomething;
5124    }
5125
5126    private final boolean removeProcessLocked(ProcessRecord app,
5127            boolean callerWillRestart, boolean allowRestart, String reason) {
5128        final String name = app.processName;
5129        final int uid = app.uid;
5130        if (DEBUG_PROCESSES) Slog.d(
5131            TAG, "Force removing proc " + app.toShortString() + " (" + name
5132            + "/" + uid + ")");
5133
5134        mProcessNames.remove(name, uid);
5135        mIsolatedProcesses.remove(app.uid);
5136        if (mHeavyWeightProcess == app) {
5137            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5138                    mHeavyWeightProcess.userId, 0));
5139            mHeavyWeightProcess = null;
5140        }
5141        boolean needRestart = false;
5142        if (app.pid > 0 && app.pid != MY_PID) {
5143            int pid = app.pid;
5144            synchronized (mPidsSelfLocked) {
5145                mPidsSelfLocked.remove(pid);
5146                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5147            }
5148            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5149            if (app.isolated) {
5150                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5151            }
5152            killUnneededProcessLocked(app, reason);
5153            Process.killProcessGroup(app.info.uid, app.pid);
5154            handleAppDiedLocked(app, true, allowRestart);
5155            removeLruProcessLocked(app);
5156
5157            if (app.persistent && !app.isolated) {
5158                if (!callerWillRestart) {
5159                    addAppLocked(app.info, false, null /* ABI override */);
5160                } else {
5161                    needRestart = true;
5162                }
5163            }
5164        } else {
5165            mRemovedProcesses.add(app);
5166        }
5167
5168        return needRestart;
5169    }
5170
5171    private final void processStartTimedOutLocked(ProcessRecord app) {
5172        final int pid = app.pid;
5173        boolean gone = false;
5174        synchronized (mPidsSelfLocked) {
5175            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5176            if (knownApp != null && knownApp.thread == null) {
5177                mPidsSelfLocked.remove(pid);
5178                gone = true;
5179            }
5180        }
5181
5182        if (gone) {
5183            Slog.w(TAG, "Process " + app + " failed to attach");
5184            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5185                    pid, app.uid, app.processName);
5186            mProcessNames.remove(app.processName, app.uid);
5187            mIsolatedProcesses.remove(app.uid);
5188            if (mHeavyWeightProcess == app) {
5189                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5190                        mHeavyWeightProcess.userId, 0));
5191                mHeavyWeightProcess = null;
5192            }
5193            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5194            if (app.isolated) {
5195                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5196            }
5197            // Take care of any launching providers waiting for this process.
5198            checkAppInLaunchingProvidersLocked(app, true);
5199            // Take care of any services that are waiting for the process.
5200            mServices.processStartTimedOutLocked(app);
5201            killUnneededProcessLocked(app, "start timeout");
5202            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5203                Slog.w(TAG, "Unattached app died before backup, skipping");
5204                try {
5205                    IBackupManager bm = IBackupManager.Stub.asInterface(
5206                            ServiceManager.getService(Context.BACKUP_SERVICE));
5207                    bm.agentDisconnected(app.info.packageName);
5208                } catch (RemoteException e) {
5209                    // Can't happen; the backup manager is local
5210                }
5211            }
5212            if (isPendingBroadcastProcessLocked(pid)) {
5213                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5214                skipPendingBroadcastLocked(pid);
5215            }
5216        } else {
5217            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5218        }
5219    }
5220
5221    private final boolean attachApplicationLocked(IApplicationThread thread,
5222            int pid) {
5223
5224        // Find the application record that is being attached...  either via
5225        // the pid if we are running in multiple processes, or just pull the
5226        // next app record if we are emulating process with anonymous threads.
5227        ProcessRecord app;
5228        if (pid != MY_PID && pid >= 0) {
5229            synchronized (mPidsSelfLocked) {
5230                app = mPidsSelfLocked.get(pid);
5231            }
5232        } else {
5233            app = null;
5234        }
5235
5236        if (app == null) {
5237            Slog.w(TAG, "No pending application record for pid " + pid
5238                    + " (IApplicationThread " + thread + "); dropping process");
5239            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5240            if (pid > 0 && pid != MY_PID) {
5241                Process.killProcessQuiet(pid);
5242                //TODO: Process.killProcessGroup(app.info.uid, pid);
5243            } else {
5244                try {
5245                    thread.scheduleExit();
5246                } catch (Exception e) {
5247                    // Ignore exceptions.
5248                }
5249            }
5250            return false;
5251        }
5252
5253        // If this application record is still attached to a previous
5254        // process, clean it up now.
5255        if (app.thread != null) {
5256            handleAppDiedLocked(app, true, true);
5257        }
5258
5259        // Tell the process all about itself.
5260
5261        if (localLOGV) Slog.v(
5262                TAG, "Binding process pid " + pid + " to record " + app);
5263
5264        final String processName = app.processName;
5265        try {
5266            AppDeathRecipient adr = new AppDeathRecipient(
5267                    app, pid, thread);
5268            thread.asBinder().linkToDeath(adr, 0);
5269            app.deathRecipient = adr;
5270        } catch (RemoteException e) {
5271            app.resetPackageList(mProcessStats);
5272            startProcessLocked(app, "link fail", processName, null /* ABI override */);
5273            return false;
5274        }
5275
5276        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5277
5278        app.makeActive(thread, mProcessStats);
5279        app.curAdj = app.setAdj = -100;
5280        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5281        app.forcingToForeground = null;
5282        updateProcessForegroundLocked(app, false, false);
5283        app.hasShownUi = false;
5284        app.debugging = false;
5285        app.cached = false;
5286
5287        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5288
5289        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5290        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5291
5292        if (!normalMode) {
5293            Slog.i(TAG, "Launching preboot mode app: " + app);
5294        }
5295
5296        if (localLOGV) Slog.v(
5297            TAG, "New app record " + app
5298            + " thread=" + thread.asBinder() + " pid=" + pid);
5299        try {
5300            int testMode = IApplicationThread.DEBUG_OFF;
5301            if (mDebugApp != null && mDebugApp.equals(processName)) {
5302                testMode = mWaitForDebugger
5303                    ? IApplicationThread.DEBUG_WAIT
5304                    : IApplicationThread.DEBUG_ON;
5305                app.debugging = true;
5306                if (mDebugTransient) {
5307                    mDebugApp = mOrigDebugApp;
5308                    mWaitForDebugger = mOrigWaitForDebugger;
5309                }
5310            }
5311            String profileFile = app.instrumentationProfileFile;
5312            ParcelFileDescriptor profileFd = null;
5313            boolean profileAutoStop = false;
5314            if (mProfileApp != null && mProfileApp.equals(processName)) {
5315                mProfileProc = app;
5316                profileFile = mProfileFile;
5317                profileFd = mProfileFd;
5318                profileAutoStop = mAutoStopProfiler;
5319            }
5320            boolean enableOpenGlTrace = false;
5321            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5322                enableOpenGlTrace = true;
5323                mOpenGlTraceApp = null;
5324            }
5325
5326            // If the app is being launched for restore or full backup, set it up specially
5327            boolean isRestrictedBackupMode = false;
5328            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5329                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5330                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5331                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5332            }
5333
5334            ensurePackageDexOpt(app.instrumentationInfo != null
5335                    ? app.instrumentationInfo.packageName
5336                    : app.info.packageName);
5337            if (app.instrumentationClass != null) {
5338                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5339            }
5340            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5341                    + processName + " with config " + mConfiguration);
5342            ApplicationInfo appInfo = app.instrumentationInfo != null
5343                    ? app.instrumentationInfo : app.info;
5344            app.compat = compatibilityInfoForPackageLocked(appInfo);
5345            if (profileFd != null) {
5346                profileFd = profileFd.dup();
5347            }
5348            thread.bindApplication(processName, appInfo, providers,
5349                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5350                    app.instrumentationArguments, app.instrumentationWatcher,
5351                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5352                    isRestrictedBackupMode || !normalMode, app.persistent,
5353                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5354                    mCoreSettingsObserver.getCoreSettingsLocked());
5355            updateLruProcessLocked(app, false, null);
5356            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5357        } catch (Exception e) {
5358            // todo: Yikes!  What should we do?  For now we will try to
5359            // start another process, but that could easily get us in
5360            // an infinite loop of restarting processes...
5361            Slog.w(TAG, "Exception thrown during bind!", e);
5362
5363            app.resetPackageList(mProcessStats);
5364            app.unlinkDeathRecipient();
5365            startProcessLocked(app, "bind fail", processName, null /* ABI override */);
5366            return false;
5367        }
5368
5369        // Remove this record from the list of starting applications.
5370        mPersistentStartingProcesses.remove(app);
5371        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5372                "Attach application locked removing on hold: " + app);
5373        mProcessesOnHold.remove(app);
5374
5375        boolean badApp = false;
5376        boolean didSomething = false;
5377
5378        // See if the top visible activity is waiting to run in this process...
5379        if (normalMode) {
5380            try {
5381                if (mStackSupervisor.attachApplicationLocked(app)) {
5382                    didSomething = true;
5383                }
5384            } catch (Exception e) {
5385                badApp = true;
5386            }
5387        }
5388
5389        // Find any services that should be running in this process...
5390        if (!badApp) {
5391            try {
5392                didSomething |= mServices.attachApplicationLocked(app, processName);
5393            } catch (Exception e) {
5394                badApp = true;
5395            }
5396        }
5397
5398        // Check if a next-broadcast receiver is in this process...
5399        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5400            try {
5401                didSomething |= sendPendingBroadcastsLocked(app);
5402            } catch (Exception e) {
5403                // If the app died trying to launch the receiver we declare it 'bad'
5404                badApp = true;
5405            }
5406        }
5407
5408        // Check whether the next backup agent is in this process...
5409        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5410            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5411            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5412            try {
5413                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5414                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5415                        mBackupTarget.backupMode);
5416            } catch (Exception e) {
5417                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5418                e.printStackTrace();
5419            }
5420        }
5421
5422        if (badApp) {
5423            // todo: Also need to kill application to deal with all
5424            // kinds of exceptions.
5425            handleAppDiedLocked(app, false, true);
5426            return false;
5427        }
5428
5429        if (!didSomething) {
5430            updateOomAdjLocked();
5431        }
5432
5433        return true;
5434    }
5435
5436    @Override
5437    public final void attachApplication(IApplicationThread thread) {
5438        synchronized (this) {
5439            int callingPid = Binder.getCallingPid();
5440            final long origId = Binder.clearCallingIdentity();
5441            attachApplicationLocked(thread, callingPid);
5442            Binder.restoreCallingIdentity(origId);
5443        }
5444    }
5445
5446    @Override
5447    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5448        final long origId = Binder.clearCallingIdentity();
5449        synchronized (this) {
5450            ActivityStack stack = ActivityRecord.getStackLocked(token);
5451            if (stack != null) {
5452                ActivityRecord r =
5453                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5454                if (stopProfiling) {
5455                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5456                        try {
5457                            mProfileFd.close();
5458                        } catch (IOException e) {
5459                        }
5460                        clearProfilerLocked();
5461                    }
5462                }
5463            }
5464        }
5465        Binder.restoreCallingIdentity(origId);
5466    }
5467
5468    void enableScreenAfterBoot() {
5469        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5470                SystemClock.uptimeMillis());
5471        mWindowManager.enableScreenAfterBoot();
5472
5473        synchronized (this) {
5474            updateEventDispatchingLocked();
5475        }
5476    }
5477
5478    @Override
5479    public void showBootMessage(final CharSequence msg, final boolean always) {
5480        enforceNotIsolatedCaller("showBootMessage");
5481        mWindowManager.showBootMessage(msg, always);
5482    }
5483
5484    @Override
5485    public void dismissKeyguardOnNextActivity() {
5486        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5487        final long token = Binder.clearCallingIdentity();
5488        try {
5489            synchronized (this) {
5490                if (DEBUG_LOCKSCREEN) logLockScreen("");
5491                if (mLockScreenShown) {
5492                    mLockScreenShown = false;
5493                    comeOutOfSleepIfNeededLocked();
5494                }
5495                mStackSupervisor.setDismissKeyguard(true);
5496            }
5497        } finally {
5498            Binder.restoreCallingIdentity(token);
5499        }
5500    }
5501
5502    final void finishBooting() {
5503        // Register receivers to handle package update events
5504        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5505
5506        synchronized (this) {
5507            // Ensure that any processes we had put on hold are now started
5508            // up.
5509            final int NP = mProcessesOnHold.size();
5510            if (NP > 0) {
5511                ArrayList<ProcessRecord> procs =
5512                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5513                for (int ip=0; ip<NP; ip++) {
5514                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5515                            + procs.get(ip));
5516                    startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */);
5517                }
5518            }
5519
5520            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5521                // Start looking for apps that are abusing wake locks.
5522                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5523                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5524                // Tell anyone interested that we are done booting!
5525                SystemProperties.set("sys.boot_completed", "1");
5526                SystemProperties.set("dev.bootcomplete", "1");
5527                for (int i=0; i<mStartedUsers.size(); i++) {
5528                    UserStartedState uss = mStartedUsers.valueAt(i);
5529                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5530                        uss.mState = UserStartedState.STATE_RUNNING;
5531                        final int userId = mStartedUsers.keyAt(i);
5532                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5533                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5534                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5535                        broadcastIntentLocked(null, null, intent, null,
5536                                new IIntentReceiver.Stub() {
5537                                    @Override
5538                                    public void performReceive(Intent intent, int resultCode,
5539                                            String data, Bundle extras, boolean ordered,
5540                                            boolean sticky, int sendingUser) {
5541                                        synchronized (ActivityManagerService.this) {
5542                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5543                                                    true, false);
5544                                        }
5545                                    }
5546                                },
5547                                0, null, null,
5548                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5549                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5550                                userId);
5551                    }
5552                }
5553                scheduleStartProfilesLocked();
5554            }
5555        }
5556    }
5557
5558    final void ensureBootCompleted() {
5559        boolean booting;
5560        boolean enableScreen;
5561        synchronized (this) {
5562            booting = mBooting;
5563            mBooting = false;
5564            enableScreen = !mBooted;
5565            mBooted = true;
5566        }
5567
5568        if (booting) {
5569            finishBooting();
5570        }
5571
5572        if (enableScreen) {
5573            enableScreenAfterBoot();
5574        }
5575    }
5576
5577    @Override
5578    public final void activityResumed(IBinder token) {
5579        final long origId = Binder.clearCallingIdentity();
5580        synchronized(this) {
5581            ActivityStack stack = ActivityRecord.getStackLocked(token);
5582            if (stack != null) {
5583                ActivityRecord.activityResumedLocked(token);
5584            }
5585        }
5586        Binder.restoreCallingIdentity(origId);
5587    }
5588
5589    @Override
5590    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5591        final long origId = Binder.clearCallingIdentity();
5592        synchronized(this) {
5593            ActivityStack stack = ActivityRecord.getStackLocked(token);
5594            if (stack != null) {
5595                stack.activityPausedLocked(token, false, persistentState);
5596            }
5597        }
5598        Binder.restoreCallingIdentity(origId);
5599    }
5600
5601    @Override
5602    public final void activityStopped(IBinder token, Bundle icicle,
5603            PersistableBundle persistentState, CharSequence description) {
5604        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5605
5606        // Refuse possible leaked file descriptors
5607        if (icicle != null && icicle.hasFileDescriptors()) {
5608            throw new IllegalArgumentException("File descriptors passed in Bundle");
5609        }
5610
5611        final long origId = Binder.clearCallingIdentity();
5612
5613        synchronized (this) {
5614            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5615            if (r != null) {
5616                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5617            }
5618        }
5619
5620        trimApplications();
5621
5622        Binder.restoreCallingIdentity(origId);
5623    }
5624
5625    @Override
5626    public final void activityDestroyed(IBinder token) {
5627        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5628        synchronized (this) {
5629            ActivityStack stack = ActivityRecord.getStackLocked(token);
5630            if (stack != null) {
5631                stack.activityDestroyedLocked(token);
5632            }
5633        }
5634    }
5635
5636    @Override
5637    public final void mediaResourcesReleased(IBinder token) {
5638        final long origId = Binder.clearCallingIdentity();
5639        try {
5640            synchronized (this) {
5641                ActivityStack stack = ActivityRecord.getStackLocked(token);
5642                if (stack != null) {
5643                    stack.mediaResourcesReleased(token);
5644                }
5645            }
5646        } finally {
5647            Binder.restoreCallingIdentity(origId);
5648        }
5649    }
5650
5651    @Override
5652    public String getCallingPackage(IBinder token) {
5653        synchronized (this) {
5654            ActivityRecord r = getCallingRecordLocked(token);
5655            return r != null ? r.info.packageName : null;
5656        }
5657    }
5658
5659    @Override
5660    public ComponentName getCallingActivity(IBinder token) {
5661        synchronized (this) {
5662            ActivityRecord r = getCallingRecordLocked(token);
5663            return r != null ? r.intent.getComponent() : null;
5664        }
5665    }
5666
5667    private ActivityRecord getCallingRecordLocked(IBinder token) {
5668        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5669        if (r == null) {
5670            return null;
5671        }
5672        return r.resultTo;
5673    }
5674
5675    @Override
5676    public ComponentName getActivityClassForToken(IBinder token) {
5677        synchronized(this) {
5678            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5679            if (r == null) {
5680                return null;
5681            }
5682            return r.intent.getComponent();
5683        }
5684    }
5685
5686    @Override
5687    public String getPackageForToken(IBinder token) {
5688        synchronized(this) {
5689            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5690            if (r == null) {
5691                return null;
5692            }
5693            return r.packageName;
5694        }
5695    }
5696
5697    @Override
5698    public IIntentSender getIntentSender(int type,
5699            String packageName, IBinder token, String resultWho,
5700            int requestCode, Intent[] intents, String[] resolvedTypes,
5701            int flags, Bundle options, int userId) {
5702        enforceNotIsolatedCaller("getIntentSender");
5703        // Refuse possible leaked file descriptors
5704        if (intents != null) {
5705            if (intents.length < 1) {
5706                throw new IllegalArgumentException("Intents array length must be >= 1");
5707            }
5708            for (int i=0; i<intents.length; i++) {
5709                Intent intent = intents[i];
5710                if (intent != null) {
5711                    if (intent.hasFileDescriptors()) {
5712                        throw new IllegalArgumentException("File descriptors passed in Intent");
5713                    }
5714                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5715                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5716                        throw new IllegalArgumentException(
5717                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5718                    }
5719                    intents[i] = new Intent(intent);
5720                }
5721            }
5722            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5723                throw new IllegalArgumentException(
5724                        "Intent array length does not match resolvedTypes length");
5725            }
5726        }
5727        if (options != null) {
5728            if (options.hasFileDescriptors()) {
5729                throw new IllegalArgumentException("File descriptors passed in options");
5730            }
5731        }
5732
5733        synchronized(this) {
5734            int callingUid = Binder.getCallingUid();
5735            int origUserId = userId;
5736            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5737                    type == ActivityManager.INTENT_SENDER_BROADCAST,
5738                    ALLOW_NON_FULL, "getIntentSender", null);
5739            if (origUserId == UserHandle.USER_CURRENT) {
5740                // We don't want to evaluate this until the pending intent is
5741                // actually executed.  However, we do want to always do the
5742                // security checking for it above.
5743                userId = UserHandle.USER_CURRENT;
5744            }
5745            try {
5746                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5747                    int uid = AppGlobals.getPackageManager()
5748                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5749                    if (!UserHandle.isSameApp(callingUid, uid)) {
5750                        String msg = "Permission Denial: getIntentSender() from pid="
5751                            + Binder.getCallingPid()
5752                            + ", uid=" + Binder.getCallingUid()
5753                            + ", (need uid=" + uid + ")"
5754                            + " is not allowed to send as package " + packageName;
5755                        Slog.w(TAG, msg);
5756                        throw new SecurityException(msg);
5757                    }
5758                }
5759
5760                return getIntentSenderLocked(type, packageName, callingUid, userId,
5761                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5762
5763            } catch (RemoteException e) {
5764                throw new SecurityException(e);
5765            }
5766        }
5767    }
5768
5769    IIntentSender getIntentSenderLocked(int type, String packageName,
5770            int callingUid, int userId, IBinder token, String resultWho,
5771            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5772            Bundle options) {
5773        if (DEBUG_MU)
5774            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5775        ActivityRecord activity = null;
5776        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5777            activity = ActivityRecord.isInStackLocked(token);
5778            if (activity == null) {
5779                return null;
5780            }
5781            if (activity.finishing) {
5782                return null;
5783            }
5784        }
5785
5786        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5787        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5788        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5789        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5790                |PendingIntent.FLAG_UPDATE_CURRENT);
5791
5792        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5793                type, packageName, activity, resultWho,
5794                requestCode, intents, resolvedTypes, flags, options, userId);
5795        WeakReference<PendingIntentRecord> ref;
5796        ref = mIntentSenderRecords.get(key);
5797        PendingIntentRecord rec = ref != null ? ref.get() : null;
5798        if (rec != null) {
5799            if (!cancelCurrent) {
5800                if (updateCurrent) {
5801                    if (rec.key.requestIntent != null) {
5802                        rec.key.requestIntent.replaceExtras(intents != null ?
5803                                intents[intents.length - 1] : null);
5804                    }
5805                    if (intents != null) {
5806                        intents[intents.length-1] = rec.key.requestIntent;
5807                        rec.key.allIntents = intents;
5808                        rec.key.allResolvedTypes = resolvedTypes;
5809                    } else {
5810                        rec.key.allIntents = null;
5811                        rec.key.allResolvedTypes = null;
5812                    }
5813                }
5814                return rec;
5815            }
5816            rec.canceled = true;
5817            mIntentSenderRecords.remove(key);
5818        }
5819        if (noCreate) {
5820            return rec;
5821        }
5822        rec = new PendingIntentRecord(this, key, callingUid);
5823        mIntentSenderRecords.put(key, rec.ref);
5824        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5825            if (activity.pendingResults == null) {
5826                activity.pendingResults
5827                        = new HashSet<WeakReference<PendingIntentRecord>>();
5828            }
5829            activity.pendingResults.add(rec.ref);
5830        }
5831        return rec;
5832    }
5833
5834    @Override
5835    public void cancelIntentSender(IIntentSender sender) {
5836        if (!(sender instanceof PendingIntentRecord)) {
5837            return;
5838        }
5839        synchronized(this) {
5840            PendingIntentRecord rec = (PendingIntentRecord)sender;
5841            try {
5842                int uid = AppGlobals.getPackageManager()
5843                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5844                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5845                    String msg = "Permission Denial: cancelIntentSender() from pid="
5846                        + Binder.getCallingPid()
5847                        + ", uid=" + Binder.getCallingUid()
5848                        + " is not allowed to cancel packges "
5849                        + rec.key.packageName;
5850                    Slog.w(TAG, msg);
5851                    throw new SecurityException(msg);
5852                }
5853            } catch (RemoteException e) {
5854                throw new SecurityException(e);
5855            }
5856            cancelIntentSenderLocked(rec, true);
5857        }
5858    }
5859
5860    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5861        rec.canceled = true;
5862        mIntentSenderRecords.remove(rec.key);
5863        if (cleanActivity && rec.key.activity != null) {
5864            rec.key.activity.pendingResults.remove(rec.ref);
5865        }
5866    }
5867
5868    @Override
5869    public String getPackageForIntentSender(IIntentSender pendingResult) {
5870        if (!(pendingResult instanceof PendingIntentRecord)) {
5871            return null;
5872        }
5873        try {
5874            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5875            return res.key.packageName;
5876        } catch (ClassCastException e) {
5877        }
5878        return null;
5879    }
5880
5881    @Override
5882    public int getUidForIntentSender(IIntentSender sender) {
5883        if (sender instanceof PendingIntentRecord) {
5884            try {
5885                PendingIntentRecord res = (PendingIntentRecord)sender;
5886                return res.uid;
5887            } catch (ClassCastException e) {
5888            }
5889        }
5890        return -1;
5891    }
5892
5893    @Override
5894    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5895        if (!(pendingResult instanceof PendingIntentRecord)) {
5896            return false;
5897        }
5898        try {
5899            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5900            if (res.key.allIntents == null) {
5901                return false;
5902            }
5903            for (int i=0; i<res.key.allIntents.length; i++) {
5904                Intent intent = res.key.allIntents[i];
5905                if (intent.getPackage() != null && intent.getComponent() != null) {
5906                    return false;
5907                }
5908            }
5909            return true;
5910        } catch (ClassCastException e) {
5911        }
5912        return false;
5913    }
5914
5915    @Override
5916    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5917        if (!(pendingResult instanceof PendingIntentRecord)) {
5918            return false;
5919        }
5920        try {
5921            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5922            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5923                return true;
5924            }
5925            return false;
5926        } catch (ClassCastException e) {
5927        }
5928        return false;
5929    }
5930
5931    @Override
5932    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5933        if (!(pendingResult instanceof PendingIntentRecord)) {
5934            return null;
5935        }
5936        try {
5937            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5938            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5939        } catch (ClassCastException e) {
5940        }
5941        return null;
5942    }
5943
5944    @Override
5945    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5946        if (!(pendingResult instanceof PendingIntentRecord)) {
5947            return null;
5948        }
5949        try {
5950            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5951            Intent intent = res.key.requestIntent;
5952            if (intent != null) {
5953                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5954                        || res.lastTagPrefix.equals(prefix))) {
5955                    return res.lastTag;
5956                }
5957                res.lastTagPrefix = prefix;
5958                StringBuilder sb = new StringBuilder(128);
5959                if (prefix != null) {
5960                    sb.append(prefix);
5961                }
5962                if (intent.getAction() != null) {
5963                    sb.append(intent.getAction());
5964                } else if (intent.getComponent() != null) {
5965                    intent.getComponent().appendShortString(sb);
5966                } else {
5967                    sb.append("?");
5968                }
5969                return res.lastTag = sb.toString();
5970            }
5971        } catch (ClassCastException e) {
5972        }
5973        return null;
5974    }
5975
5976    @Override
5977    public void setProcessLimit(int max) {
5978        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5979                "setProcessLimit()");
5980        synchronized (this) {
5981            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5982            mProcessLimitOverride = max;
5983        }
5984        trimApplications();
5985    }
5986
5987    @Override
5988    public int getProcessLimit() {
5989        synchronized (this) {
5990            return mProcessLimitOverride;
5991        }
5992    }
5993
5994    void foregroundTokenDied(ForegroundToken token) {
5995        synchronized (ActivityManagerService.this) {
5996            synchronized (mPidsSelfLocked) {
5997                ForegroundToken cur
5998                    = mForegroundProcesses.get(token.pid);
5999                if (cur != token) {
6000                    return;
6001                }
6002                mForegroundProcesses.remove(token.pid);
6003                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6004                if (pr == null) {
6005                    return;
6006                }
6007                pr.forcingToForeground = null;
6008                updateProcessForegroundLocked(pr, false, false);
6009            }
6010            updateOomAdjLocked();
6011        }
6012    }
6013
6014    @Override
6015    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6016        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6017                "setProcessForeground()");
6018        synchronized(this) {
6019            boolean changed = false;
6020
6021            synchronized (mPidsSelfLocked) {
6022                ProcessRecord pr = mPidsSelfLocked.get(pid);
6023                if (pr == null && isForeground) {
6024                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6025                    return;
6026                }
6027                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6028                if (oldToken != null) {
6029                    oldToken.token.unlinkToDeath(oldToken, 0);
6030                    mForegroundProcesses.remove(pid);
6031                    if (pr != null) {
6032                        pr.forcingToForeground = null;
6033                    }
6034                    changed = true;
6035                }
6036                if (isForeground && token != null) {
6037                    ForegroundToken newToken = new ForegroundToken() {
6038                        @Override
6039                        public void binderDied() {
6040                            foregroundTokenDied(this);
6041                        }
6042                    };
6043                    newToken.pid = pid;
6044                    newToken.token = token;
6045                    try {
6046                        token.linkToDeath(newToken, 0);
6047                        mForegroundProcesses.put(pid, newToken);
6048                        pr.forcingToForeground = token;
6049                        changed = true;
6050                    } catch (RemoteException e) {
6051                        // If the process died while doing this, we will later
6052                        // do the cleanup with the process death link.
6053                    }
6054                }
6055            }
6056
6057            if (changed) {
6058                updateOomAdjLocked();
6059            }
6060        }
6061    }
6062
6063    // =========================================================
6064    // PERMISSIONS
6065    // =========================================================
6066
6067    static class PermissionController extends IPermissionController.Stub {
6068        ActivityManagerService mActivityManagerService;
6069        PermissionController(ActivityManagerService activityManagerService) {
6070            mActivityManagerService = activityManagerService;
6071        }
6072
6073        @Override
6074        public boolean checkPermission(String permission, int pid, int uid) {
6075            return mActivityManagerService.checkPermission(permission, pid,
6076                    uid) == PackageManager.PERMISSION_GRANTED;
6077        }
6078    }
6079
6080    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6081        @Override
6082        public int checkComponentPermission(String permission, int pid, int uid,
6083                int owningUid, boolean exported) {
6084            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6085                    owningUid, exported);
6086        }
6087
6088        @Override
6089        public Object getAMSLock() {
6090            return ActivityManagerService.this;
6091        }
6092    }
6093
6094    /**
6095     * This can be called with or without the global lock held.
6096     */
6097    int checkComponentPermission(String permission, int pid, int uid,
6098            int owningUid, boolean exported) {
6099        // We might be performing an operation on behalf of an indirect binder
6100        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6101        // client identity accordingly before proceeding.
6102        Identity tlsIdentity = sCallerIdentity.get();
6103        if (tlsIdentity != null) {
6104            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6105                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6106            uid = tlsIdentity.uid;
6107            pid = tlsIdentity.pid;
6108        }
6109
6110        if (pid == MY_PID) {
6111            return PackageManager.PERMISSION_GRANTED;
6112        }
6113
6114        return ActivityManager.checkComponentPermission(permission, uid,
6115                owningUid, exported);
6116    }
6117
6118    /**
6119     * As the only public entry point for permissions checking, this method
6120     * can enforce the semantic that requesting a check on a null global
6121     * permission is automatically denied.  (Internally a null permission
6122     * string is used when calling {@link #checkComponentPermission} in cases
6123     * when only uid-based security is needed.)
6124     *
6125     * This can be called with or without the global lock held.
6126     */
6127    @Override
6128    public int checkPermission(String permission, int pid, int uid) {
6129        if (permission == null) {
6130            return PackageManager.PERMISSION_DENIED;
6131        }
6132        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6133    }
6134
6135    /**
6136     * Binder IPC calls go through the public entry point.
6137     * This can be called with or without the global lock held.
6138     */
6139    int checkCallingPermission(String permission) {
6140        return checkPermission(permission,
6141                Binder.getCallingPid(),
6142                UserHandle.getAppId(Binder.getCallingUid()));
6143    }
6144
6145    /**
6146     * This can be called with or without the global lock held.
6147     */
6148    void enforceCallingPermission(String permission, String func) {
6149        if (checkCallingPermission(permission)
6150                == PackageManager.PERMISSION_GRANTED) {
6151            return;
6152        }
6153
6154        String msg = "Permission Denial: " + func + " from pid="
6155                + Binder.getCallingPid()
6156                + ", uid=" + Binder.getCallingUid()
6157                + " requires " + permission;
6158        Slog.w(TAG, msg);
6159        throw new SecurityException(msg);
6160    }
6161
6162    /**
6163     * Determine if UID is holding permissions required to access {@link Uri} in
6164     * the given {@link ProviderInfo}. Final permission checking is always done
6165     * in {@link ContentProvider}.
6166     */
6167    private final boolean checkHoldingPermissionsLocked(
6168            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6169        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6170                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6171        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6172            return false;
6173        }
6174        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6175    }
6176
6177    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6178            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6179        if (pi.applicationInfo.uid == uid) {
6180            return true;
6181        } else if (!pi.exported) {
6182            return false;
6183        }
6184
6185        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6186        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6187        try {
6188            // check if target holds top-level <provider> permissions
6189            if (!readMet && pi.readPermission != null && considerUidPermissions
6190                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6191                readMet = true;
6192            }
6193            if (!writeMet && pi.writePermission != null && considerUidPermissions
6194                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6195                writeMet = true;
6196            }
6197
6198            // track if unprotected read/write is allowed; any denied
6199            // <path-permission> below removes this ability
6200            boolean allowDefaultRead = pi.readPermission == null;
6201            boolean allowDefaultWrite = pi.writePermission == null;
6202
6203            // check if target holds any <path-permission> that match uri
6204            final PathPermission[] pps = pi.pathPermissions;
6205            if (pps != null) {
6206                final String path = grantUri.uri.getPath();
6207                int i = pps.length;
6208                while (i > 0 && (!readMet || !writeMet)) {
6209                    i--;
6210                    PathPermission pp = pps[i];
6211                    if (pp.match(path)) {
6212                        if (!readMet) {
6213                            final String pprperm = pp.getReadPermission();
6214                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6215                                    + pprperm + " for " + pp.getPath()
6216                                    + ": match=" + pp.match(path)
6217                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6218                            if (pprperm != null) {
6219                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6220                                        == PERMISSION_GRANTED) {
6221                                    readMet = true;
6222                                } else {
6223                                    allowDefaultRead = false;
6224                                }
6225                            }
6226                        }
6227                        if (!writeMet) {
6228                            final String ppwperm = pp.getWritePermission();
6229                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6230                                    + ppwperm + " for " + pp.getPath()
6231                                    + ": match=" + pp.match(path)
6232                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6233                            if (ppwperm != null) {
6234                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6235                                        == PERMISSION_GRANTED) {
6236                                    writeMet = true;
6237                                } else {
6238                                    allowDefaultWrite = false;
6239                                }
6240                            }
6241                        }
6242                    }
6243                }
6244            }
6245
6246            // grant unprotected <provider> read/write, if not blocked by
6247            // <path-permission> above
6248            if (allowDefaultRead) readMet = true;
6249            if (allowDefaultWrite) writeMet = true;
6250
6251        } catch (RemoteException e) {
6252            return false;
6253        }
6254
6255        return readMet && writeMet;
6256    }
6257
6258    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6259        ProviderInfo pi = null;
6260        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6261        if (cpr != null) {
6262            pi = cpr.info;
6263        } else {
6264            try {
6265                pi = AppGlobals.getPackageManager().resolveContentProvider(
6266                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6267            } catch (RemoteException ex) {
6268            }
6269        }
6270        return pi;
6271    }
6272
6273    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6274        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6275        if (targetUris != null) {
6276            return targetUris.get(grantUri);
6277        }
6278        return null;
6279    }
6280
6281    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6282            String targetPkg, int targetUid, GrantUri grantUri) {
6283        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6284        if (targetUris == null) {
6285            targetUris = Maps.newArrayMap();
6286            mGrantedUriPermissions.put(targetUid, targetUris);
6287        }
6288
6289        UriPermission perm = targetUris.get(grantUri);
6290        if (perm == null) {
6291            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6292            targetUris.put(grantUri, perm);
6293        }
6294
6295        return perm;
6296    }
6297
6298    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6299            final int modeFlags) {
6300        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6301        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6302                : UriPermission.STRENGTH_OWNED;
6303
6304        // Root gets to do everything.
6305        if (uid == 0) {
6306            return true;
6307        }
6308
6309        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6310        if (perms == null) return false;
6311
6312        // First look for exact match
6313        final UriPermission exactPerm = perms.get(grantUri);
6314        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6315            return true;
6316        }
6317
6318        // No exact match, look for prefixes
6319        final int N = perms.size();
6320        for (int i = 0; i < N; i++) {
6321            final UriPermission perm = perms.valueAt(i);
6322            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6323                    && perm.getStrength(modeFlags) >= minStrength) {
6324                return true;
6325            }
6326        }
6327
6328        return false;
6329    }
6330
6331    @Override
6332    public int checkUriPermission(Uri uri, int pid, int uid,
6333            final int modeFlags, int userId) {
6334        enforceNotIsolatedCaller("checkUriPermission");
6335
6336        // Another redirected-binder-call permissions check as in
6337        // {@link checkComponentPermission}.
6338        Identity tlsIdentity = sCallerIdentity.get();
6339        if (tlsIdentity != null) {
6340            uid = tlsIdentity.uid;
6341            pid = tlsIdentity.pid;
6342        }
6343
6344        // Our own process gets to do everything.
6345        if (pid == MY_PID) {
6346            return PackageManager.PERMISSION_GRANTED;
6347        }
6348        synchronized (this) {
6349            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6350                    ? PackageManager.PERMISSION_GRANTED
6351                    : PackageManager.PERMISSION_DENIED;
6352        }
6353    }
6354
6355    /**
6356     * Check if the targetPkg can be granted permission to access uri by
6357     * the callingUid using the given modeFlags.  Throws a security exception
6358     * if callingUid is not allowed to do this.  Returns the uid of the target
6359     * if the URI permission grant should be performed; returns -1 if it is not
6360     * needed (for example targetPkg already has permission to access the URI).
6361     * If you already know the uid of the target, you can supply it in
6362     * lastTargetUid else set that to -1.
6363     */
6364    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6365            final int modeFlags, int lastTargetUid) {
6366        if (!Intent.isAccessUriMode(modeFlags)) {
6367            return -1;
6368        }
6369
6370        if (targetPkg != null) {
6371            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6372                    "Checking grant " + targetPkg + " permission to " + grantUri);
6373        }
6374
6375        final IPackageManager pm = AppGlobals.getPackageManager();
6376
6377        // If this is not a content: uri, we can't do anything with it.
6378        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6379            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6380                    "Can't grant URI permission for non-content URI: " + grantUri);
6381            return -1;
6382        }
6383
6384        final String authority = grantUri.uri.getAuthority();
6385        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6386        if (pi == null) {
6387            Slog.w(TAG, "No content provider found for permission check: " +
6388                    grantUri.uri.toSafeString());
6389            return -1;
6390        }
6391
6392        int targetUid = lastTargetUid;
6393        if (targetUid < 0 && targetPkg != null) {
6394            try {
6395                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6396                if (targetUid < 0) {
6397                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6398                            "Can't grant URI permission no uid for: " + targetPkg);
6399                    return -1;
6400                }
6401            } catch (RemoteException ex) {
6402                return -1;
6403            }
6404        }
6405
6406        if (targetUid >= 0) {
6407            // First...  does the target actually need this permission?
6408            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6409                // No need to grant the target this permission.
6410                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6411                        "Target " + targetPkg + " already has full permission to " + grantUri);
6412                return -1;
6413            }
6414        } else {
6415            // First...  there is no target package, so can anyone access it?
6416            boolean allowed = pi.exported;
6417            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6418                if (pi.readPermission != null) {
6419                    allowed = false;
6420                }
6421            }
6422            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6423                if (pi.writePermission != null) {
6424                    allowed = false;
6425                }
6426            }
6427            if (allowed) {
6428                return -1;
6429            }
6430        }
6431
6432        /* There is a special cross user grant if:
6433         * - The target is on another user.
6434         * - Apps on the current user can access the uri without any uid permissions.
6435         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6436         * grant uri permissions.
6437         */
6438        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6439                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6440                modeFlags, false /*without considering the uid permissions*/);
6441
6442        // Second...  is the provider allowing granting of URI permissions?
6443        if (!specialCrossUserGrant) {
6444            if (!pi.grantUriPermissions) {
6445                throw new SecurityException("Provider " + pi.packageName
6446                        + "/" + pi.name
6447                        + " does not allow granting of Uri permissions (uri "
6448                        + grantUri + ")");
6449            }
6450            if (pi.uriPermissionPatterns != null) {
6451                final int N = pi.uriPermissionPatterns.length;
6452                boolean allowed = false;
6453                for (int i=0; i<N; i++) {
6454                    if (pi.uriPermissionPatterns[i] != null
6455                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6456                        allowed = true;
6457                        break;
6458                    }
6459                }
6460                if (!allowed) {
6461                    throw new SecurityException("Provider " + pi.packageName
6462                            + "/" + pi.name
6463                            + " does not allow granting of permission to path of Uri "
6464                            + grantUri);
6465                }
6466            }
6467        }
6468
6469        // Third...  does the caller itself have permission to access
6470        // this uri?
6471        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6472            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6473                // Require they hold a strong enough Uri permission
6474                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6475                    throw new SecurityException("Uid " + callingUid
6476                            + " does not have permission to uri " + grantUri);
6477                }
6478            }
6479        }
6480        return targetUid;
6481    }
6482
6483    @Override
6484    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6485            final int modeFlags, int userId) {
6486        enforceNotIsolatedCaller("checkGrantUriPermission");
6487        synchronized(this) {
6488            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6489                    new GrantUri(userId, uri, false), modeFlags, -1);
6490        }
6491    }
6492
6493    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6494            final int modeFlags, UriPermissionOwner owner) {
6495        if (!Intent.isAccessUriMode(modeFlags)) {
6496            return;
6497        }
6498
6499        // So here we are: the caller has the assumed permission
6500        // to the uri, and the target doesn't.  Let's now give this to
6501        // the target.
6502
6503        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6504                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6505
6506        final String authority = grantUri.uri.getAuthority();
6507        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6508        if (pi == null) {
6509            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6510            return;
6511        }
6512
6513        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6514            grantUri.prefix = true;
6515        }
6516        final UriPermission perm = findOrCreateUriPermissionLocked(
6517                pi.packageName, targetPkg, targetUid, grantUri);
6518        perm.grantModes(modeFlags, owner);
6519    }
6520
6521    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6522            final int modeFlags, UriPermissionOwner owner) {
6523        if (targetPkg == null) {
6524            throw new NullPointerException("targetPkg");
6525        }
6526
6527        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6528                -1);
6529        if (targetUid < 0) {
6530            return;
6531        }
6532
6533        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6534                owner);
6535    }
6536
6537    static class NeededUriGrants extends ArrayList<GrantUri> {
6538        final String targetPkg;
6539        final int targetUid;
6540        final int flags;
6541
6542        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6543            this.targetPkg = targetPkg;
6544            this.targetUid = targetUid;
6545            this.flags = flags;
6546        }
6547    }
6548
6549    /**
6550     * Like checkGrantUriPermissionLocked, but takes an Intent.
6551     */
6552    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6553            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6554        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6555                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6556                + " clip=" + (intent != null ? intent.getClipData() : null)
6557                + " from " + intent + "; flags=0x"
6558                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6559
6560        if (targetPkg == null) {
6561            throw new NullPointerException("targetPkg");
6562        }
6563
6564        if (intent == null) {
6565            return null;
6566        }
6567        Uri data = intent.getData();
6568        ClipData clip = intent.getClipData();
6569        if (data == null && clip == null) {
6570            return null;
6571        }
6572        final IPackageManager pm = AppGlobals.getPackageManager();
6573        int targetUid;
6574        if (needed != null) {
6575            targetUid = needed.targetUid;
6576        } else {
6577            try {
6578                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6579            } catch (RemoteException ex) {
6580                return null;
6581            }
6582            if (targetUid < 0) {
6583                if (DEBUG_URI_PERMISSION) {
6584                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6585                            + " on user " + targetUserId);
6586                }
6587                return null;
6588            }
6589        }
6590        if (data != null) {
6591            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6592            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6593                    targetUid);
6594            if (targetUid > 0) {
6595                if (needed == null) {
6596                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6597                }
6598                needed.add(grantUri);
6599            }
6600        }
6601        if (clip != null) {
6602            for (int i=0; i<clip.getItemCount(); i++) {
6603                Uri uri = clip.getItemAt(i).getUri();
6604                if (uri != null) {
6605                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6606                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6607                            targetUid);
6608                    if (targetUid > 0) {
6609                        if (needed == null) {
6610                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6611                        }
6612                        needed.add(grantUri);
6613                    }
6614                } else {
6615                    Intent clipIntent = clip.getItemAt(i).getIntent();
6616                    if (clipIntent != null) {
6617                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6618                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6619                        if (newNeeded != null) {
6620                            needed = newNeeded;
6621                        }
6622                    }
6623                }
6624            }
6625        }
6626
6627        return needed;
6628    }
6629
6630    /**
6631     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6632     */
6633    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6634            UriPermissionOwner owner) {
6635        if (needed != null) {
6636            for (int i=0; i<needed.size(); i++) {
6637                GrantUri grantUri = needed.get(i);
6638                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6639                        grantUri, needed.flags, owner);
6640            }
6641        }
6642    }
6643
6644    void grantUriPermissionFromIntentLocked(int callingUid,
6645            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6646        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6647                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6648        if (needed == null) {
6649            return;
6650        }
6651
6652        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6653    }
6654
6655    @Override
6656    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6657            final int modeFlags, int userId) {
6658        enforceNotIsolatedCaller("grantUriPermission");
6659        GrantUri grantUri = new GrantUri(userId, uri, false);
6660        synchronized(this) {
6661            final ProcessRecord r = getRecordForAppLocked(caller);
6662            if (r == null) {
6663                throw new SecurityException("Unable to find app for caller "
6664                        + caller
6665                        + " when granting permission to uri " + grantUri);
6666            }
6667            if (targetPkg == null) {
6668                throw new IllegalArgumentException("null target");
6669            }
6670            if (grantUri == null) {
6671                throw new IllegalArgumentException("null uri");
6672            }
6673
6674            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6675                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6676                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6677                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6678
6679            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null);
6680        }
6681    }
6682
6683    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6684        if (perm.modeFlags == 0) {
6685            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6686                    perm.targetUid);
6687            if (perms != null) {
6688                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6689                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6690
6691                perms.remove(perm.uri);
6692                if (perms.isEmpty()) {
6693                    mGrantedUriPermissions.remove(perm.targetUid);
6694                }
6695            }
6696        }
6697    }
6698
6699    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6700        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6701
6702        final IPackageManager pm = AppGlobals.getPackageManager();
6703        final String authority = grantUri.uri.getAuthority();
6704        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6705        if (pi == null) {
6706            Slog.w(TAG, "No content provider found for permission revoke: "
6707                    + grantUri.toSafeString());
6708            return;
6709        }
6710
6711        // Does the caller have this permission on the URI?
6712        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6713            // Right now, if you are not the original owner of the permission,
6714            // you are not allowed to revoke it.
6715            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6716                throw new SecurityException("Uid " + callingUid
6717                        + " does not have permission to uri " + grantUri);
6718            //}
6719        }
6720
6721        boolean persistChanged = false;
6722
6723        // Go through all of the permissions and remove any that match.
6724        int N = mGrantedUriPermissions.size();
6725        for (int i = 0; i < N; i++) {
6726            final int targetUid = mGrantedUriPermissions.keyAt(i);
6727            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6728
6729            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6730                final UriPermission perm = it.next();
6731                if (perm.uri.sourceUserId == grantUri.sourceUserId
6732                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6733                    if (DEBUG_URI_PERMISSION)
6734                        Slog.v(TAG,
6735                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6736                    persistChanged |= perm.revokeModes(
6737                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6738                    if (perm.modeFlags == 0) {
6739                        it.remove();
6740                    }
6741                }
6742            }
6743
6744            if (perms.isEmpty()) {
6745                mGrantedUriPermissions.remove(targetUid);
6746                N--;
6747                i--;
6748            }
6749        }
6750
6751        if (persistChanged) {
6752            schedulePersistUriGrants();
6753        }
6754    }
6755
6756    @Override
6757    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6758            int userId) {
6759        enforceNotIsolatedCaller("revokeUriPermission");
6760        synchronized(this) {
6761            final ProcessRecord r = getRecordForAppLocked(caller);
6762            if (r == null) {
6763                throw new SecurityException("Unable to find app for caller "
6764                        + caller
6765                        + " when revoking permission to uri " + uri);
6766            }
6767            if (uri == null) {
6768                Slog.w(TAG, "revokeUriPermission: null uri");
6769                return;
6770            }
6771
6772            if (!Intent.isAccessUriMode(modeFlags)) {
6773                return;
6774            }
6775
6776            final IPackageManager pm = AppGlobals.getPackageManager();
6777            final String authority = uri.getAuthority();
6778            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6779            if (pi == null) {
6780                Slog.w(TAG, "No content provider found for permission revoke: "
6781                        + uri.toSafeString());
6782                return;
6783            }
6784
6785            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6786        }
6787    }
6788
6789    /**
6790     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6791     * given package.
6792     *
6793     * @param packageName Package name to match, or {@code null} to apply to all
6794     *            packages.
6795     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6796     *            to all users.
6797     * @param persistable If persistable grants should be removed.
6798     */
6799    private void removeUriPermissionsForPackageLocked(
6800            String packageName, int userHandle, boolean persistable) {
6801        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6802            throw new IllegalArgumentException("Must narrow by either package or user");
6803        }
6804
6805        boolean persistChanged = false;
6806
6807        int N = mGrantedUriPermissions.size();
6808        for (int i = 0; i < N; i++) {
6809            final int targetUid = mGrantedUriPermissions.keyAt(i);
6810            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6811
6812            // Only inspect grants matching user
6813            if (userHandle == UserHandle.USER_ALL
6814                    || userHandle == UserHandle.getUserId(targetUid)) {
6815                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6816                    final UriPermission perm = it.next();
6817
6818                    // Only inspect grants matching package
6819                    if (packageName == null || perm.sourcePkg.equals(packageName)
6820                            || perm.targetPkg.equals(packageName)) {
6821                        persistChanged |= perm.revokeModes(
6822                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6823
6824                        // Only remove when no modes remain; any persisted grants
6825                        // will keep this alive.
6826                        if (perm.modeFlags == 0) {
6827                            it.remove();
6828                        }
6829                    }
6830                }
6831
6832                if (perms.isEmpty()) {
6833                    mGrantedUriPermissions.remove(targetUid);
6834                    N--;
6835                    i--;
6836                }
6837            }
6838        }
6839
6840        if (persistChanged) {
6841            schedulePersistUriGrants();
6842        }
6843    }
6844
6845    @Override
6846    public IBinder newUriPermissionOwner(String name) {
6847        enforceNotIsolatedCaller("newUriPermissionOwner");
6848        synchronized(this) {
6849            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6850            return owner.getExternalTokenLocked();
6851        }
6852    }
6853
6854    @Override
6855    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6856            final int modeFlags, int userId) {
6857        synchronized(this) {
6858            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6859            if (owner == null) {
6860                throw new IllegalArgumentException("Unknown owner: " + token);
6861            }
6862            if (fromUid != Binder.getCallingUid()) {
6863                if (Binder.getCallingUid() != Process.myUid()) {
6864                    // Only system code can grant URI permissions on behalf
6865                    // of other users.
6866                    throw new SecurityException("nice try");
6867                }
6868            }
6869            if (targetPkg == null) {
6870                throw new IllegalArgumentException("null target");
6871            }
6872            if (uri == null) {
6873                throw new IllegalArgumentException("null uri");
6874            }
6875
6876            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false),
6877                    modeFlags, owner);
6878        }
6879    }
6880
6881    @Override
6882    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6883        synchronized(this) {
6884            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6885            if (owner == null) {
6886                throw new IllegalArgumentException("Unknown owner: " + token);
6887            }
6888
6889            if (uri == null) {
6890                owner.removeUriPermissionsLocked(mode);
6891            } else {
6892                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6893            }
6894        }
6895    }
6896
6897    private void schedulePersistUriGrants() {
6898        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6899            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6900                    10 * DateUtils.SECOND_IN_MILLIS);
6901        }
6902    }
6903
6904    private void writeGrantedUriPermissions() {
6905        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6906
6907        // Snapshot permissions so we can persist without lock
6908        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6909        synchronized (this) {
6910            final int size = mGrantedUriPermissions.size();
6911            for (int i = 0; i < size; i++) {
6912                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6913                for (UriPermission perm : perms.values()) {
6914                    if (perm.persistedModeFlags != 0) {
6915                        persist.add(perm.snapshot());
6916                    }
6917                }
6918            }
6919        }
6920
6921        FileOutputStream fos = null;
6922        try {
6923            fos = mGrantFile.startWrite();
6924
6925            XmlSerializer out = new FastXmlSerializer();
6926            out.setOutput(fos, "utf-8");
6927            out.startDocument(null, true);
6928            out.startTag(null, TAG_URI_GRANTS);
6929            for (UriPermission.Snapshot perm : persist) {
6930                out.startTag(null, TAG_URI_GRANT);
6931                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6932                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6933                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6934                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6935                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6936                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6937                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6938                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6939                out.endTag(null, TAG_URI_GRANT);
6940            }
6941            out.endTag(null, TAG_URI_GRANTS);
6942            out.endDocument();
6943
6944            mGrantFile.finishWrite(fos);
6945        } catch (IOException e) {
6946            if (fos != null) {
6947                mGrantFile.failWrite(fos);
6948            }
6949        }
6950    }
6951
6952    private void readGrantedUriPermissionsLocked() {
6953        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6954
6955        final long now = System.currentTimeMillis();
6956
6957        FileInputStream fis = null;
6958        try {
6959            fis = mGrantFile.openRead();
6960            final XmlPullParser in = Xml.newPullParser();
6961            in.setInput(fis, null);
6962
6963            int type;
6964            while ((type = in.next()) != END_DOCUMENT) {
6965                final String tag = in.getName();
6966                if (type == START_TAG) {
6967                    if (TAG_URI_GRANT.equals(tag)) {
6968                        final int sourceUserId;
6969                        final int targetUserId;
6970                        final int userHandle = readIntAttribute(in,
6971                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
6972                        if (userHandle != UserHandle.USER_NULL) {
6973                            // For backwards compatibility.
6974                            sourceUserId = userHandle;
6975                            targetUserId = userHandle;
6976                        } else {
6977                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
6978                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
6979                        }
6980                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6981                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6982                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6983                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6984                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6985                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6986
6987                        // Sanity check that provider still belongs to source package
6988                        final ProviderInfo pi = getProviderInfoLocked(
6989                                uri.getAuthority(), sourceUserId);
6990                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6991                            int targetUid = -1;
6992                            try {
6993                                targetUid = AppGlobals.getPackageManager()
6994                                        .getPackageUid(targetPkg, targetUserId);
6995                            } catch (RemoteException e) {
6996                            }
6997                            if (targetUid != -1) {
6998                                final UriPermission perm = findOrCreateUriPermissionLocked(
6999                                        sourcePkg, targetPkg, targetUid,
7000                                        new GrantUri(sourceUserId, uri, prefix));
7001                                perm.initPersistedModes(modeFlags, createdTime);
7002                            }
7003                        } else {
7004                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7005                                    + " but instead found " + pi);
7006                        }
7007                    }
7008                }
7009            }
7010        } catch (FileNotFoundException e) {
7011            // Missing grants is okay
7012        } catch (IOException e) {
7013            Log.wtf(TAG, "Failed reading Uri grants", e);
7014        } catch (XmlPullParserException e) {
7015            Log.wtf(TAG, "Failed reading Uri grants", e);
7016        } finally {
7017            IoUtils.closeQuietly(fis);
7018        }
7019    }
7020
7021    @Override
7022    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7023        enforceNotIsolatedCaller("takePersistableUriPermission");
7024
7025        Preconditions.checkFlagsArgument(modeFlags,
7026                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7027
7028        synchronized (this) {
7029            final int callingUid = Binder.getCallingUid();
7030            boolean persistChanged = false;
7031            GrantUri grantUri = new GrantUri(userId, uri, false);
7032
7033            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7034                    new GrantUri(userId, uri, false));
7035            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7036                    new GrantUri(userId, uri, true));
7037
7038            final boolean exactValid = (exactPerm != null)
7039                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7040            final boolean prefixValid = (prefixPerm != null)
7041                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7042
7043            if (!(exactValid || prefixValid)) {
7044                throw new SecurityException("No persistable permission grants found for UID "
7045                        + callingUid + " and Uri " + grantUri.toSafeString());
7046            }
7047
7048            if (exactValid) {
7049                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7050            }
7051            if (prefixValid) {
7052                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7053            }
7054
7055            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7056
7057            if (persistChanged) {
7058                schedulePersistUriGrants();
7059            }
7060        }
7061    }
7062
7063    @Override
7064    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7065        enforceNotIsolatedCaller("releasePersistableUriPermission");
7066
7067        Preconditions.checkFlagsArgument(modeFlags,
7068                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7069
7070        synchronized (this) {
7071            final int callingUid = Binder.getCallingUid();
7072            boolean persistChanged = false;
7073
7074            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7075                    new GrantUri(userId, uri, false));
7076            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7077                    new GrantUri(userId, uri, true));
7078            if (exactPerm == null && prefixPerm == null) {
7079                throw new SecurityException("No permission grants found for UID " + callingUid
7080                        + " and Uri " + uri.toSafeString());
7081            }
7082
7083            if (exactPerm != null) {
7084                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7085                removeUriPermissionIfNeededLocked(exactPerm);
7086            }
7087            if (prefixPerm != null) {
7088                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7089                removeUriPermissionIfNeededLocked(prefixPerm);
7090            }
7091
7092            if (persistChanged) {
7093                schedulePersistUriGrants();
7094            }
7095        }
7096    }
7097
7098    /**
7099     * Prune any older {@link UriPermission} for the given UID until outstanding
7100     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7101     *
7102     * @return if any mutations occured that require persisting.
7103     */
7104    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7105        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7106        if (perms == null) return false;
7107        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7108
7109        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7110        for (UriPermission perm : perms.values()) {
7111            if (perm.persistedModeFlags != 0) {
7112                persisted.add(perm);
7113            }
7114        }
7115
7116        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7117        if (trimCount <= 0) return false;
7118
7119        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7120        for (int i = 0; i < trimCount; i++) {
7121            final UriPermission perm = persisted.get(i);
7122
7123            if (DEBUG_URI_PERMISSION) {
7124                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7125            }
7126
7127            perm.releasePersistableModes(~0);
7128            removeUriPermissionIfNeededLocked(perm);
7129        }
7130
7131        return true;
7132    }
7133
7134    @Override
7135    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7136            String packageName, boolean incoming) {
7137        enforceNotIsolatedCaller("getPersistedUriPermissions");
7138        Preconditions.checkNotNull(packageName, "packageName");
7139
7140        final int callingUid = Binder.getCallingUid();
7141        final IPackageManager pm = AppGlobals.getPackageManager();
7142        try {
7143            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7144            if (packageUid != callingUid) {
7145                throw new SecurityException(
7146                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7147            }
7148        } catch (RemoteException e) {
7149            throw new SecurityException("Failed to verify package name ownership");
7150        }
7151
7152        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7153        synchronized (this) {
7154            if (incoming) {
7155                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7156                        callingUid);
7157                if (perms == null) {
7158                    Slog.w(TAG, "No permission grants found for " + packageName);
7159                } else {
7160                    for (UriPermission perm : perms.values()) {
7161                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7162                            result.add(perm.buildPersistedPublicApiObject());
7163                        }
7164                    }
7165                }
7166            } else {
7167                final int size = mGrantedUriPermissions.size();
7168                for (int i = 0; i < size; i++) {
7169                    final ArrayMap<GrantUri, UriPermission> perms =
7170                            mGrantedUriPermissions.valueAt(i);
7171                    for (UriPermission perm : perms.values()) {
7172                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7173                            result.add(perm.buildPersistedPublicApiObject());
7174                        }
7175                    }
7176                }
7177            }
7178        }
7179        return new ParceledListSlice<android.content.UriPermission>(result);
7180    }
7181
7182    @Override
7183    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7184        synchronized (this) {
7185            ProcessRecord app =
7186                who != null ? getRecordForAppLocked(who) : null;
7187            if (app == null) return;
7188
7189            Message msg = Message.obtain();
7190            msg.what = WAIT_FOR_DEBUGGER_MSG;
7191            msg.obj = app;
7192            msg.arg1 = waiting ? 1 : 0;
7193            mHandler.sendMessage(msg);
7194        }
7195    }
7196
7197    @Override
7198    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7199        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7200        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7201        outInfo.availMem = Process.getFreeMemory();
7202        outInfo.totalMem = Process.getTotalMemory();
7203        outInfo.threshold = homeAppMem;
7204        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7205        outInfo.hiddenAppThreshold = cachedAppMem;
7206        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7207                ProcessList.SERVICE_ADJ);
7208        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7209                ProcessList.VISIBLE_APP_ADJ);
7210        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7211                ProcessList.FOREGROUND_APP_ADJ);
7212    }
7213
7214    // =========================================================
7215    // TASK MANAGEMENT
7216    // =========================================================
7217
7218    @Override
7219    public List<IAppTask> getAppTasks() {
7220        final PackageManager pm = mContext.getPackageManager();
7221        int callingUid = Binder.getCallingUid();
7222        long ident = Binder.clearCallingIdentity();
7223
7224        // Compose the list of packages for this id to test against
7225        HashSet<String> packages = new HashSet<String>();
7226        String[] uidPackages = pm.getPackagesForUid(callingUid);
7227        for (int i = 0; i < uidPackages.length; i++) {
7228            packages.add(uidPackages[i]);
7229        }
7230
7231        synchronized(this) {
7232            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7233            try {
7234                if (localLOGV) Slog.v(TAG, "getAppTasks");
7235
7236                final int N = mRecentTasks.size();
7237                for (int i = 0; i < N; i++) {
7238                    TaskRecord tr = mRecentTasks.get(i);
7239                    // Skip tasks that are not created by the caller
7240                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
7241                        ActivityManager.RecentTaskInfo taskInfo =
7242                                createRecentTaskInfoFromTaskRecord(tr);
7243                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7244                        list.add(taskImpl);
7245                    }
7246                }
7247            } finally {
7248                Binder.restoreCallingIdentity(ident);
7249            }
7250            return list;
7251        }
7252    }
7253
7254    @Override
7255    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7256        final int callingUid = Binder.getCallingUid();
7257        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7258
7259        synchronized(this) {
7260            if (localLOGV) Slog.v(
7261                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7262
7263            final boolean allowed = checkCallingPermission(
7264                    android.Manifest.permission.GET_TASKS)
7265                    == PackageManager.PERMISSION_GRANTED;
7266            if (!allowed) {
7267                Slog.w(TAG, "getTasks: caller " + callingUid
7268                        + " does not hold GET_TASKS; limiting output");
7269            }
7270
7271            // TODO: Improve with MRU list from all ActivityStacks.
7272            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7273        }
7274
7275        return list;
7276    }
7277
7278    TaskRecord getMostRecentTask() {
7279        return mRecentTasks.get(0);
7280    }
7281
7282    /**
7283     * Creates a new RecentTaskInfo from a TaskRecord.
7284     */
7285    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7286        // Update the task description to reflect any changes in the task stack
7287        tr.updateTaskDescription();
7288
7289        // Compose the recent task info
7290        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7291        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7292        rti.persistentId = tr.taskId;
7293        rti.baseIntent = new Intent(tr.getBaseIntent());
7294        rti.origActivity = tr.origActivity;
7295        rti.description = tr.lastDescription;
7296        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7297        rti.userId = tr.userId;
7298        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7299        rti.firstActiveTime = tr.firstActiveTime;
7300        rti.lastActiveTime = tr.lastActiveTime;
7301        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7302        return rti;
7303    }
7304
7305    @Override
7306    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7307        final int callingUid = Binder.getCallingUid();
7308        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7309                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7310
7311        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7312        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7313        synchronized (this) {
7314            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
7315                    == PackageManager.PERMISSION_GRANTED;
7316            if (!allowed) {
7317                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7318                        + " does not hold GET_TASKS; limiting output");
7319            }
7320            final boolean detailed = checkCallingPermission(
7321                    android.Manifest.permission.GET_DETAILED_TASKS)
7322                    == PackageManager.PERMISSION_GRANTED;
7323
7324            IPackageManager pm = AppGlobals.getPackageManager();
7325
7326            final int N = mRecentTasks.size();
7327            ArrayList<ActivityManager.RecentTaskInfo> res
7328                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7329                            maxNum < N ? maxNum : N);
7330
7331            final Set<Integer> includedUsers;
7332            if (includeProfiles) {
7333                includedUsers = getProfileIdsLocked(userId);
7334            } else {
7335                includedUsers = new HashSet<Integer>();
7336            }
7337            includedUsers.add(Integer.valueOf(userId));
7338
7339            // Regroup affiliated tasks together.
7340            for (int i = 0; i < N; ) {
7341                TaskRecord task = mRecentTasks.remove(i);
7342                if (mTmpRecents.contains(task)) {
7343                    continue;
7344                }
7345                int affiliatedTaskId = task.mAffiliatedTaskId;
7346                while (true) {
7347                    TaskRecord next = task.mNextAffiliate;
7348                    if (next == null) {
7349                        break;
7350                    }
7351                    if (next.mAffiliatedTaskId != affiliatedTaskId) {
7352                        Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
7353                                next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
7354                        task.setNextAffiliate(null);
7355                        if (next.mPrevAffiliate == task) {
7356                            next.setPrevAffiliate(null);
7357                        }
7358                        break;
7359                    }
7360                    if (next.mPrevAffiliate != task) {
7361                        Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
7362                                next.mPrevAffiliate + " task=" + task);
7363                        next.setPrevAffiliate(null);
7364                        break;
7365                    }
7366                    if (!mRecentTasks.contains(next)) {
7367                        Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
7368                        task.setNextAffiliate(null);
7369                        if (next.mPrevAffiliate == task) {
7370                            next.setPrevAffiliate(null);
7371                        }
7372                        break;
7373                    }
7374                    task = next;
7375                }
7376                // task is now the end of the list
7377                do {
7378                    mRecentTasks.remove(task);
7379                    mRecentTasks.add(i++, task);
7380                    mTmpRecents.add(task);
7381                } while ((task = task.mPrevAffiliate) != null);
7382            }
7383            mTmpRecents.clear();
7384            // mRecentTasks is now in sorted, affiliated order.
7385
7386            for (int i=0; i<N && maxNum > 0; i++) {
7387                TaskRecord tr = mRecentTasks.get(i);
7388                // Only add calling user or related users recent tasks
7389                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7390
7391                // Return the entry if desired by the caller.  We always return
7392                // the first entry, because callers always expect this to be the
7393                // foreground app.  We may filter others if the caller has
7394                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7395                // we should exclude the entry.
7396
7397                if (i == 0
7398                        || withExcluded
7399                        || (tr.intent == null)
7400                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7401                                == 0)) {
7402                    if (!allowed) {
7403                        // If the caller doesn't have the GET_TASKS permission, then only
7404                        // allow them to see a small subset of tasks -- their own and home.
7405                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7406                            continue;
7407                        }
7408                    }
7409                    if (tr.intent != null &&
7410                            (tr.intent.getFlags() & Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS)
7411                            != 0 && tr.getTopActivity() == null) {
7412                        // Don't include auto remove tasks that are finished or finishing.
7413                        continue;
7414                    }
7415
7416                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7417                    if (!detailed) {
7418                        rti.baseIntent.replaceExtras((Bundle)null);
7419                    }
7420
7421                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7422                        // Check whether this activity is currently available.
7423                        try {
7424                            if (rti.origActivity != null) {
7425                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7426                                        == null) {
7427                                    continue;
7428                                }
7429                            } else if (rti.baseIntent != null) {
7430                                if (pm.queryIntentActivities(rti.baseIntent,
7431                                        null, 0, userId) == null) {
7432                                    continue;
7433                                }
7434                            }
7435                        } catch (RemoteException e) {
7436                            // Will never happen.
7437                        }
7438                    }
7439
7440                    res.add(rti);
7441                    maxNum--;
7442                }
7443            }
7444            return res;
7445        }
7446    }
7447
7448    private TaskRecord recentTaskForIdLocked(int id) {
7449        final int N = mRecentTasks.size();
7450            for (int i=0; i<N; i++) {
7451                TaskRecord tr = mRecentTasks.get(i);
7452                if (tr.taskId == id) {
7453                    return tr;
7454                }
7455            }
7456            return null;
7457    }
7458
7459    @Override
7460    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7461        synchronized (this) {
7462            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7463                    "getTaskThumbnail()");
7464            TaskRecord tr = recentTaskForIdLocked(id);
7465            if (tr != null) {
7466                return tr.getTaskThumbnailLocked();
7467            }
7468        }
7469        return null;
7470    }
7471
7472    @Override
7473    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7474        synchronized (this) {
7475            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7476            if (r != null) {
7477                r.taskDescription = td;
7478                r.task.updateTaskDescription();
7479            }
7480        }
7481    }
7482
7483    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7484        if (!pr.killedByAm) {
7485            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7486            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7487                    pr.processName, pr.setAdj, reason);
7488            pr.killedByAm = true;
7489            Process.killProcessQuiet(pr.pid);
7490            Process.killProcessGroup(pr.info.uid, pr.pid);
7491        }
7492    }
7493
7494    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7495        tr.disposeThumbnail();
7496        mRecentTasks.remove(tr);
7497        tr.closeRecentsChain();
7498        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7499        Intent baseIntent = new Intent(
7500                tr.intent != null ? tr.intent : tr.affinityIntent);
7501        ComponentName component = baseIntent.getComponent();
7502        if (component == null) {
7503            Slog.w(TAG, "Now component for base intent of task: " + tr);
7504            return;
7505        }
7506
7507        // Find any running services associated with this app.
7508        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7509
7510        if (killProcesses) {
7511            // Find any running processes associated with this app.
7512            final String pkg = component.getPackageName();
7513            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7514            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7515            for (int i=0; i<pmap.size(); i++) {
7516                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7517                for (int j=0; j<uids.size(); j++) {
7518                    ProcessRecord proc = uids.valueAt(j);
7519                    if (proc.userId != tr.userId) {
7520                        continue;
7521                    }
7522                    if (!proc.pkgList.containsKey(pkg)) {
7523                        continue;
7524                    }
7525                    procs.add(proc);
7526                }
7527            }
7528
7529            // Kill the running processes.
7530            for (int i=0; i<procs.size(); i++) {
7531                ProcessRecord pr = procs.get(i);
7532                if (pr == mHomeProcess) {
7533                    // Don't kill the home process along with tasks from the same package.
7534                    continue;
7535                }
7536                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7537                    killUnneededProcessLocked(pr, "remove task");
7538                } else {
7539                    pr.waitingToKill = "remove task";
7540                }
7541            }
7542        }
7543    }
7544
7545    /**
7546     * Removes the task with the specified task id.
7547     *
7548     * @param taskId Identifier of the task to be removed.
7549     * @param flags Additional operational flags.  May be 0 or
7550     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7551     * @return Returns true if the given task was found and removed.
7552     */
7553    private boolean removeTaskByIdLocked(int taskId, int flags) {
7554        TaskRecord tr = recentTaskForIdLocked(taskId);
7555        if (tr != null) {
7556            tr.removeTaskActivitiesLocked();
7557            cleanUpRemovedTaskLocked(tr, flags);
7558            if (tr.isPersistable) {
7559                notifyTaskPersisterLocked(tr, true);
7560            }
7561            return true;
7562        }
7563        return false;
7564    }
7565
7566    @Override
7567    public boolean removeTask(int taskId, int flags) {
7568        synchronized (this) {
7569            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7570                    "removeTask()");
7571            long ident = Binder.clearCallingIdentity();
7572            try {
7573                return removeTaskByIdLocked(taskId, flags);
7574            } finally {
7575                Binder.restoreCallingIdentity(ident);
7576            }
7577        }
7578    }
7579
7580    /**
7581     * TODO: Add mController hook
7582     */
7583    @Override
7584    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7585        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7586                "moveTaskToFront()");
7587
7588        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7589        synchronized(this) {
7590            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7591                    Binder.getCallingUid(), "Task to front")) {
7592                ActivityOptions.abort(options);
7593                return;
7594            }
7595            final long origId = Binder.clearCallingIdentity();
7596            try {
7597                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7598                if (task == null) {
7599                    return;
7600                }
7601                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7602                    mStackSupervisor.showLockTaskToast();
7603                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7604                    return;
7605                }
7606                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7607                if (prev != null && prev.isRecentsActivity()) {
7608                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7609                }
7610                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7611            } finally {
7612                Binder.restoreCallingIdentity(origId);
7613            }
7614            ActivityOptions.abort(options);
7615        }
7616    }
7617
7618    @Override
7619    public void moveTaskToBack(int taskId) {
7620        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7621                "moveTaskToBack()");
7622
7623        synchronized(this) {
7624            TaskRecord tr = recentTaskForIdLocked(taskId);
7625            if (tr != null) {
7626                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7627                ActivityStack stack = tr.stack;
7628                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7629                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7630                            Binder.getCallingUid(), "Task to back")) {
7631                        return;
7632                    }
7633                }
7634                final long origId = Binder.clearCallingIdentity();
7635                try {
7636                    stack.moveTaskToBackLocked(taskId, null);
7637                } finally {
7638                    Binder.restoreCallingIdentity(origId);
7639                }
7640            }
7641        }
7642    }
7643
7644    /**
7645     * Moves an activity, and all of the other activities within the same task, to the bottom
7646     * of the history stack.  The activity's order within the task is unchanged.
7647     *
7648     * @param token A reference to the activity we wish to move
7649     * @param nonRoot If false then this only works if the activity is the root
7650     *                of a task; if true it will work for any activity in a task.
7651     * @return Returns true if the move completed, false if not.
7652     */
7653    @Override
7654    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7655        enforceNotIsolatedCaller("moveActivityTaskToBack");
7656        synchronized(this) {
7657            final long origId = Binder.clearCallingIdentity();
7658            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7659            if (taskId >= 0) {
7660                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7661            }
7662            Binder.restoreCallingIdentity(origId);
7663        }
7664        return false;
7665    }
7666
7667    @Override
7668    public void moveTaskBackwards(int task) {
7669        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7670                "moveTaskBackwards()");
7671
7672        synchronized(this) {
7673            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7674                    Binder.getCallingUid(), "Task backwards")) {
7675                return;
7676            }
7677            final long origId = Binder.clearCallingIdentity();
7678            moveTaskBackwardsLocked(task);
7679            Binder.restoreCallingIdentity(origId);
7680        }
7681    }
7682
7683    private final void moveTaskBackwardsLocked(int task) {
7684        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7685    }
7686
7687    @Override
7688    public IBinder getHomeActivityToken() throws RemoteException {
7689        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7690                "getHomeActivityToken()");
7691        synchronized (this) {
7692            return mStackSupervisor.getHomeActivityToken();
7693        }
7694    }
7695
7696    @Override
7697    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7698            IActivityContainerCallback callback) throws RemoteException {
7699        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7700                "createActivityContainer()");
7701        synchronized (this) {
7702            if (parentActivityToken == null) {
7703                throw new IllegalArgumentException("parent token must not be null");
7704            }
7705            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7706            if (r == null) {
7707                return null;
7708            }
7709            if (callback == null) {
7710                throw new IllegalArgumentException("callback must not be null");
7711            }
7712            return mStackSupervisor.createActivityContainer(r, callback);
7713        }
7714    }
7715
7716    @Override
7717    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7718        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7719                "deleteActivityContainer()");
7720        synchronized (this) {
7721            mStackSupervisor.deleteActivityContainer(container);
7722        }
7723    }
7724
7725    @Override
7726    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7727            throws RemoteException {
7728        synchronized (this) {
7729            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7730            if (stack != null) {
7731                return stack.mActivityContainer;
7732            }
7733            return null;
7734        }
7735    }
7736
7737    @Override
7738    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7739        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7740                "moveTaskToStack()");
7741        if (stackId == HOME_STACK_ID) {
7742            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7743                    new RuntimeException("here").fillInStackTrace());
7744        }
7745        synchronized (this) {
7746            long ident = Binder.clearCallingIdentity();
7747            try {
7748                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7749                        + stackId + " toTop=" + toTop);
7750                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7751            } finally {
7752                Binder.restoreCallingIdentity(ident);
7753            }
7754        }
7755    }
7756
7757    @Override
7758    public void resizeStack(int stackBoxId, Rect bounds) {
7759        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7760                "resizeStackBox()");
7761        long ident = Binder.clearCallingIdentity();
7762        try {
7763            mWindowManager.resizeStack(stackBoxId, bounds);
7764        } finally {
7765            Binder.restoreCallingIdentity(ident);
7766        }
7767    }
7768
7769    @Override
7770    public List<StackInfo> getAllStackInfos() {
7771        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7772                "getAllStackInfos()");
7773        long ident = Binder.clearCallingIdentity();
7774        try {
7775            synchronized (this) {
7776                return mStackSupervisor.getAllStackInfosLocked();
7777            }
7778        } finally {
7779            Binder.restoreCallingIdentity(ident);
7780        }
7781    }
7782
7783    @Override
7784    public StackInfo getStackInfo(int stackId) {
7785        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7786                "getStackInfo()");
7787        long ident = Binder.clearCallingIdentity();
7788        try {
7789            synchronized (this) {
7790                return mStackSupervisor.getStackInfoLocked(stackId);
7791            }
7792        } finally {
7793            Binder.restoreCallingIdentity(ident);
7794        }
7795    }
7796
7797    @Override
7798    public boolean isInHomeStack(int taskId) {
7799        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7800                "getStackInfo()");
7801        long ident = Binder.clearCallingIdentity();
7802        try {
7803            synchronized (this) {
7804                TaskRecord tr = recentTaskForIdLocked(taskId);
7805                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7806            }
7807        } finally {
7808            Binder.restoreCallingIdentity(ident);
7809        }
7810    }
7811
7812    @Override
7813    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7814        synchronized(this) {
7815            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7816        }
7817    }
7818
7819    private boolean isLockTaskAuthorized(String pkg) {
7820        final DevicePolicyManager dpm = (DevicePolicyManager)
7821                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7822        try {
7823            int uid = mContext.getPackageManager().getPackageUid(pkg,
7824                    Binder.getCallingUserHandle().getIdentifier());
7825            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7826        } catch (NameNotFoundException e) {
7827            return false;
7828        }
7829    }
7830
7831    void startLockTaskMode(TaskRecord task) {
7832        final String pkg;
7833        synchronized (this) {
7834            pkg = task.intent.getComponent().getPackageName();
7835        }
7836        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
7837        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
7838            final TaskRecord taskRecord = task;
7839            mHandler.post(new Runnable() {
7840                @Override
7841                public void run() {
7842                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
7843                }
7844            });
7845            return;
7846        }
7847        long ident = Binder.clearCallingIdentity();
7848        try {
7849            synchronized (this) {
7850                // Since we lost lock on task, make sure it is still there.
7851                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7852                if (task != null) {
7853                    if (!isSystemInitiated
7854                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
7855                        throw new IllegalArgumentException("Invalid task, not in foreground");
7856                    }
7857                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
7858                }
7859            }
7860        } finally {
7861            Binder.restoreCallingIdentity(ident);
7862        }
7863    }
7864
7865    @Override
7866    public void startLockTaskMode(int taskId) {
7867        final TaskRecord task;
7868        long ident = Binder.clearCallingIdentity();
7869        try {
7870            synchronized (this) {
7871                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7872            }
7873        } finally {
7874            Binder.restoreCallingIdentity(ident);
7875        }
7876        if (task != null) {
7877            startLockTaskMode(task);
7878        }
7879    }
7880
7881    @Override
7882    public void startLockTaskMode(IBinder token) {
7883        final TaskRecord task;
7884        long ident = Binder.clearCallingIdentity();
7885        try {
7886            synchronized (this) {
7887                final ActivityRecord r = ActivityRecord.forToken(token);
7888                if (r == null) {
7889                    return;
7890                }
7891                task = r.task;
7892            }
7893        } finally {
7894            Binder.restoreCallingIdentity(ident);
7895        }
7896        if (task != null) {
7897            startLockTaskMode(task);
7898        }
7899    }
7900
7901    @Override
7902    public void startLockTaskModeOnCurrent() throws RemoteException {
7903        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7904        ActivityRecord r = null;
7905        synchronized (this) {
7906            r = mStackSupervisor.topRunningActivityLocked();
7907        }
7908        startLockTaskMode(r.task);
7909    }
7910
7911    @Override
7912    public void stopLockTaskMode() {
7913        // Verify that the user matches the package of the intent for the TaskRecord
7914        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
7915        // and stopLockTaskMode.
7916        final int callingUid = Binder.getCallingUid();
7917        if (callingUid != Process.SYSTEM_UID) {
7918            try {
7919                String pkg =
7920                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
7921                int uid = mContext.getPackageManager().getPackageUid(pkg,
7922                        Binder.getCallingUserHandle().getIdentifier());
7923                if (uid != callingUid) {
7924                    throw new SecurityException("Invalid uid, expected " + uid);
7925                }
7926            } catch (NameNotFoundException e) {
7927                Log.d(TAG, "stopLockTaskMode " + e);
7928                return;
7929            }
7930        }
7931        long ident = Binder.clearCallingIdentity();
7932        try {
7933            Log.d(TAG, "stopLockTaskMode");
7934            // Stop lock task
7935            synchronized (this) {
7936                mStackSupervisor.setLockTaskModeLocked(null, false);
7937            }
7938        } finally {
7939            Binder.restoreCallingIdentity(ident);
7940        }
7941    }
7942
7943    @Override
7944    public void stopLockTaskModeOnCurrent() throws RemoteException {
7945        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7946        long ident = Binder.clearCallingIdentity();
7947        try {
7948            stopLockTaskMode();
7949        } finally {
7950            Binder.restoreCallingIdentity(ident);
7951        }
7952    }
7953
7954    @Override
7955    public boolean isInLockTaskMode() {
7956        synchronized (this) {
7957            return mStackSupervisor.isInLockTaskMode();
7958        }
7959    }
7960
7961    // =========================================================
7962    // CONTENT PROVIDERS
7963    // =========================================================
7964
7965    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7966        List<ProviderInfo> providers = null;
7967        try {
7968            providers = AppGlobals.getPackageManager().
7969                queryContentProviders(app.processName, app.uid,
7970                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7971        } catch (RemoteException ex) {
7972        }
7973        if (DEBUG_MU)
7974            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7975        int userId = app.userId;
7976        if (providers != null) {
7977            int N = providers.size();
7978            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7979            for (int i=0; i<N; i++) {
7980                ProviderInfo cpi =
7981                    (ProviderInfo)providers.get(i);
7982                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7983                        cpi.name, cpi.flags);
7984                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7985                    // This is a singleton provider, but a user besides the
7986                    // default user is asking to initialize a process it runs
7987                    // in...  well, no, it doesn't actually run in this process,
7988                    // it runs in the process of the default user.  Get rid of it.
7989                    providers.remove(i);
7990                    N--;
7991                    i--;
7992                    continue;
7993                }
7994
7995                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7996                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7997                if (cpr == null) {
7998                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7999                    mProviderMap.putProviderByClass(comp, cpr);
8000                }
8001                if (DEBUG_MU)
8002                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8003                app.pubProviders.put(cpi.name, cpr);
8004                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8005                    // Don't add this if it is a platform component that is marked
8006                    // to run in multiple processes, because this is actually
8007                    // part of the framework so doesn't make sense to track as a
8008                    // separate apk in the process.
8009                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8010                            mProcessStats);
8011                }
8012                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8013            }
8014        }
8015        return providers;
8016    }
8017
8018    /**
8019     * Check if {@link ProcessRecord} has a possible chance at accessing the
8020     * given {@link ProviderInfo}. Final permission checking is always done
8021     * in {@link ContentProvider}.
8022     */
8023    private final String checkContentProviderPermissionLocked(
8024            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8025        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8026        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8027        boolean checkedGrants = false;
8028        if (checkUser) {
8029            // Looking for cross-user grants before enforcing the typical cross-users permissions
8030            int tmpTargetUserId = unsafeConvertIncomingUser(UserHandle.getUserId(callingUid));
8031            if (tmpTargetUserId != userId) {
8032                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8033                    return null;
8034                }
8035                checkedGrants = true;
8036            }
8037            userId = handleIncomingUser(callingPid, callingUid, userId,
8038                    false, ALLOW_NON_FULL_IN_PROFILE,
8039                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8040            if (userId != tmpTargetUserId) {
8041                // When we actually went to determine the final targer user ID, this ended
8042                // up different than our initial check for the authority.  This is because
8043                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8044                // SELF.  So we need to re-check the grants again.
8045                checkedGrants = false;
8046            }
8047        }
8048        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8049                cpi.applicationInfo.uid, cpi.exported)
8050                == PackageManager.PERMISSION_GRANTED) {
8051            return null;
8052        }
8053        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8054                cpi.applicationInfo.uid, cpi.exported)
8055                == PackageManager.PERMISSION_GRANTED) {
8056            return null;
8057        }
8058
8059        PathPermission[] pps = cpi.pathPermissions;
8060        if (pps != null) {
8061            int i = pps.length;
8062            while (i > 0) {
8063                i--;
8064                PathPermission pp = pps[i];
8065                String pprperm = pp.getReadPermission();
8066                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8067                        cpi.applicationInfo.uid, cpi.exported)
8068                        == PackageManager.PERMISSION_GRANTED) {
8069                    return null;
8070                }
8071                String ppwperm = pp.getWritePermission();
8072                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8073                        cpi.applicationInfo.uid, cpi.exported)
8074                        == PackageManager.PERMISSION_GRANTED) {
8075                    return null;
8076                }
8077            }
8078        }
8079        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8080            return null;
8081        }
8082
8083        String msg;
8084        if (!cpi.exported) {
8085            msg = "Permission Denial: opening provider " + cpi.name
8086                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8087                    + ", uid=" + callingUid + ") that is not exported from uid "
8088                    + cpi.applicationInfo.uid;
8089        } else {
8090            msg = "Permission Denial: opening provider " + cpi.name
8091                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8092                    + ", uid=" + callingUid + ") requires "
8093                    + cpi.readPermission + " or " + cpi.writePermission;
8094        }
8095        Slog.w(TAG, msg);
8096        return msg;
8097    }
8098
8099    /**
8100     * Returns if the ContentProvider has granted a uri to callingUid
8101     */
8102    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8103        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8104        if (perms != null) {
8105            for (int i=perms.size()-1; i>=0; i--) {
8106                GrantUri grantUri = perms.keyAt(i);
8107                if (grantUri.sourceUserId == userId || !checkUser) {
8108                    if (matchesProvider(grantUri.uri, cpi)) {
8109                        return true;
8110                    }
8111                }
8112            }
8113        }
8114        return false;
8115    }
8116
8117    /**
8118     * Returns true if the uri authority is one of the authorities specified in the provider.
8119     */
8120    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8121        String uriAuth = uri.getAuthority();
8122        String cpiAuth = cpi.authority;
8123        if (cpiAuth.indexOf(';') == -1) {
8124            return cpiAuth.equals(uriAuth);
8125        }
8126        String[] cpiAuths = cpiAuth.split(";");
8127        int length = cpiAuths.length;
8128        for (int i = 0; i < length; i++) {
8129            if (cpiAuths[i].equals(uriAuth)) return true;
8130        }
8131        return false;
8132    }
8133
8134    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8135            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8136        if (r != null) {
8137            for (int i=0; i<r.conProviders.size(); i++) {
8138                ContentProviderConnection conn = r.conProviders.get(i);
8139                if (conn.provider == cpr) {
8140                    if (DEBUG_PROVIDER) Slog.v(TAG,
8141                            "Adding provider requested by "
8142                            + r.processName + " from process "
8143                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8144                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8145                    if (stable) {
8146                        conn.stableCount++;
8147                        conn.numStableIncs++;
8148                    } else {
8149                        conn.unstableCount++;
8150                        conn.numUnstableIncs++;
8151                    }
8152                    return conn;
8153                }
8154            }
8155            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8156            if (stable) {
8157                conn.stableCount = 1;
8158                conn.numStableIncs = 1;
8159            } else {
8160                conn.unstableCount = 1;
8161                conn.numUnstableIncs = 1;
8162            }
8163            cpr.connections.add(conn);
8164            r.conProviders.add(conn);
8165            return conn;
8166        }
8167        cpr.addExternalProcessHandleLocked(externalProcessToken);
8168        return null;
8169    }
8170
8171    boolean decProviderCountLocked(ContentProviderConnection conn,
8172            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8173        if (conn != null) {
8174            cpr = conn.provider;
8175            if (DEBUG_PROVIDER) Slog.v(TAG,
8176                    "Removing provider requested by "
8177                    + conn.client.processName + " from process "
8178                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8179                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8180            if (stable) {
8181                conn.stableCount--;
8182            } else {
8183                conn.unstableCount--;
8184            }
8185            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8186                cpr.connections.remove(conn);
8187                conn.client.conProviders.remove(conn);
8188                return true;
8189            }
8190            return false;
8191        }
8192        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8193        return false;
8194    }
8195
8196    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8197            String name, IBinder token, boolean stable, int userId) {
8198        ContentProviderRecord cpr;
8199        ContentProviderConnection conn = null;
8200        ProviderInfo cpi = null;
8201
8202        synchronized(this) {
8203            ProcessRecord r = null;
8204            if (caller != null) {
8205                r = getRecordForAppLocked(caller);
8206                if (r == null) {
8207                    throw new SecurityException(
8208                            "Unable to find app for caller " + caller
8209                          + " (pid=" + Binder.getCallingPid()
8210                          + ") when getting content provider " + name);
8211                }
8212            }
8213
8214            boolean checkCrossUser = true;
8215
8216            // First check if this content provider has been published...
8217            cpr = mProviderMap.getProviderByName(name, userId);
8218            // If that didn't work, check if it exists for user 0 and then
8219            // verify that it's a singleton provider before using it.
8220            if (cpr == null && userId != UserHandle.USER_OWNER) {
8221                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8222                if (cpr != null) {
8223                    cpi = cpr.info;
8224                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8225                            cpi.name, cpi.flags)
8226                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8227                        userId = UserHandle.USER_OWNER;
8228                        checkCrossUser = false;
8229                    } else {
8230                        cpr = null;
8231                        cpi = null;
8232                    }
8233                }
8234            }
8235
8236            boolean providerRunning = cpr != null;
8237            if (providerRunning) {
8238                cpi = cpr.info;
8239                String msg;
8240                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8241                        != null) {
8242                    throw new SecurityException(msg);
8243                }
8244
8245                if (r != null && cpr.canRunHere(r)) {
8246                    // This provider has been published or is in the process
8247                    // of being published...  but it is also allowed to run
8248                    // in the caller's process, so don't make a connection
8249                    // and just let the caller instantiate its own instance.
8250                    ContentProviderHolder holder = cpr.newHolder(null);
8251                    // don't give caller the provider object, it needs
8252                    // to make its own.
8253                    holder.provider = null;
8254                    return holder;
8255                }
8256
8257                final long origId = Binder.clearCallingIdentity();
8258
8259                // In this case the provider instance already exists, so we can
8260                // return it right away.
8261                conn = incProviderCountLocked(r, cpr, token, stable);
8262                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8263                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8264                        // If this is a perceptible app accessing the provider,
8265                        // make sure to count it as being accessed and thus
8266                        // back up on the LRU list.  This is good because
8267                        // content providers are often expensive to start.
8268                        updateLruProcessLocked(cpr.proc, false, null);
8269                    }
8270                }
8271
8272                if (cpr.proc != null) {
8273                    if (false) {
8274                        if (cpr.name.flattenToShortString().equals(
8275                                "com.android.providers.calendar/.CalendarProvider2")) {
8276                            Slog.v(TAG, "****************** KILLING "
8277                                + cpr.name.flattenToShortString());
8278                            Process.killProcess(cpr.proc.pid);
8279                        }
8280                    }
8281                    boolean success = updateOomAdjLocked(cpr.proc);
8282                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8283                    // NOTE: there is still a race here where a signal could be
8284                    // pending on the process even though we managed to update its
8285                    // adj level.  Not sure what to do about this, but at least
8286                    // the race is now smaller.
8287                    if (!success) {
8288                        // Uh oh...  it looks like the provider's process
8289                        // has been killed on us.  We need to wait for a new
8290                        // process to be started, and make sure its death
8291                        // doesn't kill our process.
8292                        Slog.i(TAG,
8293                                "Existing provider " + cpr.name.flattenToShortString()
8294                                + " is crashing; detaching " + r);
8295                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8296                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8297                        if (!lastRef) {
8298                            // This wasn't the last ref our process had on
8299                            // the provider...  we have now been killed, bail.
8300                            return null;
8301                        }
8302                        providerRunning = false;
8303                        conn = null;
8304                    }
8305                }
8306
8307                Binder.restoreCallingIdentity(origId);
8308            }
8309
8310            boolean singleton;
8311            if (!providerRunning) {
8312                try {
8313                    cpi = AppGlobals.getPackageManager().
8314                        resolveContentProvider(name,
8315                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8316                } catch (RemoteException ex) {
8317                }
8318                if (cpi == null) {
8319                    return null;
8320                }
8321                // If the provider is a singleton AND
8322                // (it's a call within the same user || the provider is a
8323                // privileged app)
8324                // Then allow connecting to the singleton provider
8325                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8326                        cpi.name, cpi.flags)
8327                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8328                if (singleton) {
8329                    userId = UserHandle.USER_OWNER;
8330                }
8331                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8332
8333                String msg;
8334                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8335                        != null) {
8336                    throw new SecurityException(msg);
8337                }
8338
8339                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8340                        && !cpi.processName.equals("system")) {
8341                    // If this content provider does not run in the system
8342                    // process, and the system is not yet ready to run other
8343                    // processes, then fail fast instead of hanging.
8344                    throw new IllegalArgumentException(
8345                            "Attempt to launch content provider before system ready");
8346                }
8347
8348                // Make sure that the user who owns this provider is started.  If not,
8349                // we don't want to allow it to run.
8350                if (mStartedUsers.get(userId) == null) {
8351                    Slog.w(TAG, "Unable to launch app "
8352                            + cpi.applicationInfo.packageName + "/"
8353                            + cpi.applicationInfo.uid + " for provider "
8354                            + name + ": user " + userId + " is stopped");
8355                    return null;
8356                }
8357
8358                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8359                cpr = mProviderMap.getProviderByClass(comp, userId);
8360                final boolean firstClass = cpr == null;
8361                if (firstClass) {
8362                    try {
8363                        ApplicationInfo ai =
8364                            AppGlobals.getPackageManager().
8365                                getApplicationInfo(
8366                                        cpi.applicationInfo.packageName,
8367                                        STOCK_PM_FLAGS, userId);
8368                        if (ai == null) {
8369                            Slog.w(TAG, "No package info for content provider "
8370                                    + cpi.name);
8371                            return null;
8372                        }
8373                        ai = getAppInfoForUser(ai, userId);
8374                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8375                    } catch (RemoteException ex) {
8376                        // pm is in same process, this will never happen.
8377                    }
8378                }
8379
8380                if (r != null && cpr.canRunHere(r)) {
8381                    // If this is a multiprocess provider, then just return its
8382                    // info and allow the caller to instantiate it.  Only do
8383                    // this if the provider is the same user as the caller's
8384                    // process, or can run as root (so can be in any process).
8385                    return cpr.newHolder(null);
8386                }
8387
8388                if (DEBUG_PROVIDER) {
8389                    RuntimeException e = new RuntimeException("here");
8390                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8391                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8392                }
8393
8394                // This is single process, and our app is now connecting to it.
8395                // See if we are already in the process of launching this
8396                // provider.
8397                final int N = mLaunchingProviders.size();
8398                int i;
8399                for (i=0; i<N; i++) {
8400                    if (mLaunchingProviders.get(i) == cpr) {
8401                        break;
8402                    }
8403                }
8404
8405                // If the provider is not already being launched, then get it
8406                // started.
8407                if (i >= N) {
8408                    final long origId = Binder.clearCallingIdentity();
8409
8410                    try {
8411                        // Content provider is now in use, its package can't be stopped.
8412                        try {
8413                            AppGlobals.getPackageManager().setPackageStoppedState(
8414                                    cpr.appInfo.packageName, false, userId);
8415                        } catch (RemoteException e) {
8416                        } catch (IllegalArgumentException e) {
8417                            Slog.w(TAG, "Failed trying to unstop package "
8418                                    + cpr.appInfo.packageName + ": " + e);
8419                        }
8420
8421                        // Use existing process if already started
8422                        ProcessRecord proc = getProcessRecordLocked(
8423                                cpi.processName, cpr.appInfo.uid, false);
8424                        if (proc != null && proc.thread != null) {
8425                            if (DEBUG_PROVIDER) {
8426                                Slog.d(TAG, "Installing in existing process " + proc);
8427                            }
8428                            proc.pubProviders.put(cpi.name, cpr);
8429                            try {
8430                                proc.thread.scheduleInstallProvider(cpi);
8431                            } catch (RemoteException e) {
8432                            }
8433                        } else {
8434                            proc = startProcessLocked(cpi.processName,
8435                                    cpr.appInfo, false, 0, "content provider",
8436                                    new ComponentName(cpi.applicationInfo.packageName,
8437                                            cpi.name), false, false, false);
8438                            if (proc == null) {
8439                                Slog.w(TAG, "Unable to launch app "
8440                                        + cpi.applicationInfo.packageName + "/"
8441                                        + cpi.applicationInfo.uid + " for provider "
8442                                        + name + ": process is bad");
8443                                return null;
8444                            }
8445                        }
8446                        cpr.launchingApp = proc;
8447                        mLaunchingProviders.add(cpr);
8448                    } finally {
8449                        Binder.restoreCallingIdentity(origId);
8450                    }
8451                }
8452
8453                // Make sure the provider is published (the same provider class
8454                // may be published under multiple names).
8455                if (firstClass) {
8456                    mProviderMap.putProviderByClass(comp, cpr);
8457                }
8458
8459                mProviderMap.putProviderByName(name, cpr);
8460                conn = incProviderCountLocked(r, cpr, token, stable);
8461                if (conn != null) {
8462                    conn.waiting = true;
8463                }
8464            }
8465        }
8466
8467        // Wait for the provider to be published...
8468        synchronized (cpr) {
8469            while (cpr.provider == null) {
8470                if (cpr.launchingApp == null) {
8471                    Slog.w(TAG, "Unable to launch app "
8472                            + cpi.applicationInfo.packageName + "/"
8473                            + cpi.applicationInfo.uid + " for provider "
8474                            + name + ": launching app became null");
8475                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8476                            UserHandle.getUserId(cpi.applicationInfo.uid),
8477                            cpi.applicationInfo.packageName,
8478                            cpi.applicationInfo.uid, name);
8479                    return null;
8480                }
8481                try {
8482                    if (DEBUG_MU) {
8483                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8484                                + cpr.launchingApp);
8485                    }
8486                    if (conn != null) {
8487                        conn.waiting = true;
8488                    }
8489                    cpr.wait();
8490                } catch (InterruptedException ex) {
8491                } finally {
8492                    if (conn != null) {
8493                        conn.waiting = false;
8494                    }
8495                }
8496            }
8497        }
8498        return cpr != null ? cpr.newHolder(conn) : null;
8499    }
8500
8501    @Override
8502    public final ContentProviderHolder getContentProvider(
8503            IApplicationThread caller, String name, int userId, boolean stable) {
8504        enforceNotIsolatedCaller("getContentProvider");
8505        if (caller == null) {
8506            String msg = "null IApplicationThread when getting content provider "
8507                    + name;
8508            Slog.w(TAG, msg);
8509            throw new SecurityException(msg);
8510        }
8511        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8512        // with cross-user grant.
8513        return getContentProviderImpl(caller, name, null, stable, userId);
8514    }
8515
8516    public ContentProviderHolder getContentProviderExternal(
8517            String name, int userId, IBinder token) {
8518        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8519            "Do not have permission in call getContentProviderExternal()");
8520        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8521                false, ALLOW_FULL_ONLY, "getContentProvider", null);
8522        return getContentProviderExternalUnchecked(name, token, userId);
8523    }
8524
8525    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8526            IBinder token, int userId) {
8527        return getContentProviderImpl(null, name, token, true, userId);
8528    }
8529
8530    /**
8531     * Drop a content provider from a ProcessRecord's bookkeeping
8532     */
8533    public void removeContentProvider(IBinder connection, boolean stable) {
8534        enforceNotIsolatedCaller("removeContentProvider");
8535        long ident = Binder.clearCallingIdentity();
8536        try {
8537            synchronized (this) {
8538                ContentProviderConnection conn;
8539                try {
8540                    conn = (ContentProviderConnection)connection;
8541                } catch (ClassCastException e) {
8542                    String msg ="removeContentProvider: " + connection
8543                            + " not a ContentProviderConnection";
8544                    Slog.w(TAG, msg);
8545                    throw new IllegalArgumentException(msg);
8546                }
8547                if (conn == null) {
8548                    throw new NullPointerException("connection is null");
8549                }
8550                if (decProviderCountLocked(conn, null, null, stable)) {
8551                    updateOomAdjLocked();
8552                }
8553            }
8554        } finally {
8555            Binder.restoreCallingIdentity(ident);
8556        }
8557    }
8558
8559    public void removeContentProviderExternal(String name, IBinder token) {
8560        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8561            "Do not have permission in call removeContentProviderExternal()");
8562        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8563    }
8564
8565    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8566        synchronized (this) {
8567            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8568            if(cpr == null) {
8569                //remove from mProvidersByClass
8570                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8571                return;
8572            }
8573
8574            //update content provider record entry info
8575            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8576            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8577            if (localCpr.hasExternalProcessHandles()) {
8578                if (localCpr.removeExternalProcessHandleLocked(token)) {
8579                    updateOomAdjLocked();
8580                } else {
8581                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8582                            + " with no external reference for token: "
8583                            + token + ".");
8584                }
8585            } else {
8586                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8587                        + " with no external references.");
8588            }
8589        }
8590    }
8591
8592    public final void publishContentProviders(IApplicationThread caller,
8593            List<ContentProviderHolder> providers) {
8594        if (providers == null) {
8595            return;
8596        }
8597
8598        enforceNotIsolatedCaller("publishContentProviders");
8599        synchronized (this) {
8600            final ProcessRecord r = getRecordForAppLocked(caller);
8601            if (DEBUG_MU)
8602                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8603            if (r == null) {
8604                throw new SecurityException(
8605                        "Unable to find app for caller " + caller
8606                      + " (pid=" + Binder.getCallingPid()
8607                      + ") when publishing content providers");
8608            }
8609
8610            final long origId = Binder.clearCallingIdentity();
8611
8612            final int N = providers.size();
8613            for (int i=0; i<N; i++) {
8614                ContentProviderHolder src = providers.get(i);
8615                if (src == null || src.info == null || src.provider == null) {
8616                    continue;
8617                }
8618                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8619                if (DEBUG_MU)
8620                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8621                if (dst != null) {
8622                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8623                    mProviderMap.putProviderByClass(comp, dst);
8624                    String names[] = dst.info.authority.split(";");
8625                    for (int j = 0; j < names.length; j++) {
8626                        mProviderMap.putProviderByName(names[j], dst);
8627                    }
8628
8629                    int NL = mLaunchingProviders.size();
8630                    int j;
8631                    for (j=0; j<NL; j++) {
8632                        if (mLaunchingProviders.get(j) == dst) {
8633                            mLaunchingProviders.remove(j);
8634                            j--;
8635                            NL--;
8636                        }
8637                    }
8638                    synchronized (dst) {
8639                        dst.provider = src.provider;
8640                        dst.proc = r;
8641                        dst.notifyAll();
8642                    }
8643                    updateOomAdjLocked(r);
8644                }
8645            }
8646
8647            Binder.restoreCallingIdentity(origId);
8648        }
8649    }
8650
8651    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8652        ContentProviderConnection conn;
8653        try {
8654            conn = (ContentProviderConnection)connection;
8655        } catch (ClassCastException e) {
8656            String msg ="refContentProvider: " + connection
8657                    + " not a ContentProviderConnection";
8658            Slog.w(TAG, msg);
8659            throw new IllegalArgumentException(msg);
8660        }
8661        if (conn == null) {
8662            throw new NullPointerException("connection is null");
8663        }
8664
8665        synchronized (this) {
8666            if (stable > 0) {
8667                conn.numStableIncs += stable;
8668            }
8669            stable = conn.stableCount + stable;
8670            if (stable < 0) {
8671                throw new IllegalStateException("stableCount < 0: " + stable);
8672            }
8673
8674            if (unstable > 0) {
8675                conn.numUnstableIncs += unstable;
8676            }
8677            unstable = conn.unstableCount + unstable;
8678            if (unstable < 0) {
8679                throw new IllegalStateException("unstableCount < 0: " + unstable);
8680            }
8681
8682            if ((stable+unstable) <= 0) {
8683                throw new IllegalStateException("ref counts can't go to zero here: stable="
8684                        + stable + " unstable=" + unstable);
8685            }
8686            conn.stableCount = stable;
8687            conn.unstableCount = unstable;
8688            return !conn.dead;
8689        }
8690    }
8691
8692    public void unstableProviderDied(IBinder connection) {
8693        ContentProviderConnection conn;
8694        try {
8695            conn = (ContentProviderConnection)connection;
8696        } catch (ClassCastException e) {
8697            String msg ="refContentProvider: " + connection
8698                    + " not a ContentProviderConnection";
8699            Slog.w(TAG, msg);
8700            throw new IllegalArgumentException(msg);
8701        }
8702        if (conn == null) {
8703            throw new NullPointerException("connection is null");
8704        }
8705
8706        // Safely retrieve the content provider associated with the connection.
8707        IContentProvider provider;
8708        synchronized (this) {
8709            provider = conn.provider.provider;
8710        }
8711
8712        if (provider == null) {
8713            // Um, yeah, we're way ahead of you.
8714            return;
8715        }
8716
8717        // Make sure the caller is being honest with us.
8718        if (provider.asBinder().pingBinder()) {
8719            // Er, no, still looks good to us.
8720            synchronized (this) {
8721                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8722                        + " says " + conn + " died, but we don't agree");
8723                return;
8724            }
8725        }
8726
8727        // Well look at that!  It's dead!
8728        synchronized (this) {
8729            if (conn.provider.provider != provider) {
8730                // But something changed...  good enough.
8731                return;
8732            }
8733
8734            ProcessRecord proc = conn.provider.proc;
8735            if (proc == null || proc.thread == null) {
8736                // Seems like the process is already cleaned up.
8737                return;
8738            }
8739
8740            // As far as we're concerned, this is just like receiving a
8741            // death notification...  just a bit prematurely.
8742            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8743                    + ") early provider death");
8744            final long ident = Binder.clearCallingIdentity();
8745            try {
8746                appDiedLocked(proc, proc.pid, proc.thread);
8747            } finally {
8748                Binder.restoreCallingIdentity(ident);
8749            }
8750        }
8751    }
8752
8753    @Override
8754    public void appNotRespondingViaProvider(IBinder connection) {
8755        enforceCallingPermission(
8756                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8757
8758        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8759        if (conn == null) {
8760            Slog.w(TAG, "ContentProviderConnection is null");
8761            return;
8762        }
8763
8764        final ProcessRecord host = conn.provider.proc;
8765        if (host == null) {
8766            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8767            return;
8768        }
8769
8770        final long token = Binder.clearCallingIdentity();
8771        try {
8772            appNotResponding(host, null, null, false, "ContentProvider not responding");
8773        } finally {
8774            Binder.restoreCallingIdentity(token);
8775        }
8776    }
8777
8778    public final void installSystemProviders() {
8779        List<ProviderInfo> providers;
8780        synchronized (this) {
8781            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8782            providers = generateApplicationProvidersLocked(app);
8783            if (providers != null) {
8784                for (int i=providers.size()-1; i>=0; i--) {
8785                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8786                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8787                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8788                                + ": not system .apk");
8789                        providers.remove(i);
8790                    }
8791                }
8792            }
8793        }
8794        if (providers != null) {
8795            mSystemThread.installSystemProviders(providers);
8796        }
8797
8798        mCoreSettingsObserver = new CoreSettingsObserver(this);
8799
8800        mUsageStatsService.monitorPackages();
8801    }
8802
8803    /**
8804     * Allows app to retrieve the MIME type of a URI without having permission
8805     * to access its content provider.
8806     *
8807     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8808     *
8809     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8810     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8811     */
8812    public String getProviderMimeType(Uri uri, int userId) {
8813        enforceNotIsolatedCaller("getProviderMimeType");
8814        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8815                userId, false, ALLOW_NON_FULL_IN_PROFILE, "getProviderMimeType", null);
8816        final String name = uri.getAuthority();
8817        final long ident = Binder.clearCallingIdentity();
8818        ContentProviderHolder holder = null;
8819
8820        try {
8821            holder = getContentProviderExternalUnchecked(name, null, userId);
8822            if (holder != null) {
8823                return holder.provider.getType(uri);
8824            }
8825        } catch (RemoteException e) {
8826            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8827            return null;
8828        } finally {
8829            if (holder != null) {
8830                removeContentProviderExternalUnchecked(name, null, userId);
8831            }
8832            Binder.restoreCallingIdentity(ident);
8833        }
8834
8835        return null;
8836    }
8837
8838    // =========================================================
8839    // GLOBAL MANAGEMENT
8840    // =========================================================
8841
8842    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8843            boolean isolated) {
8844        String proc = customProcess != null ? customProcess : info.processName;
8845        BatteryStatsImpl.Uid.Proc ps = null;
8846        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8847        int uid = info.uid;
8848        if (isolated) {
8849            int userId = UserHandle.getUserId(uid);
8850            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8851            while (true) {
8852                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8853                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8854                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8855                }
8856                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8857                mNextIsolatedProcessUid++;
8858                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8859                    // No process for this uid, use it.
8860                    break;
8861                }
8862                stepsLeft--;
8863                if (stepsLeft <= 0) {
8864                    return null;
8865                }
8866            }
8867        }
8868        return new ProcessRecord(stats, info, proc, uid);
8869    }
8870
8871    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8872            String abiOverride) {
8873        ProcessRecord app;
8874        if (!isolated) {
8875            app = getProcessRecordLocked(info.processName, info.uid, true);
8876        } else {
8877            app = null;
8878        }
8879
8880        if (app == null) {
8881            app = newProcessRecordLocked(info, null, isolated);
8882            mProcessNames.put(info.processName, app.uid, app);
8883            if (isolated) {
8884                mIsolatedProcesses.put(app.uid, app);
8885            }
8886            updateLruProcessLocked(app, false, null);
8887            updateOomAdjLocked();
8888        }
8889
8890        // This package really, really can not be stopped.
8891        try {
8892            AppGlobals.getPackageManager().setPackageStoppedState(
8893                    info.packageName, false, UserHandle.getUserId(app.uid));
8894        } catch (RemoteException e) {
8895        } catch (IllegalArgumentException e) {
8896            Slog.w(TAG, "Failed trying to unstop package "
8897                    + info.packageName + ": " + e);
8898        }
8899
8900        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8901                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8902            app.persistent = true;
8903            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8904        }
8905        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8906            mPersistentStartingProcesses.add(app);
8907            startProcessLocked(app, "added application", app.processName,
8908                    abiOverride);
8909        }
8910
8911        return app;
8912    }
8913
8914    public void unhandledBack() {
8915        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8916                "unhandledBack()");
8917
8918        synchronized(this) {
8919            final long origId = Binder.clearCallingIdentity();
8920            try {
8921                getFocusedStack().unhandledBackLocked();
8922            } finally {
8923                Binder.restoreCallingIdentity(origId);
8924            }
8925        }
8926    }
8927
8928    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8929        enforceNotIsolatedCaller("openContentUri");
8930        final int userId = UserHandle.getCallingUserId();
8931        String name = uri.getAuthority();
8932        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8933        ParcelFileDescriptor pfd = null;
8934        if (cph != null) {
8935            // We record the binder invoker's uid in thread-local storage before
8936            // going to the content provider to open the file.  Later, in the code
8937            // that handles all permissions checks, we look for this uid and use
8938            // that rather than the Activity Manager's own uid.  The effect is that
8939            // we do the check against the caller's permissions even though it looks
8940            // to the content provider like the Activity Manager itself is making
8941            // the request.
8942            sCallerIdentity.set(new Identity(
8943                    Binder.getCallingPid(), Binder.getCallingUid()));
8944            try {
8945                pfd = cph.provider.openFile(null, uri, "r", null);
8946            } catch (FileNotFoundException e) {
8947                // do nothing; pfd will be returned null
8948            } finally {
8949                // Ensure that whatever happens, we clean up the identity state
8950                sCallerIdentity.remove();
8951            }
8952
8953            // We've got the fd now, so we're done with the provider.
8954            removeContentProviderExternalUnchecked(name, null, userId);
8955        } else {
8956            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8957        }
8958        return pfd;
8959    }
8960
8961    // Actually is sleeping or shutting down or whatever else in the future
8962    // is an inactive state.
8963    public boolean isSleepingOrShuttingDown() {
8964        return mSleeping || mShuttingDown;
8965    }
8966
8967    public boolean isSleeping() {
8968        return mSleeping;
8969    }
8970
8971    void goingToSleep() {
8972        synchronized(this) {
8973            mWentToSleep = true;
8974            updateEventDispatchingLocked();
8975            goToSleepIfNeededLocked();
8976        }
8977    }
8978
8979    void finishRunningVoiceLocked() {
8980        if (mRunningVoice) {
8981            mRunningVoice = false;
8982            goToSleepIfNeededLocked();
8983        }
8984    }
8985
8986    void goToSleepIfNeededLocked() {
8987        if (mWentToSleep && !mRunningVoice) {
8988            if (!mSleeping) {
8989                mSleeping = true;
8990                mStackSupervisor.goingToSleepLocked();
8991
8992                // Initialize the wake times of all processes.
8993                checkExcessivePowerUsageLocked(false);
8994                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8995                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8996                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8997            }
8998        }
8999    }
9000
9001    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9002        mTaskPersister.notify(task, flush);
9003    }
9004
9005    @Override
9006    public boolean shutdown(int timeout) {
9007        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9008                != PackageManager.PERMISSION_GRANTED) {
9009            throw new SecurityException("Requires permission "
9010                    + android.Manifest.permission.SHUTDOWN);
9011        }
9012
9013        boolean timedout = false;
9014
9015        synchronized(this) {
9016            mShuttingDown = true;
9017            updateEventDispatchingLocked();
9018            timedout = mStackSupervisor.shutdownLocked(timeout);
9019        }
9020
9021        mAppOpsService.shutdown();
9022        mUsageStatsService.shutdown();
9023        mBatteryStatsService.shutdown();
9024        synchronized (this) {
9025            mProcessStats.shutdownLocked();
9026        }
9027        notifyTaskPersisterLocked(null, true);
9028
9029        return timedout;
9030    }
9031
9032    public final void activitySlept(IBinder token) {
9033        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9034
9035        final long origId = Binder.clearCallingIdentity();
9036
9037        synchronized (this) {
9038            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9039            if (r != null) {
9040                mStackSupervisor.activitySleptLocked(r);
9041            }
9042        }
9043
9044        Binder.restoreCallingIdentity(origId);
9045    }
9046
9047    void logLockScreen(String msg) {
9048        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9049                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9050                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
9051                mStackSupervisor.mDismissKeyguardOnNextActivity);
9052    }
9053
9054    private void comeOutOfSleepIfNeededLocked() {
9055        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9056            if (mSleeping) {
9057                mSleeping = false;
9058                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9059            }
9060        }
9061    }
9062
9063    void wakingUp() {
9064        synchronized(this) {
9065            mWentToSleep = false;
9066            updateEventDispatchingLocked();
9067            comeOutOfSleepIfNeededLocked();
9068        }
9069    }
9070
9071    void startRunningVoiceLocked() {
9072        if (!mRunningVoice) {
9073            mRunningVoice = true;
9074            comeOutOfSleepIfNeededLocked();
9075        }
9076    }
9077
9078    private void updateEventDispatchingLocked() {
9079        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9080    }
9081
9082    public void setLockScreenShown(boolean shown) {
9083        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9084                != PackageManager.PERMISSION_GRANTED) {
9085            throw new SecurityException("Requires permission "
9086                    + android.Manifest.permission.DEVICE_POWER);
9087        }
9088
9089        synchronized(this) {
9090            long ident = Binder.clearCallingIdentity();
9091            try {
9092                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9093                mLockScreenShown = shown;
9094                comeOutOfSleepIfNeededLocked();
9095            } finally {
9096                Binder.restoreCallingIdentity(ident);
9097            }
9098        }
9099    }
9100
9101    public void stopAppSwitches() {
9102        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9103                != PackageManager.PERMISSION_GRANTED) {
9104            throw new SecurityException("Requires permission "
9105                    + android.Manifest.permission.STOP_APP_SWITCHES);
9106        }
9107
9108        synchronized(this) {
9109            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9110                    + APP_SWITCH_DELAY_TIME;
9111            mDidAppSwitch = false;
9112            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9113            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9114            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9115        }
9116    }
9117
9118    public void resumeAppSwitches() {
9119        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9120                != PackageManager.PERMISSION_GRANTED) {
9121            throw new SecurityException("Requires permission "
9122                    + android.Manifest.permission.STOP_APP_SWITCHES);
9123        }
9124
9125        synchronized(this) {
9126            // Note that we don't execute any pending app switches... we will
9127            // let those wait until either the timeout, or the next start
9128            // activity request.
9129            mAppSwitchesAllowedTime = 0;
9130        }
9131    }
9132
9133    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9134            String name) {
9135        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9136            return true;
9137        }
9138
9139        final int perm = checkComponentPermission(
9140                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9141                callingUid, -1, true);
9142        if (perm == PackageManager.PERMISSION_GRANTED) {
9143            return true;
9144        }
9145
9146        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9147        return false;
9148    }
9149
9150    public void setDebugApp(String packageName, boolean waitForDebugger,
9151            boolean persistent) {
9152        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9153                "setDebugApp()");
9154
9155        long ident = Binder.clearCallingIdentity();
9156        try {
9157            // Note that this is not really thread safe if there are multiple
9158            // callers into it at the same time, but that's not a situation we
9159            // care about.
9160            if (persistent) {
9161                final ContentResolver resolver = mContext.getContentResolver();
9162                Settings.Global.putString(
9163                    resolver, Settings.Global.DEBUG_APP,
9164                    packageName);
9165                Settings.Global.putInt(
9166                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9167                    waitForDebugger ? 1 : 0);
9168            }
9169
9170            synchronized (this) {
9171                if (!persistent) {
9172                    mOrigDebugApp = mDebugApp;
9173                    mOrigWaitForDebugger = mWaitForDebugger;
9174                }
9175                mDebugApp = packageName;
9176                mWaitForDebugger = waitForDebugger;
9177                mDebugTransient = !persistent;
9178                if (packageName != null) {
9179                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9180                            false, UserHandle.USER_ALL, "set debug app");
9181                }
9182            }
9183        } finally {
9184            Binder.restoreCallingIdentity(ident);
9185        }
9186    }
9187
9188    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9189        synchronized (this) {
9190            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9191            if (!isDebuggable) {
9192                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9193                    throw new SecurityException("Process not debuggable: " + app.packageName);
9194                }
9195            }
9196
9197            mOpenGlTraceApp = processName;
9198        }
9199    }
9200
9201    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9202            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9203        synchronized (this) {
9204            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9205            if (!isDebuggable) {
9206                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9207                    throw new SecurityException("Process not debuggable: " + app.packageName);
9208                }
9209            }
9210            mProfileApp = processName;
9211            mProfileFile = profileFile;
9212            if (mProfileFd != null) {
9213                try {
9214                    mProfileFd.close();
9215                } catch (IOException e) {
9216                }
9217                mProfileFd = null;
9218            }
9219            mProfileFd = profileFd;
9220            mProfileType = 0;
9221            mAutoStopProfiler = autoStopProfiler;
9222        }
9223    }
9224
9225    @Override
9226    public void setAlwaysFinish(boolean enabled) {
9227        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9228                "setAlwaysFinish()");
9229
9230        Settings.Global.putInt(
9231                mContext.getContentResolver(),
9232                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9233
9234        synchronized (this) {
9235            mAlwaysFinishActivities = enabled;
9236        }
9237    }
9238
9239    @Override
9240    public void setActivityController(IActivityController controller) {
9241        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9242                "setActivityController()");
9243        synchronized (this) {
9244            mController = controller;
9245            Watchdog.getInstance().setActivityController(controller);
9246        }
9247    }
9248
9249    @Override
9250    public void setUserIsMonkey(boolean userIsMonkey) {
9251        synchronized (this) {
9252            synchronized (mPidsSelfLocked) {
9253                final int callingPid = Binder.getCallingPid();
9254                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9255                if (precessRecord == null) {
9256                    throw new SecurityException("Unknown process: " + callingPid);
9257                }
9258                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9259                    throw new SecurityException("Only an instrumentation process "
9260                            + "with a UiAutomation can call setUserIsMonkey");
9261                }
9262            }
9263            mUserIsMonkey = userIsMonkey;
9264        }
9265    }
9266
9267    @Override
9268    public boolean isUserAMonkey() {
9269        synchronized (this) {
9270            // If there is a controller also implies the user is a monkey.
9271            return (mUserIsMonkey || mController != null);
9272        }
9273    }
9274
9275    public void requestBugReport() {
9276        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9277        SystemProperties.set("ctl.start", "bugreport");
9278    }
9279
9280    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9281        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9282    }
9283
9284    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9285        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9286            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9287        }
9288        return KEY_DISPATCHING_TIMEOUT;
9289    }
9290
9291    @Override
9292    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9293        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9294                != PackageManager.PERMISSION_GRANTED) {
9295            throw new SecurityException("Requires permission "
9296                    + android.Manifest.permission.FILTER_EVENTS);
9297        }
9298        ProcessRecord proc;
9299        long timeout;
9300        synchronized (this) {
9301            synchronized (mPidsSelfLocked) {
9302                proc = mPidsSelfLocked.get(pid);
9303            }
9304            timeout = getInputDispatchingTimeoutLocked(proc);
9305        }
9306
9307        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9308            return -1;
9309        }
9310
9311        return timeout;
9312    }
9313
9314    /**
9315     * Handle input dispatching timeouts.
9316     * Returns whether input dispatching should be aborted or not.
9317     */
9318    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9319            final ActivityRecord activity, final ActivityRecord parent,
9320            final boolean aboveSystem, String reason) {
9321        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9322                != PackageManager.PERMISSION_GRANTED) {
9323            throw new SecurityException("Requires permission "
9324                    + android.Manifest.permission.FILTER_EVENTS);
9325        }
9326
9327        final String annotation;
9328        if (reason == null) {
9329            annotation = "Input dispatching timed out";
9330        } else {
9331            annotation = "Input dispatching timed out (" + reason + ")";
9332        }
9333
9334        if (proc != null) {
9335            synchronized (this) {
9336                if (proc.debugging) {
9337                    return false;
9338                }
9339
9340                if (mDidDexOpt) {
9341                    // Give more time since we were dexopting.
9342                    mDidDexOpt = false;
9343                    return false;
9344                }
9345
9346                if (proc.instrumentationClass != null) {
9347                    Bundle info = new Bundle();
9348                    info.putString("shortMsg", "keyDispatchingTimedOut");
9349                    info.putString("longMsg", annotation);
9350                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9351                    return true;
9352                }
9353            }
9354            mHandler.post(new Runnable() {
9355                @Override
9356                public void run() {
9357                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9358                }
9359            });
9360        }
9361
9362        return true;
9363    }
9364
9365    public Bundle getAssistContextExtras(int requestType) {
9366        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9367                "getAssistContextExtras()");
9368        PendingAssistExtras pae;
9369        Bundle extras = new Bundle();
9370        synchronized (this) {
9371            ActivityRecord activity = getFocusedStack().mResumedActivity;
9372            if (activity == null) {
9373                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9374                return null;
9375            }
9376            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9377            if (activity.app == null || activity.app.thread == null) {
9378                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9379                return extras;
9380            }
9381            if (activity.app.pid == Binder.getCallingPid()) {
9382                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9383                return extras;
9384            }
9385            pae = new PendingAssistExtras(activity);
9386            try {
9387                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9388                        requestType);
9389                mPendingAssistExtras.add(pae);
9390                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9391            } catch (RemoteException e) {
9392                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9393                return extras;
9394            }
9395        }
9396        synchronized (pae) {
9397            while (!pae.haveResult) {
9398                try {
9399                    pae.wait();
9400                } catch (InterruptedException e) {
9401                }
9402            }
9403            if (pae.result != null) {
9404                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9405            }
9406        }
9407        synchronized (this) {
9408            mPendingAssistExtras.remove(pae);
9409            mHandler.removeCallbacks(pae);
9410        }
9411        return extras;
9412    }
9413
9414    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9415        PendingAssistExtras pae = (PendingAssistExtras)token;
9416        synchronized (pae) {
9417            pae.result = extras;
9418            pae.haveResult = true;
9419            pae.notifyAll();
9420        }
9421    }
9422
9423    public void registerProcessObserver(IProcessObserver observer) {
9424        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9425                "registerProcessObserver()");
9426        synchronized (this) {
9427            mProcessObservers.register(observer);
9428        }
9429    }
9430
9431    @Override
9432    public void unregisterProcessObserver(IProcessObserver observer) {
9433        synchronized (this) {
9434            mProcessObservers.unregister(observer);
9435        }
9436    }
9437
9438    @Override
9439    public boolean convertFromTranslucent(IBinder token) {
9440        final long origId = Binder.clearCallingIdentity();
9441        try {
9442            synchronized (this) {
9443                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9444                if (r == null) {
9445                    return false;
9446                }
9447                if (r.changeWindowTranslucency(true)) {
9448                    mWindowManager.setAppFullscreen(token, true);
9449                    r.task.stack.releaseMediaResources();
9450                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9451                    return true;
9452                }
9453                return false;
9454            }
9455        } finally {
9456            Binder.restoreCallingIdentity(origId);
9457        }
9458    }
9459
9460    @Override
9461    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9462        final long origId = Binder.clearCallingIdentity();
9463        try {
9464            synchronized (this) {
9465                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9466                if (r == null) {
9467                    return false;
9468                }
9469                if (r.changeWindowTranslucency(false)) {
9470                    r.task.stack.convertToTranslucent(r, options);
9471                    mWindowManager.setAppFullscreen(token, false);
9472                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9473                    return true;
9474                } else {
9475                    r.task.stack.mReturningActivityOptions = options;
9476                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9477                    return false;
9478                }
9479            }
9480        } finally {
9481            Binder.restoreCallingIdentity(origId);
9482        }
9483    }
9484
9485    @Override
9486    public boolean setMediaPlaying(IBinder token, boolean playing) {
9487        final long origId = Binder.clearCallingIdentity();
9488        try {
9489            synchronized (this) {
9490                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9491                if (r != null) {
9492                    return mStackSupervisor.setMediaPlayingLocked(r, playing);
9493                }
9494            }
9495            return false;
9496        } finally {
9497            Binder.restoreCallingIdentity(origId);
9498        }
9499    }
9500
9501    @Override
9502    public boolean isBackgroundMediaPlaying(IBinder token) {
9503        final long origId = Binder.clearCallingIdentity();
9504        try {
9505            synchronized (this) {
9506                final ActivityStack stack = ActivityRecord.getStackLocked(token);
9507                final boolean playing = stack == null ? false : stack.isMediaPlaying();
9508                if (ActivityStackSupervisor.DEBUG_MEDIA_VISIBILITY) Slog.d(TAG,
9509                        "isBackgroundMediaPlaying: stack=" + stack + " playing=" + playing);
9510                return playing;
9511            }
9512        } finally {
9513            Binder.restoreCallingIdentity(origId);
9514        }
9515    }
9516
9517    @Override
9518    public ActivityOptions getActivityOptions(IBinder token) {
9519        final long origId = Binder.clearCallingIdentity();
9520        try {
9521            synchronized (this) {
9522                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9523                if (r != null) {
9524                    final ActivityOptions activityOptions = r.pendingOptions;
9525                    r.pendingOptions = null;
9526                    return activityOptions;
9527                }
9528                return null;
9529            }
9530        } finally {
9531            Binder.restoreCallingIdentity(origId);
9532        }
9533    }
9534
9535    @Override
9536    public void setImmersive(IBinder token, boolean immersive) {
9537        synchronized(this) {
9538            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9539            if (r == null) {
9540                throw new IllegalArgumentException();
9541            }
9542            r.immersive = immersive;
9543
9544            // update associated state if we're frontmost
9545            if (r == mFocusedActivity) {
9546                if (DEBUG_IMMERSIVE) {
9547                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9548                }
9549                applyUpdateLockStateLocked(r);
9550            }
9551        }
9552    }
9553
9554    @Override
9555    public boolean isImmersive(IBinder token) {
9556        synchronized (this) {
9557            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9558            if (r == null) {
9559                throw new IllegalArgumentException();
9560            }
9561            return r.immersive;
9562        }
9563    }
9564
9565    public boolean isTopActivityImmersive() {
9566        enforceNotIsolatedCaller("startActivity");
9567        synchronized (this) {
9568            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9569            return (r != null) ? r.immersive : false;
9570        }
9571    }
9572
9573    @Override
9574    public boolean isTopOfTask(IBinder token) {
9575        synchronized (this) {
9576            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9577            if (r == null) {
9578                throw new IllegalArgumentException();
9579            }
9580            return r.task.getTopActivity() == r;
9581        }
9582    }
9583
9584    public final void enterSafeMode() {
9585        synchronized(this) {
9586            // It only makes sense to do this before the system is ready
9587            // and started launching other packages.
9588            if (!mSystemReady) {
9589                try {
9590                    AppGlobals.getPackageManager().enterSafeMode();
9591                } catch (RemoteException e) {
9592                }
9593            }
9594
9595            mSafeMode = true;
9596        }
9597    }
9598
9599    public final void showSafeModeOverlay() {
9600        View v = LayoutInflater.from(mContext).inflate(
9601                com.android.internal.R.layout.safe_mode, null);
9602        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9603        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9604        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9605        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9606        lp.gravity = Gravity.BOTTOM | Gravity.START;
9607        lp.format = v.getBackground().getOpacity();
9608        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9609                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9610        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9611        ((WindowManager)mContext.getSystemService(
9612                Context.WINDOW_SERVICE)).addView(v, lp);
9613    }
9614
9615    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9616        if (!(sender instanceof PendingIntentRecord)) {
9617            return;
9618        }
9619        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9620        synchronized (stats) {
9621            if (mBatteryStatsService.isOnBattery()) {
9622                mBatteryStatsService.enforceCallingPermission();
9623                PendingIntentRecord rec = (PendingIntentRecord)sender;
9624                int MY_UID = Binder.getCallingUid();
9625                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9626                BatteryStatsImpl.Uid.Pkg pkg =
9627                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9628                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9629                pkg.incWakeupsLocked();
9630            }
9631        }
9632    }
9633
9634    public boolean killPids(int[] pids, String pReason, boolean secure) {
9635        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9636            throw new SecurityException("killPids only available to the system");
9637        }
9638        String reason = (pReason == null) ? "Unknown" : pReason;
9639        // XXX Note: don't acquire main activity lock here, because the window
9640        // manager calls in with its locks held.
9641
9642        boolean killed = false;
9643        synchronized (mPidsSelfLocked) {
9644            int[] types = new int[pids.length];
9645            int worstType = 0;
9646            for (int i=0; i<pids.length; i++) {
9647                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9648                if (proc != null) {
9649                    int type = proc.setAdj;
9650                    types[i] = type;
9651                    if (type > worstType) {
9652                        worstType = type;
9653                    }
9654                }
9655            }
9656
9657            // If the worst oom_adj is somewhere in the cached proc LRU range,
9658            // then constrain it so we will kill all cached procs.
9659            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9660                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9661                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9662            }
9663
9664            // If this is not a secure call, don't let it kill processes that
9665            // are important.
9666            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9667                worstType = ProcessList.SERVICE_ADJ;
9668            }
9669
9670            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9671            for (int i=0; i<pids.length; i++) {
9672                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9673                if (proc == null) {
9674                    continue;
9675                }
9676                int adj = proc.setAdj;
9677                if (adj >= worstType && !proc.killedByAm) {
9678                    killUnneededProcessLocked(proc, reason);
9679                    killed = true;
9680                }
9681            }
9682        }
9683        return killed;
9684    }
9685
9686    @Override
9687    public void killUid(int uid, String reason) {
9688        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9689            throw new SecurityException("killUid only available to the system");
9690        }
9691        synchronized (this) {
9692            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9693                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9694                    reason != null ? reason : "kill uid");
9695        }
9696    }
9697
9698    @Override
9699    public boolean killProcessesBelowForeground(String reason) {
9700        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9701            throw new SecurityException("killProcessesBelowForeground() only available to system");
9702        }
9703
9704        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9705    }
9706
9707    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9708        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9709            throw new SecurityException("killProcessesBelowAdj() only available to system");
9710        }
9711
9712        boolean killed = false;
9713        synchronized (mPidsSelfLocked) {
9714            final int size = mPidsSelfLocked.size();
9715            for (int i = 0; i < size; i++) {
9716                final int pid = mPidsSelfLocked.keyAt(i);
9717                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9718                if (proc == null) continue;
9719
9720                final int adj = proc.setAdj;
9721                if (adj > belowAdj && !proc.killedByAm) {
9722                    killUnneededProcessLocked(proc, reason);
9723                    killed = true;
9724                }
9725            }
9726        }
9727        return killed;
9728    }
9729
9730    @Override
9731    public void hang(final IBinder who, boolean allowRestart) {
9732        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9733                != PackageManager.PERMISSION_GRANTED) {
9734            throw new SecurityException("Requires permission "
9735                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9736        }
9737
9738        final IBinder.DeathRecipient death = new DeathRecipient() {
9739            @Override
9740            public void binderDied() {
9741                synchronized (this) {
9742                    notifyAll();
9743                }
9744            }
9745        };
9746
9747        try {
9748            who.linkToDeath(death, 0);
9749        } catch (RemoteException e) {
9750            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9751            return;
9752        }
9753
9754        synchronized (this) {
9755            Watchdog.getInstance().setAllowRestart(allowRestart);
9756            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9757            synchronized (death) {
9758                while (who.isBinderAlive()) {
9759                    try {
9760                        death.wait();
9761                    } catch (InterruptedException e) {
9762                    }
9763                }
9764            }
9765            Watchdog.getInstance().setAllowRestart(true);
9766        }
9767    }
9768
9769    @Override
9770    public void restart() {
9771        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9772                != PackageManager.PERMISSION_GRANTED) {
9773            throw new SecurityException("Requires permission "
9774                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9775        }
9776
9777        Log.i(TAG, "Sending shutdown broadcast...");
9778
9779        BroadcastReceiver br = new BroadcastReceiver() {
9780            @Override public void onReceive(Context context, Intent intent) {
9781                // Now the broadcast is done, finish up the low-level shutdown.
9782                Log.i(TAG, "Shutting down activity manager...");
9783                shutdown(10000);
9784                Log.i(TAG, "Shutdown complete, restarting!");
9785                Process.killProcess(Process.myPid());
9786                System.exit(10);
9787            }
9788        };
9789
9790        // First send the high-level shut down broadcast.
9791        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9792        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9793        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9794        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9795        mContext.sendOrderedBroadcastAsUser(intent,
9796                UserHandle.ALL, null, br, mHandler, 0, null, null);
9797        */
9798        br.onReceive(mContext, intent);
9799    }
9800
9801    private long getLowRamTimeSinceIdle(long now) {
9802        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9803    }
9804
9805    @Override
9806    public void performIdleMaintenance() {
9807        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9808                != PackageManager.PERMISSION_GRANTED) {
9809            throw new SecurityException("Requires permission "
9810                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9811        }
9812
9813        synchronized (this) {
9814            final long now = SystemClock.uptimeMillis();
9815            final long timeSinceLastIdle = now - mLastIdleTime;
9816            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9817            mLastIdleTime = now;
9818            mLowRamTimeSinceLastIdle = 0;
9819            if (mLowRamStartTime != 0) {
9820                mLowRamStartTime = now;
9821            }
9822
9823            StringBuilder sb = new StringBuilder(128);
9824            sb.append("Idle maintenance over ");
9825            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9826            sb.append(" low RAM for ");
9827            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9828            Slog.i(TAG, sb.toString());
9829
9830            // If at least 1/3 of our time since the last idle period has been spent
9831            // with RAM low, then we want to kill processes.
9832            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9833
9834            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9835                ProcessRecord proc = mLruProcesses.get(i);
9836                if (proc.notCachedSinceIdle) {
9837                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9838                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9839                        if (doKilling && proc.initialIdlePss != 0
9840                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9841                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9842                                    + " from " + proc.initialIdlePss + ")");
9843                        }
9844                    }
9845                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9846                    proc.notCachedSinceIdle = true;
9847                    proc.initialIdlePss = 0;
9848                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9849                            isSleeping(), now);
9850                }
9851            }
9852
9853            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9854            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9855        }
9856    }
9857
9858    private void retrieveSettings() {
9859        final ContentResolver resolver = mContext.getContentResolver();
9860        String debugApp = Settings.Global.getString(
9861            resolver, Settings.Global.DEBUG_APP);
9862        boolean waitForDebugger = Settings.Global.getInt(
9863            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9864        boolean alwaysFinishActivities = Settings.Global.getInt(
9865            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9866        boolean forceRtl = Settings.Global.getInt(
9867                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9868        // Transfer any global setting for forcing RTL layout, into a System Property
9869        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9870
9871        Configuration configuration = new Configuration();
9872        Settings.System.getConfiguration(resolver, configuration);
9873        if (forceRtl) {
9874            // This will take care of setting the correct layout direction flags
9875            configuration.setLayoutDirection(configuration.locale);
9876        }
9877
9878        synchronized (this) {
9879            mDebugApp = mOrigDebugApp = debugApp;
9880            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9881            mAlwaysFinishActivities = alwaysFinishActivities;
9882            // This happens before any activities are started, so we can
9883            // change mConfiguration in-place.
9884            updateConfigurationLocked(configuration, null, false, true);
9885            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9886        }
9887    }
9888
9889    public boolean testIsSystemReady() {
9890        // no need to synchronize(this) just to read & return the value
9891        return mSystemReady;
9892    }
9893
9894    private static File getCalledPreBootReceiversFile() {
9895        File dataDir = Environment.getDataDirectory();
9896        File systemDir = new File(dataDir, "system");
9897        File fname = new File(systemDir, "called_pre_boots.dat");
9898        return fname;
9899    }
9900
9901    static final int LAST_DONE_VERSION = 10000;
9902
9903    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9904        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9905        File file = getCalledPreBootReceiversFile();
9906        FileInputStream fis = null;
9907        try {
9908            fis = new FileInputStream(file);
9909            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9910            int fvers = dis.readInt();
9911            if (fvers == LAST_DONE_VERSION) {
9912                String vers = dis.readUTF();
9913                String codename = dis.readUTF();
9914                String build = dis.readUTF();
9915                if (android.os.Build.VERSION.RELEASE.equals(vers)
9916                        && android.os.Build.VERSION.CODENAME.equals(codename)
9917                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9918                    int num = dis.readInt();
9919                    while (num > 0) {
9920                        num--;
9921                        String pkg = dis.readUTF();
9922                        String cls = dis.readUTF();
9923                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9924                    }
9925                }
9926            }
9927        } catch (FileNotFoundException e) {
9928        } catch (IOException e) {
9929            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9930        } finally {
9931            if (fis != null) {
9932                try {
9933                    fis.close();
9934                } catch (IOException e) {
9935                }
9936            }
9937        }
9938        return lastDoneReceivers;
9939    }
9940
9941    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9942        File file = getCalledPreBootReceiversFile();
9943        FileOutputStream fos = null;
9944        DataOutputStream dos = null;
9945        try {
9946            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9947            fos = new FileOutputStream(file);
9948            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9949            dos.writeInt(LAST_DONE_VERSION);
9950            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9951            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9952            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9953            dos.writeInt(list.size());
9954            for (int i=0; i<list.size(); i++) {
9955                dos.writeUTF(list.get(i).getPackageName());
9956                dos.writeUTF(list.get(i).getClassName());
9957            }
9958        } catch (IOException e) {
9959            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9960            file.delete();
9961        } finally {
9962            FileUtils.sync(fos);
9963            if (dos != null) {
9964                try {
9965                    dos.close();
9966                } catch (IOException e) {
9967                    // TODO Auto-generated catch block
9968                    e.printStackTrace();
9969                }
9970            }
9971        }
9972    }
9973
9974    public void systemReady(final Runnable goingCallback) {
9975        synchronized(this) {
9976            if (mSystemReady) {
9977                if (goingCallback != null) goingCallback.run();
9978                return;
9979            }
9980
9981            // Make sure we have the current profile info, since it is needed for
9982            // security checks.
9983            updateCurrentProfileIdsLocked();
9984
9985            if (mRecentTasks == null) {
9986                mRecentTasks = mTaskPersister.restoreTasksLocked();
9987                if (!mRecentTasks.isEmpty()) {
9988                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
9989                }
9990                mTaskPersister.startPersisting();
9991            }
9992
9993            // Check to see if there are any update receivers to run.
9994            if (!mDidUpdate) {
9995                if (mWaitingUpdate) {
9996                    return;
9997                }
9998                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9999                List<ResolveInfo> ris = null;
10000                try {
10001                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
10002                            intent, null, 0, 0);
10003                } catch (RemoteException e) {
10004                }
10005                if (ris != null) {
10006                    for (int i=ris.size()-1; i>=0; i--) {
10007                        if ((ris.get(i).activityInfo.applicationInfo.flags
10008                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
10009                            ris.remove(i);
10010                        }
10011                    }
10012                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10013
10014                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10015
10016                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10017                    for (int i=0; i<ris.size(); i++) {
10018                        ActivityInfo ai = ris.get(i).activityInfo;
10019                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
10020                        if (lastDoneReceivers.contains(comp)) {
10021                            // We already did the pre boot receiver for this app with the current
10022                            // platform version, so don't do it again...
10023                            ris.remove(i);
10024                            i--;
10025                            // ...however, do keep it as one that has been done, so we don't
10026                            // forget about it when rewriting the file of last done receivers.
10027                            doneReceivers.add(comp);
10028                        }
10029                    }
10030
10031                    final int[] users = getUsersLocked();
10032                    for (int i=0; i<ris.size(); i++) {
10033                        ActivityInfo ai = ris.get(i).activityInfo;
10034                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
10035                        doneReceivers.add(comp);
10036                        intent.setComponent(comp);
10037                        for (int j=0; j<users.length; j++) {
10038                            IIntentReceiver finisher = null;
10039                            if (i == ris.size()-1 && j == users.length-1) {
10040                                finisher = new IIntentReceiver.Stub() {
10041                                    public void performReceive(Intent intent, int resultCode,
10042                                            String data, Bundle extras, boolean ordered,
10043                                            boolean sticky, int sendingUser) {
10044                                        // The raw IIntentReceiver interface is called
10045                                        // with the AM lock held, so redispatch to
10046                                        // execute our code without the lock.
10047                                        mHandler.post(new Runnable() {
10048                                            public void run() {
10049                                                synchronized (ActivityManagerService.this) {
10050                                                    mDidUpdate = true;
10051                                                }
10052                                                writeLastDonePreBootReceivers(doneReceivers);
10053                                                showBootMessage(mContext.getText(
10054                                                        R.string.android_upgrading_complete),
10055                                                        false);
10056                                                systemReady(goingCallback);
10057                                            }
10058                                        });
10059                                    }
10060                                };
10061                            }
10062                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
10063                                    + " for user " + users[j]);
10064                            broadcastIntentLocked(null, null, intent, null, finisher,
10065                                    0, null, null, null, AppOpsManager.OP_NONE,
10066                                    true, false, MY_PID, Process.SYSTEM_UID,
10067                                    users[j]);
10068                            if (finisher != null) {
10069                                mWaitingUpdate = true;
10070                            }
10071                        }
10072                    }
10073                }
10074                if (mWaitingUpdate) {
10075                    return;
10076                }
10077                mDidUpdate = true;
10078            }
10079
10080            mAppOpsService.systemReady();
10081            mUsageStatsService.systemReady();
10082            mSystemReady = true;
10083        }
10084
10085        ArrayList<ProcessRecord> procsToKill = null;
10086        synchronized(mPidsSelfLocked) {
10087            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10088                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10089                if (!isAllowedWhileBooting(proc.info)){
10090                    if (procsToKill == null) {
10091                        procsToKill = new ArrayList<ProcessRecord>();
10092                    }
10093                    procsToKill.add(proc);
10094                }
10095            }
10096        }
10097
10098        synchronized(this) {
10099            if (procsToKill != null) {
10100                for (int i=procsToKill.size()-1; i>=0; i--) {
10101                    ProcessRecord proc = procsToKill.get(i);
10102                    Slog.i(TAG, "Removing system update proc: " + proc);
10103                    removeProcessLocked(proc, true, false, "system update done");
10104                }
10105            }
10106
10107            // Now that we have cleaned up any update processes, we
10108            // are ready to start launching real processes and know that
10109            // we won't trample on them any more.
10110            mProcessesReady = true;
10111        }
10112
10113        Slog.i(TAG, "System now ready");
10114        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10115            SystemClock.uptimeMillis());
10116
10117        synchronized(this) {
10118            // Make sure we have no pre-ready processes sitting around.
10119
10120            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10121                ResolveInfo ri = mContext.getPackageManager()
10122                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10123                                STOCK_PM_FLAGS);
10124                CharSequence errorMsg = null;
10125                if (ri != null) {
10126                    ActivityInfo ai = ri.activityInfo;
10127                    ApplicationInfo app = ai.applicationInfo;
10128                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10129                        mTopAction = Intent.ACTION_FACTORY_TEST;
10130                        mTopData = null;
10131                        mTopComponent = new ComponentName(app.packageName,
10132                                ai.name);
10133                    } else {
10134                        errorMsg = mContext.getResources().getText(
10135                                com.android.internal.R.string.factorytest_not_system);
10136                    }
10137                } else {
10138                    errorMsg = mContext.getResources().getText(
10139                            com.android.internal.R.string.factorytest_no_action);
10140                }
10141                if (errorMsg != null) {
10142                    mTopAction = null;
10143                    mTopData = null;
10144                    mTopComponent = null;
10145                    Message msg = Message.obtain();
10146                    msg.what = SHOW_FACTORY_ERROR_MSG;
10147                    msg.getData().putCharSequence("msg", errorMsg);
10148                    mHandler.sendMessage(msg);
10149                }
10150            }
10151        }
10152
10153        retrieveSettings();
10154
10155        synchronized (this) {
10156            readGrantedUriPermissionsLocked();
10157        }
10158
10159        if (goingCallback != null) goingCallback.run();
10160
10161        mSystemServiceManager.startUser(mCurrentUserId);
10162
10163        synchronized (this) {
10164            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10165                try {
10166                    List apps = AppGlobals.getPackageManager().
10167                        getPersistentApplications(STOCK_PM_FLAGS);
10168                    if (apps != null) {
10169                        int N = apps.size();
10170                        int i;
10171                        for (i=0; i<N; i++) {
10172                            ApplicationInfo info
10173                                = (ApplicationInfo)apps.get(i);
10174                            if (info != null &&
10175                                    !info.packageName.equals("android")) {
10176                                addAppLocked(info, false, null /* ABI override */);
10177                            }
10178                        }
10179                    }
10180                } catch (RemoteException ex) {
10181                    // pm is in same process, this will never happen.
10182                }
10183            }
10184
10185            // Start up initial activity.
10186            mBooting = true;
10187
10188            try {
10189                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10190                    Message msg = Message.obtain();
10191                    msg.what = SHOW_UID_ERROR_MSG;
10192                    mHandler.sendMessage(msg);
10193                }
10194            } catch (RemoteException e) {
10195            }
10196
10197            long ident = Binder.clearCallingIdentity();
10198            try {
10199                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10200                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10201                        | Intent.FLAG_RECEIVER_FOREGROUND);
10202                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10203                broadcastIntentLocked(null, null, intent,
10204                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10205                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10206                intent = new Intent(Intent.ACTION_USER_STARTING);
10207                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10208                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10209                broadcastIntentLocked(null, null, intent,
10210                        null, new IIntentReceiver.Stub() {
10211                            @Override
10212                            public void performReceive(Intent intent, int resultCode, String data,
10213                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10214                                    throws RemoteException {
10215                            }
10216                        }, 0, null, null,
10217                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10218                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10219            } catch (Throwable t) {
10220                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10221            } finally {
10222                Binder.restoreCallingIdentity(ident);
10223            }
10224            mStackSupervisor.resumeTopActivitiesLocked();
10225            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10226        }
10227    }
10228
10229    private boolean makeAppCrashingLocked(ProcessRecord app,
10230            String shortMsg, String longMsg, String stackTrace) {
10231        app.crashing = true;
10232        app.crashingReport = generateProcessError(app,
10233                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10234        startAppProblemLocked(app);
10235        app.stopFreezingAllLocked();
10236        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10237    }
10238
10239    private void makeAppNotRespondingLocked(ProcessRecord app,
10240            String activity, String shortMsg, String longMsg) {
10241        app.notResponding = true;
10242        app.notRespondingReport = generateProcessError(app,
10243                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10244                activity, shortMsg, longMsg, null);
10245        startAppProblemLocked(app);
10246        app.stopFreezingAllLocked();
10247    }
10248
10249    /**
10250     * Generate a process error record, suitable for attachment to a ProcessRecord.
10251     *
10252     * @param app The ProcessRecord in which the error occurred.
10253     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10254     *                      ActivityManager.AppErrorStateInfo
10255     * @param activity The activity associated with the crash, if known.
10256     * @param shortMsg Short message describing the crash.
10257     * @param longMsg Long message describing the crash.
10258     * @param stackTrace Full crash stack trace, may be null.
10259     *
10260     * @return Returns a fully-formed AppErrorStateInfo record.
10261     */
10262    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10263            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10264        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10265
10266        report.condition = condition;
10267        report.processName = app.processName;
10268        report.pid = app.pid;
10269        report.uid = app.info.uid;
10270        report.tag = activity;
10271        report.shortMsg = shortMsg;
10272        report.longMsg = longMsg;
10273        report.stackTrace = stackTrace;
10274
10275        return report;
10276    }
10277
10278    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10279        synchronized (this) {
10280            app.crashing = false;
10281            app.crashingReport = null;
10282            app.notResponding = false;
10283            app.notRespondingReport = null;
10284            if (app.anrDialog == fromDialog) {
10285                app.anrDialog = null;
10286            }
10287            if (app.waitDialog == fromDialog) {
10288                app.waitDialog = null;
10289            }
10290            if (app.pid > 0 && app.pid != MY_PID) {
10291                handleAppCrashLocked(app, null, null, null);
10292                killUnneededProcessLocked(app, "user request after error");
10293            }
10294        }
10295    }
10296
10297    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10298            String stackTrace) {
10299        long now = SystemClock.uptimeMillis();
10300
10301        Long crashTime;
10302        if (!app.isolated) {
10303            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10304        } else {
10305            crashTime = null;
10306        }
10307        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10308            // This process loses!
10309            Slog.w(TAG, "Process " + app.info.processName
10310                    + " has crashed too many times: killing!");
10311            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10312                    app.userId, app.info.processName, app.uid);
10313            mStackSupervisor.handleAppCrashLocked(app);
10314            if (!app.persistent) {
10315                // We don't want to start this process again until the user
10316                // explicitly does so...  but for persistent process, we really
10317                // need to keep it running.  If a persistent process is actually
10318                // repeatedly crashing, then badness for everyone.
10319                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10320                        app.info.processName);
10321                if (!app.isolated) {
10322                    // XXX We don't have a way to mark isolated processes
10323                    // as bad, since they don't have a peristent identity.
10324                    mBadProcesses.put(app.info.processName, app.uid,
10325                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10326                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10327                }
10328                app.bad = true;
10329                app.removed = true;
10330                // Don't let services in this process be restarted and potentially
10331                // annoy the user repeatedly.  Unless it is persistent, since those
10332                // processes run critical code.
10333                removeProcessLocked(app, false, false, "crash");
10334                mStackSupervisor.resumeTopActivitiesLocked();
10335                return false;
10336            }
10337            mStackSupervisor.resumeTopActivitiesLocked();
10338        } else {
10339            mStackSupervisor.finishTopRunningActivityLocked(app);
10340        }
10341
10342        // Bump up the crash count of any services currently running in the proc.
10343        for (int i=app.services.size()-1; i>=0; i--) {
10344            // Any services running in the application need to be placed
10345            // back in the pending list.
10346            ServiceRecord sr = app.services.valueAt(i);
10347            sr.crashCount++;
10348        }
10349
10350        // If the crashing process is what we consider to be the "home process" and it has been
10351        // replaced by a third-party app, clear the package preferred activities from packages
10352        // with a home activity running in the process to prevent a repeatedly crashing app
10353        // from blocking the user to manually clear the list.
10354        final ArrayList<ActivityRecord> activities = app.activities;
10355        if (app == mHomeProcess && activities.size() > 0
10356                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10357            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10358                final ActivityRecord r = activities.get(activityNdx);
10359                if (r.isHomeActivity()) {
10360                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10361                    try {
10362                        ActivityThread.getPackageManager()
10363                                .clearPackagePreferredActivities(r.packageName);
10364                    } catch (RemoteException c) {
10365                        // pm is in same process, this will never happen.
10366                    }
10367                }
10368            }
10369        }
10370
10371        if (!app.isolated) {
10372            // XXX Can't keep track of crash times for isolated processes,
10373            // because they don't have a perisistent identity.
10374            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10375        }
10376
10377        return true;
10378    }
10379
10380    void startAppProblemLocked(ProcessRecord app) {
10381        if (app.userId == mCurrentUserId) {
10382            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10383                    mContext, app.info.packageName, app.info.flags);
10384        } else {
10385            // If this app is not running under the current user, then we
10386            // can't give it a report button because that would require
10387            // launching the report UI under a different user.
10388            app.errorReportReceiver = null;
10389        }
10390        skipCurrentReceiverLocked(app);
10391    }
10392
10393    void skipCurrentReceiverLocked(ProcessRecord app) {
10394        for (BroadcastQueue queue : mBroadcastQueues) {
10395            queue.skipCurrentReceiverLocked(app);
10396        }
10397    }
10398
10399    /**
10400     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10401     * The application process will exit immediately after this call returns.
10402     * @param app object of the crashing app, null for the system server
10403     * @param crashInfo describing the exception
10404     */
10405    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10406        ProcessRecord r = findAppProcess(app, "Crash");
10407        final String processName = app == null ? "system_server"
10408                : (r == null ? "unknown" : r.processName);
10409
10410        handleApplicationCrashInner("crash", r, processName, crashInfo);
10411    }
10412
10413    /* Native crash reporting uses this inner version because it needs to be somewhat
10414     * decoupled from the AM-managed cleanup lifecycle
10415     */
10416    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10417            ApplicationErrorReport.CrashInfo crashInfo) {
10418        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10419                UserHandle.getUserId(Binder.getCallingUid()), processName,
10420                r == null ? -1 : r.info.flags,
10421                crashInfo.exceptionClassName,
10422                crashInfo.exceptionMessage,
10423                crashInfo.throwFileName,
10424                crashInfo.throwLineNumber);
10425
10426        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10427
10428        crashApplication(r, crashInfo);
10429    }
10430
10431    public void handleApplicationStrictModeViolation(
10432            IBinder app,
10433            int violationMask,
10434            StrictMode.ViolationInfo info) {
10435        ProcessRecord r = findAppProcess(app, "StrictMode");
10436        if (r == null) {
10437            return;
10438        }
10439
10440        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10441            Integer stackFingerprint = info.hashCode();
10442            boolean logIt = true;
10443            synchronized (mAlreadyLoggedViolatedStacks) {
10444                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10445                    logIt = false;
10446                    // TODO: sub-sample into EventLog for these, with
10447                    // the info.durationMillis?  Then we'd get
10448                    // the relative pain numbers, without logging all
10449                    // the stack traces repeatedly.  We'd want to do
10450                    // likewise in the client code, which also does
10451                    // dup suppression, before the Binder call.
10452                } else {
10453                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10454                        mAlreadyLoggedViolatedStacks.clear();
10455                    }
10456                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10457                }
10458            }
10459            if (logIt) {
10460                logStrictModeViolationToDropBox(r, info);
10461            }
10462        }
10463
10464        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10465            AppErrorResult result = new AppErrorResult();
10466            synchronized (this) {
10467                final long origId = Binder.clearCallingIdentity();
10468
10469                Message msg = Message.obtain();
10470                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10471                HashMap<String, Object> data = new HashMap<String, Object>();
10472                data.put("result", result);
10473                data.put("app", r);
10474                data.put("violationMask", violationMask);
10475                data.put("info", info);
10476                msg.obj = data;
10477                mHandler.sendMessage(msg);
10478
10479                Binder.restoreCallingIdentity(origId);
10480            }
10481            int res = result.get();
10482            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10483        }
10484    }
10485
10486    // Depending on the policy in effect, there could be a bunch of
10487    // these in quick succession so we try to batch these together to
10488    // minimize disk writes, number of dropbox entries, and maximize
10489    // compression, by having more fewer, larger records.
10490    private void logStrictModeViolationToDropBox(
10491            ProcessRecord process,
10492            StrictMode.ViolationInfo info) {
10493        if (info == null) {
10494            return;
10495        }
10496        final boolean isSystemApp = process == null ||
10497                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10498                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10499        final String processName = process == null ? "unknown" : process.processName;
10500        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10501        final DropBoxManager dbox = (DropBoxManager)
10502                mContext.getSystemService(Context.DROPBOX_SERVICE);
10503
10504        // Exit early if the dropbox isn't configured to accept this report type.
10505        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10506
10507        boolean bufferWasEmpty;
10508        boolean needsFlush;
10509        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10510        synchronized (sb) {
10511            bufferWasEmpty = sb.length() == 0;
10512            appendDropBoxProcessHeaders(process, processName, sb);
10513            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10514            sb.append("System-App: ").append(isSystemApp).append("\n");
10515            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10516            if (info.violationNumThisLoop != 0) {
10517                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10518            }
10519            if (info.numAnimationsRunning != 0) {
10520                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10521            }
10522            if (info.broadcastIntentAction != null) {
10523                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10524            }
10525            if (info.durationMillis != -1) {
10526                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10527            }
10528            if (info.numInstances != -1) {
10529                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10530            }
10531            if (info.tags != null) {
10532                for (String tag : info.tags) {
10533                    sb.append("Span-Tag: ").append(tag).append("\n");
10534                }
10535            }
10536            sb.append("\n");
10537            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10538                sb.append(info.crashInfo.stackTrace);
10539            }
10540            sb.append("\n");
10541
10542            // Only buffer up to ~64k.  Various logging bits truncate
10543            // things at 128k.
10544            needsFlush = (sb.length() > 64 * 1024);
10545        }
10546
10547        // Flush immediately if the buffer's grown too large, or this
10548        // is a non-system app.  Non-system apps are isolated with a
10549        // different tag & policy and not batched.
10550        //
10551        // Batching is useful during internal testing with
10552        // StrictMode settings turned up high.  Without batching,
10553        // thousands of separate files could be created on boot.
10554        if (!isSystemApp || needsFlush) {
10555            new Thread("Error dump: " + dropboxTag) {
10556                @Override
10557                public void run() {
10558                    String report;
10559                    synchronized (sb) {
10560                        report = sb.toString();
10561                        sb.delete(0, sb.length());
10562                        sb.trimToSize();
10563                    }
10564                    if (report.length() != 0) {
10565                        dbox.addText(dropboxTag, report);
10566                    }
10567                }
10568            }.start();
10569            return;
10570        }
10571
10572        // System app batching:
10573        if (!bufferWasEmpty) {
10574            // An existing dropbox-writing thread is outstanding, so
10575            // we don't need to start it up.  The existing thread will
10576            // catch the buffer appends we just did.
10577            return;
10578        }
10579
10580        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10581        // (After this point, we shouldn't access AMS internal data structures.)
10582        new Thread("Error dump: " + dropboxTag) {
10583            @Override
10584            public void run() {
10585                // 5 second sleep to let stacks arrive and be batched together
10586                try {
10587                    Thread.sleep(5000);  // 5 seconds
10588                } catch (InterruptedException e) {}
10589
10590                String errorReport;
10591                synchronized (mStrictModeBuffer) {
10592                    errorReport = mStrictModeBuffer.toString();
10593                    if (errorReport.length() == 0) {
10594                        return;
10595                    }
10596                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10597                    mStrictModeBuffer.trimToSize();
10598                }
10599                dbox.addText(dropboxTag, errorReport);
10600            }
10601        }.start();
10602    }
10603
10604    /**
10605     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10606     * @param app object of the crashing app, null for the system server
10607     * @param tag reported by the caller
10608     * @param crashInfo describing the context of the error
10609     * @return true if the process should exit immediately (WTF is fatal)
10610     */
10611    public boolean handleApplicationWtf(IBinder app, String tag,
10612            ApplicationErrorReport.CrashInfo crashInfo) {
10613        ProcessRecord r = findAppProcess(app, "WTF");
10614        final String processName = app == null ? "system_server"
10615                : (r == null ? "unknown" : r.processName);
10616
10617        EventLog.writeEvent(EventLogTags.AM_WTF,
10618                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10619                processName,
10620                r == null ? -1 : r.info.flags,
10621                tag, crashInfo.exceptionMessage);
10622
10623        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10624
10625        if (r != null && r.pid != Process.myPid() &&
10626                Settings.Global.getInt(mContext.getContentResolver(),
10627                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10628            crashApplication(r, crashInfo);
10629            return true;
10630        } else {
10631            return false;
10632        }
10633    }
10634
10635    /**
10636     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10637     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10638     */
10639    private ProcessRecord findAppProcess(IBinder app, String reason) {
10640        if (app == null) {
10641            return null;
10642        }
10643
10644        synchronized (this) {
10645            final int NP = mProcessNames.getMap().size();
10646            for (int ip=0; ip<NP; ip++) {
10647                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10648                final int NA = apps.size();
10649                for (int ia=0; ia<NA; ia++) {
10650                    ProcessRecord p = apps.valueAt(ia);
10651                    if (p.thread != null && p.thread.asBinder() == app) {
10652                        return p;
10653                    }
10654                }
10655            }
10656
10657            Slog.w(TAG, "Can't find mystery application for " + reason
10658                    + " from pid=" + Binder.getCallingPid()
10659                    + " uid=" + Binder.getCallingUid() + ": " + app);
10660            return null;
10661        }
10662    }
10663
10664    /**
10665     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10666     * to append various headers to the dropbox log text.
10667     */
10668    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10669            StringBuilder sb) {
10670        // Watchdog thread ends up invoking this function (with
10671        // a null ProcessRecord) to add the stack file to dropbox.
10672        // Do not acquire a lock on this (am) in such cases, as it
10673        // could cause a potential deadlock, if and when watchdog
10674        // is invoked due to unavailability of lock on am and it
10675        // would prevent watchdog from killing system_server.
10676        if (process == null) {
10677            sb.append("Process: ").append(processName).append("\n");
10678            return;
10679        }
10680        // Note: ProcessRecord 'process' is guarded by the service
10681        // instance.  (notably process.pkgList, which could otherwise change
10682        // concurrently during execution of this method)
10683        synchronized (this) {
10684            sb.append("Process: ").append(processName).append("\n");
10685            int flags = process.info.flags;
10686            IPackageManager pm = AppGlobals.getPackageManager();
10687            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10688            for (int ip=0; ip<process.pkgList.size(); ip++) {
10689                String pkg = process.pkgList.keyAt(ip);
10690                sb.append("Package: ").append(pkg);
10691                try {
10692                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10693                    if (pi != null) {
10694                        sb.append(" v").append(pi.versionCode);
10695                        if (pi.versionName != null) {
10696                            sb.append(" (").append(pi.versionName).append(")");
10697                        }
10698                    }
10699                } catch (RemoteException e) {
10700                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10701                }
10702                sb.append("\n");
10703            }
10704        }
10705    }
10706
10707    private static String processClass(ProcessRecord process) {
10708        if (process == null || process.pid == MY_PID) {
10709            return "system_server";
10710        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10711            return "system_app";
10712        } else {
10713            return "data_app";
10714        }
10715    }
10716
10717    /**
10718     * Write a description of an error (crash, WTF, ANR) to the drop box.
10719     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10720     * @param process which caused the error, null means the system server
10721     * @param activity which triggered the error, null if unknown
10722     * @param parent activity related to the error, null if unknown
10723     * @param subject line related to the error, null if absent
10724     * @param report in long form describing the error, null if absent
10725     * @param logFile to include in the report, null if none
10726     * @param crashInfo giving an application stack trace, null if absent
10727     */
10728    public void addErrorToDropBox(String eventType,
10729            ProcessRecord process, String processName, ActivityRecord activity,
10730            ActivityRecord parent, String subject,
10731            final String report, final File logFile,
10732            final ApplicationErrorReport.CrashInfo crashInfo) {
10733        // NOTE -- this must never acquire the ActivityManagerService lock,
10734        // otherwise the watchdog may be prevented from resetting the system.
10735
10736        final String dropboxTag = processClass(process) + "_" + eventType;
10737        final DropBoxManager dbox = (DropBoxManager)
10738                mContext.getSystemService(Context.DROPBOX_SERVICE);
10739
10740        // Exit early if the dropbox isn't configured to accept this report type.
10741        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10742
10743        final StringBuilder sb = new StringBuilder(1024);
10744        appendDropBoxProcessHeaders(process, processName, sb);
10745        if (activity != null) {
10746            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10747        }
10748        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10749            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10750        }
10751        if (parent != null && parent != activity) {
10752            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10753        }
10754        if (subject != null) {
10755            sb.append("Subject: ").append(subject).append("\n");
10756        }
10757        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10758        if (Debug.isDebuggerConnected()) {
10759            sb.append("Debugger: Connected\n");
10760        }
10761        sb.append("\n");
10762
10763        // Do the rest in a worker thread to avoid blocking the caller on I/O
10764        // (After this point, we shouldn't access AMS internal data structures.)
10765        Thread worker = new Thread("Error dump: " + dropboxTag) {
10766            @Override
10767            public void run() {
10768                if (report != null) {
10769                    sb.append(report);
10770                }
10771                if (logFile != null) {
10772                    try {
10773                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10774                                    "\n\n[[TRUNCATED]]"));
10775                    } catch (IOException e) {
10776                        Slog.e(TAG, "Error reading " + logFile, e);
10777                    }
10778                }
10779                if (crashInfo != null && crashInfo.stackTrace != null) {
10780                    sb.append(crashInfo.stackTrace);
10781                }
10782
10783                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10784                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10785                if (lines > 0) {
10786                    sb.append("\n");
10787
10788                    // Merge several logcat streams, and take the last N lines
10789                    InputStreamReader input = null;
10790                    try {
10791                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10792                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10793                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10794
10795                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10796                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10797                        input = new InputStreamReader(logcat.getInputStream());
10798
10799                        int num;
10800                        char[] buf = new char[8192];
10801                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10802                    } catch (IOException e) {
10803                        Slog.e(TAG, "Error running logcat", e);
10804                    } finally {
10805                        if (input != null) try { input.close(); } catch (IOException e) {}
10806                    }
10807                }
10808
10809                dbox.addText(dropboxTag, sb.toString());
10810            }
10811        };
10812
10813        if (process == null) {
10814            // If process is null, we are being called from some internal code
10815            // and may be about to die -- run this synchronously.
10816            worker.run();
10817        } else {
10818            worker.start();
10819        }
10820    }
10821
10822    /**
10823     * Bring up the "unexpected error" dialog box for a crashing app.
10824     * Deal with edge cases (intercepts from instrumented applications,
10825     * ActivityController, error intent receivers, that sort of thing).
10826     * @param r the application crashing
10827     * @param crashInfo describing the failure
10828     */
10829    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10830        long timeMillis = System.currentTimeMillis();
10831        String shortMsg = crashInfo.exceptionClassName;
10832        String longMsg = crashInfo.exceptionMessage;
10833        String stackTrace = crashInfo.stackTrace;
10834        if (shortMsg != null && longMsg != null) {
10835            longMsg = shortMsg + ": " + longMsg;
10836        } else if (shortMsg != null) {
10837            longMsg = shortMsg;
10838        }
10839
10840        AppErrorResult result = new AppErrorResult();
10841        synchronized (this) {
10842            if (mController != null) {
10843                try {
10844                    String name = r != null ? r.processName : null;
10845                    int pid = r != null ? r.pid : Binder.getCallingPid();
10846                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
10847                    if (!mController.appCrashed(name, pid,
10848                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10849                        Slog.w(TAG, "Force-killing crashed app " + name
10850                                + " at watcher's request");
10851                        Process.killProcess(pid);
10852                        if (r != null) {
10853                            Process.killProcessGroup(uid, pid);
10854                        }
10855                        return;
10856                    }
10857                } catch (RemoteException e) {
10858                    mController = null;
10859                    Watchdog.getInstance().setActivityController(null);
10860                }
10861            }
10862
10863            final long origId = Binder.clearCallingIdentity();
10864
10865            // If this process is running instrumentation, finish it.
10866            if (r != null && r.instrumentationClass != null) {
10867                Slog.w(TAG, "Error in app " + r.processName
10868                      + " running instrumentation " + r.instrumentationClass + ":");
10869                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10870                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10871                Bundle info = new Bundle();
10872                info.putString("shortMsg", shortMsg);
10873                info.putString("longMsg", longMsg);
10874                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10875                Binder.restoreCallingIdentity(origId);
10876                return;
10877            }
10878
10879            // If we can't identify the process or it's already exceeded its crash quota,
10880            // quit right away without showing a crash dialog.
10881            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10882                Binder.restoreCallingIdentity(origId);
10883                return;
10884            }
10885
10886            Message msg = Message.obtain();
10887            msg.what = SHOW_ERROR_MSG;
10888            HashMap data = new HashMap();
10889            data.put("result", result);
10890            data.put("app", r);
10891            msg.obj = data;
10892            mHandler.sendMessage(msg);
10893
10894            Binder.restoreCallingIdentity(origId);
10895        }
10896
10897        int res = result.get();
10898
10899        Intent appErrorIntent = null;
10900        synchronized (this) {
10901            if (r != null && !r.isolated) {
10902                // XXX Can't keep track of crash time for isolated processes,
10903                // since they don't have a persistent identity.
10904                mProcessCrashTimes.put(r.info.processName, r.uid,
10905                        SystemClock.uptimeMillis());
10906            }
10907            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10908                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10909            }
10910        }
10911
10912        if (appErrorIntent != null) {
10913            try {
10914                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10915            } catch (ActivityNotFoundException e) {
10916                Slog.w(TAG, "bug report receiver dissappeared", e);
10917            }
10918        }
10919    }
10920
10921    Intent createAppErrorIntentLocked(ProcessRecord r,
10922            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10923        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10924        if (report == null) {
10925            return null;
10926        }
10927        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10928        result.setComponent(r.errorReportReceiver);
10929        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10930        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10931        return result;
10932    }
10933
10934    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10935            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10936        if (r.errorReportReceiver == null) {
10937            return null;
10938        }
10939
10940        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10941            return null;
10942        }
10943
10944        ApplicationErrorReport report = new ApplicationErrorReport();
10945        report.packageName = r.info.packageName;
10946        report.installerPackageName = r.errorReportReceiver.getPackageName();
10947        report.processName = r.processName;
10948        report.time = timeMillis;
10949        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10950
10951        if (r.crashing || r.forceCrashReport) {
10952            report.type = ApplicationErrorReport.TYPE_CRASH;
10953            report.crashInfo = crashInfo;
10954        } else if (r.notResponding) {
10955            report.type = ApplicationErrorReport.TYPE_ANR;
10956            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10957
10958            report.anrInfo.activity = r.notRespondingReport.tag;
10959            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10960            report.anrInfo.info = r.notRespondingReport.longMsg;
10961        }
10962
10963        return report;
10964    }
10965
10966    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10967        enforceNotIsolatedCaller("getProcessesInErrorState");
10968        // assume our apps are happy - lazy create the list
10969        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10970
10971        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10972                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10973        int userId = UserHandle.getUserId(Binder.getCallingUid());
10974
10975        synchronized (this) {
10976
10977            // iterate across all processes
10978            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10979                ProcessRecord app = mLruProcesses.get(i);
10980                if (!allUsers && app.userId != userId) {
10981                    continue;
10982                }
10983                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10984                    // This one's in trouble, so we'll generate a report for it
10985                    // crashes are higher priority (in case there's a crash *and* an anr)
10986                    ActivityManager.ProcessErrorStateInfo report = null;
10987                    if (app.crashing) {
10988                        report = app.crashingReport;
10989                    } else if (app.notResponding) {
10990                        report = app.notRespondingReport;
10991                    }
10992
10993                    if (report != null) {
10994                        if (errList == null) {
10995                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10996                        }
10997                        errList.add(report);
10998                    } else {
10999                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11000                                " crashing = " + app.crashing +
11001                                " notResponding = " + app.notResponding);
11002                    }
11003                }
11004            }
11005        }
11006
11007        return errList;
11008    }
11009
11010    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
11011        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
11012            if (currApp != null) {
11013                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
11014            }
11015            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
11016        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
11017            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
11018        } else if (adj >= ProcessList.HOME_APP_ADJ) {
11019            if (currApp != null) {
11020                currApp.lru = 0;
11021            }
11022            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
11023        } else if (adj >= ProcessList.SERVICE_ADJ) {
11024            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
11025        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
11026            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
11027        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
11028            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
11029        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
11030            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
11031        } else {
11032            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
11033        }
11034    }
11035
11036    private void fillInProcMemInfo(ProcessRecord app,
11037            ActivityManager.RunningAppProcessInfo outInfo) {
11038        outInfo.pid = app.pid;
11039        outInfo.uid = app.info.uid;
11040        if (mHeavyWeightProcess == app) {
11041            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11042        }
11043        if (app.persistent) {
11044            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11045        }
11046        if (app.activities.size() > 0) {
11047            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11048        }
11049        outInfo.lastTrimLevel = app.trimMemoryLevel;
11050        int adj = app.curAdj;
11051        outInfo.importance = oomAdjToImportance(adj, outInfo);
11052        outInfo.importanceReasonCode = app.adjTypeCode;
11053        outInfo.processState = app.curProcState;
11054    }
11055
11056    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11057        enforceNotIsolatedCaller("getRunningAppProcesses");
11058        // Lazy instantiation of list
11059        List<ActivityManager.RunningAppProcessInfo> runList = null;
11060        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11061                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11062        int userId = UserHandle.getUserId(Binder.getCallingUid());
11063        synchronized (this) {
11064            // Iterate across all processes
11065            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11066                ProcessRecord app = mLruProcesses.get(i);
11067                if (!allUsers && app.userId != userId) {
11068                    continue;
11069                }
11070                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11071                    // Generate process state info for running application
11072                    ActivityManager.RunningAppProcessInfo currApp =
11073                        new ActivityManager.RunningAppProcessInfo(app.processName,
11074                                app.pid, app.getPackageList());
11075                    fillInProcMemInfo(app, currApp);
11076                    if (app.adjSource instanceof ProcessRecord) {
11077                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11078                        currApp.importanceReasonImportance = oomAdjToImportance(
11079                                app.adjSourceOom, null);
11080                    } else if (app.adjSource instanceof ActivityRecord) {
11081                        ActivityRecord r = (ActivityRecord)app.adjSource;
11082                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11083                    }
11084                    if (app.adjTarget instanceof ComponentName) {
11085                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11086                    }
11087                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11088                    //        + " lru=" + currApp.lru);
11089                    if (runList == null) {
11090                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11091                    }
11092                    runList.add(currApp);
11093                }
11094            }
11095        }
11096        return runList;
11097    }
11098
11099    public List<ApplicationInfo> getRunningExternalApplications() {
11100        enforceNotIsolatedCaller("getRunningExternalApplications");
11101        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11102        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11103        if (runningApps != null && runningApps.size() > 0) {
11104            Set<String> extList = new HashSet<String>();
11105            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11106                if (app.pkgList != null) {
11107                    for (String pkg : app.pkgList) {
11108                        extList.add(pkg);
11109                    }
11110                }
11111            }
11112            IPackageManager pm = AppGlobals.getPackageManager();
11113            for (String pkg : extList) {
11114                try {
11115                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11116                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11117                        retList.add(info);
11118                    }
11119                } catch (RemoteException e) {
11120                }
11121            }
11122        }
11123        return retList;
11124    }
11125
11126    @Override
11127    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11128        enforceNotIsolatedCaller("getMyMemoryState");
11129        synchronized (this) {
11130            ProcessRecord proc;
11131            synchronized (mPidsSelfLocked) {
11132                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11133            }
11134            fillInProcMemInfo(proc, outInfo);
11135        }
11136    }
11137
11138    @Override
11139    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11140        if (checkCallingPermission(android.Manifest.permission.DUMP)
11141                != PackageManager.PERMISSION_GRANTED) {
11142            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11143                    + Binder.getCallingPid()
11144                    + ", uid=" + Binder.getCallingUid()
11145                    + " without permission "
11146                    + android.Manifest.permission.DUMP);
11147            return;
11148        }
11149
11150        boolean dumpAll = false;
11151        boolean dumpClient = false;
11152        String dumpPackage = null;
11153
11154        int opti = 0;
11155        while (opti < args.length) {
11156            String opt = args[opti];
11157            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11158                break;
11159            }
11160            opti++;
11161            if ("-a".equals(opt)) {
11162                dumpAll = true;
11163            } else if ("-c".equals(opt)) {
11164                dumpClient = true;
11165            } else if ("-h".equals(opt)) {
11166                pw.println("Activity manager dump options:");
11167                pw.println("  [-a] [-c] [-h] [cmd] ...");
11168                pw.println("  cmd may be one of:");
11169                pw.println("    a[ctivities]: activity stack state");
11170                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11171                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11172                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11173                pw.println("    o[om]: out of memory management");
11174                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11175                pw.println("    provider [COMP_SPEC]: provider client-side state");
11176                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11177                pw.println("    service [COMP_SPEC]: service client-side state");
11178                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11179                pw.println("    all: dump all activities");
11180                pw.println("    top: dump the top activity");
11181                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11182                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11183                pw.println("    a partial substring in a component name, a");
11184                pw.println("    hex object identifier.");
11185                pw.println("  -a: include all available server state.");
11186                pw.println("  -c: include client state.");
11187                return;
11188            } else {
11189                pw.println("Unknown argument: " + opt + "; use -h for help");
11190            }
11191        }
11192
11193        long origId = Binder.clearCallingIdentity();
11194        boolean more = false;
11195        // Is the caller requesting to dump a particular piece of data?
11196        if (opti < args.length) {
11197            String cmd = args[opti];
11198            opti++;
11199            if ("activities".equals(cmd) || "a".equals(cmd)) {
11200                synchronized (this) {
11201                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11202                }
11203            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11204                String[] newArgs;
11205                String name;
11206                if (opti >= args.length) {
11207                    name = null;
11208                    newArgs = EMPTY_STRING_ARRAY;
11209                } else {
11210                    name = args[opti];
11211                    opti++;
11212                    newArgs = new String[args.length - opti];
11213                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11214                            args.length - opti);
11215                }
11216                synchronized (this) {
11217                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11218                }
11219            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11220                String[] newArgs;
11221                String name;
11222                if (opti >= args.length) {
11223                    name = null;
11224                    newArgs = EMPTY_STRING_ARRAY;
11225                } else {
11226                    name = args[opti];
11227                    opti++;
11228                    newArgs = new String[args.length - opti];
11229                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11230                            args.length - opti);
11231                }
11232                synchronized (this) {
11233                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11234                }
11235            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11236                String[] newArgs;
11237                String name;
11238                if (opti >= args.length) {
11239                    name = null;
11240                    newArgs = EMPTY_STRING_ARRAY;
11241                } else {
11242                    name = args[opti];
11243                    opti++;
11244                    newArgs = new String[args.length - opti];
11245                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11246                            args.length - opti);
11247                }
11248                synchronized (this) {
11249                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11250                }
11251            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11252                synchronized (this) {
11253                    dumpOomLocked(fd, pw, args, opti, true);
11254                }
11255            } else if ("provider".equals(cmd)) {
11256                String[] newArgs;
11257                String name;
11258                if (opti >= args.length) {
11259                    name = null;
11260                    newArgs = EMPTY_STRING_ARRAY;
11261                } else {
11262                    name = args[opti];
11263                    opti++;
11264                    newArgs = new String[args.length - opti];
11265                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11266                }
11267                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11268                    pw.println("No providers match: " + name);
11269                    pw.println("Use -h for help.");
11270                }
11271            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11272                synchronized (this) {
11273                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11274                }
11275            } else if ("service".equals(cmd)) {
11276                String[] newArgs;
11277                String name;
11278                if (opti >= args.length) {
11279                    name = null;
11280                    newArgs = EMPTY_STRING_ARRAY;
11281                } else {
11282                    name = args[opti];
11283                    opti++;
11284                    newArgs = new String[args.length - opti];
11285                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11286                            args.length - opti);
11287                }
11288                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11289                    pw.println("No services match: " + name);
11290                    pw.println("Use -h for help.");
11291                }
11292            } else if ("package".equals(cmd)) {
11293                String[] newArgs;
11294                if (opti >= args.length) {
11295                    pw.println("package: no package name specified");
11296                    pw.println("Use -h for help.");
11297                } else {
11298                    dumpPackage = args[opti];
11299                    opti++;
11300                    newArgs = new String[args.length - opti];
11301                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11302                            args.length - opti);
11303                    args = newArgs;
11304                    opti = 0;
11305                    more = true;
11306                }
11307            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11308                synchronized (this) {
11309                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11310                }
11311            } else {
11312                // Dumping a single activity?
11313                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11314                    pw.println("Bad activity command, or no activities match: " + cmd);
11315                    pw.println("Use -h for help.");
11316                }
11317            }
11318            if (!more) {
11319                Binder.restoreCallingIdentity(origId);
11320                return;
11321            }
11322        }
11323
11324        // No piece of data specified, dump everything.
11325        synchronized (this) {
11326            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11327            pw.println();
11328            if (dumpAll) {
11329                pw.println("-------------------------------------------------------------------------------");
11330            }
11331            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11332            pw.println();
11333            if (dumpAll) {
11334                pw.println("-------------------------------------------------------------------------------");
11335            }
11336            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11337            pw.println();
11338            if (dumpAll) {
11339                pw.println("-------------------------------------------------------------------------------");
11340            }
11341            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11342            pw.println();
11343            if (dumpAll) {
11344                pw.println("-------------------------------------------------------------------------------");
11345            }
11346            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11347            pw.println();
11348            if (dumpAll) {
11349                pw.println("-------------------------------------------------------------------------------");
11350            }
11351            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11352        }
11353        Binder.restoreCallingIdentity(origId);
11354    }
11355
11356    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11357            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11358        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11359
11360        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11361                dumpPackage);
11362        boolean needSep = printedAnything;
11363
11364        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11365                dumpPackage, needSep, "  mFocusedActivity: ");
11366        if (printed) {
11367            printedAnything = true;
11368            needSep = false;
11369        }
11370
11371        if (dumpPackage == null) {
11372            if (needSep) {
11373                pw.println();
11374            }
11375            needSep = true;
11376            printedAnything = true;
11377            mStackSupervisor.dump(pw, "  ");
11378        }
11379
11380        if (mRecentTasks.size() > 0) {
11381            boolean printedHeader = false;
11382
11383            final int N = mRecentTasks.size();
11384            for (int i=0; i<N; i++) {
11385                TaskRecord tr = mRecentTasks.get(i);
11386                if (dumpPackage != null) {
11387                    if (tr.realActivity == null ||
11388                            !dumpPackage.equals(tr.realActivity)) {
11389                        continue;
11390                    }
11391                }
11392                if (!printedHeader) {
11393                    if (needSep) {
11394                        pw.println();
11395                    }
11396                    pw.println("  Recent tasks:");
11397                    printedHeader = true;
11398                    printedAnything = true;
11399                }
11400                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11401                        pw.println(tr);
11402                if (dumpAll) {
11403                    mRecentTasks.get(i).dump(pw, "    ");
11404                }
11405            }
11406        }
11407
11408        if (!printedAnything) {
11409            pw.println("  (nothing)");
11410        }
11411    }
11412
11413    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11414            int opti, boolean dumpAll, String dumpPackage) {
11415        boolean needSep = false;
11416        boolean printedAnything = false;
11417        int numPers = 0;
11418
11419        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11420
11421        if (dumpAll) {
11422            final int NP = mProcessNames.getMap().size();
11423            for (int ip=0; ip<NP; ip++) {
11424                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11425                final int NA = procs.size();
11426                for (int ia=0; ia<NA; ia++) {
11427                    ProcessRecord r = procs.valueAt(ia);
11428                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11429                        continue;
11430                    }
11431                    if (!needSep) {
11432                        pw.println("  All known processes:");
11433                        needSep = true;
11434                        printedAnything = true;
11435                    }
11436                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11437                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11438                        pw.print(" "); pw.println(r);
11439                    r.dump(pw, "    ");
11440                    if (r.persistent) {
11441                        numPers++;
11442                    }
11443                }
11444            }
11445        }
11446
11447        if (mIsolatedProcesses.size() > 0) {
11448            boolean printed = false;
11449            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11450                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11451                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11452                    continue;
11453                }
11454                if (!printed) {
11455                    if (needSep) {
11456                        pw.println();
11457                    }
11458                    pw.println("  Isolated process list (sorted by uid):");
11459                    printedAnything = true;
11460                    printed = true;
11461                    needSep = true;
11462                }
11463                pw.println(String.format("%sIsolated #%2d: %s",
11464                        "    ", i, r.toString()));
11465            }
11466        }
11467
11468        if (mLruProcesses.size() > 0) {
11469            if (needSep) {
11470                pw.println();
11471            }
11472            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11473                    pw.print(" total, non-act at ");
11474                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11475                    pw.print(", non-svc at ");
11476                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11477                    pw.println("):");
11478            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11479            needSep = true;
11480            printedAnything = true;
11481        }
11482
11483        if (dumpAll || dumpPackage != null) {
11484            synchronized (mPidsSelfLocked) {
11485                boolean printed = false;
11486                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11487                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11488                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11489                        continue;
11490                    }
11491                    if (!printed) {
11492                        if (needSep) pw.println();
11493                        needSep = true;
11494                        pw.println("  PID mappings:");
11495                        printed = true;
11496                        printedAnything = true;
11497                    }
11498                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11499                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11500                }
11501            }
11502        }
11503
11504        if (mForegroundProcesses.size() > 0) {
11505            synchronized (mPidsSelfLocked) {
11506                boolean printed = false;
11507                for (int i=0; i<mForegroundProcesses.size(); i++) {
11508                    ProcessRecord r = mPidsSelfLocked.get(
11509                            mForegroundProcesses.valueAt(i).pid);
11510                    if (dumpPackage != null && (r == null
11511                            || !r.pkgList.containsKey(dumpPackage))) {
11512                        continue;
11513                    }
11514                    if (!printed) {
11515                        if (needSep) pw.println();
11516                        needSep = true;
11517                        pw.println("  Foreground Processes:");
11518                        printed = true;
11519                        printedAnything = true;
11520                    }
11521                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11522                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11523                }
11524            }
11525        }
11526
11527        if (mPersistentStartingProcesses.size() > 0) {
11528            if (needSep) pw.println();
11529            needSep = true;
11530            printedAnything = true;
11531            pw.println("  Persisent processes that are starting:");
11532            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11533                    "Starting Norm", "Restarting PERS", dumpPackage);
11534        }
11535
11536        if (mRemovedProcesses.size() > 0) {
11537            if (needSep) pw.println();
11538            needSep = true;
11539            printedAnything = true;
11540            pw.println("  Processes that are being removed:");
11541            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11542                    "Removed Norm", "Removed PERS", dumpPackage);
11543        }
11544
11545        if (mProcessesOnHold.size() > 0) {
11546            if (needSep) pw.println();
11547            needSep = true;
11548            printedAnything = true;
11549            pw.println("  Processes that are on old until the system is ready:");
11550            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11551                    "OnHold Norm", "OnHold PERS", dumpPackage);
11552        }
11553
11554        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11555
11556        if (mProcessCrashTimes.getMap().size() > 0) {
11557            boolean printed = false;
11558            long now = SystemClock.uptimeMillis();
11559            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11560            final int NP = pmap.size();
11561            for (int ip=0; ip<NP; ip++) {
11562                String pname = pmap.keyAt(ip);
11563                SparseArray<Long> uids = pmap.valueAt(ip);
11564                final int N = uids.size();
11565                for (int i=0; i<N; i++) {
11566                    int puid = uids.keyAt(i);
11567                    ProcessRecord r = mProcessNames.get(pname, puid);
11568                    if (dumpPackage != null && (r == null
11569                            || !r.pkgList.containsKey(dumpPackage))) {
11570                        continue;
11571                    }
11572                    if (!printed) {
11573                        if (needSep) pw.println();
11574                        needSep = true;
11575                        pw.println("  Time since processes crashed:");
11576                        printed = true;
11577                        printedAnything = true;
11578                    }
11579                    pw.print("    Process "); pw.print(pname);
11580                            pw.print(" uid "); pw.print(puid);
11581                            pw.print(": last crashed ");
11582                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11583                            pw.println(" ago");
11584                }
11585            }
11586        }
11587
11588        if (mBadProcesses.getMap().size() > 0) {
11589            boolean printed = false;
11590            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11591            final int NP = pmap.size();
11592            for (int ip=0; ip<NP; ip++) {
11593                String pname = pmap.keyAt(ip);
11594                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11595                final int N = uids.size();
11596                for (int i=0; i<N; i++) {
11597                    int puid = uids.keyAt(i);
11598                    ProcessRecord r = mProcessNames.get(pname, puid);
11599                    if (dumpPackage != null && (r == null
11600                            || !r.pkgList.containsKey(dumpPackage))) {
11601                        continue;
11602                    }
11603                    if (!printed) {
11604                        if (needSep) pw.println();
11605                        needSep = true;
11606                        pw.println("  Bad processes:");
11607                        printedAnything = true;
11608                    }
11609                    BadProcessInfo info = uids.valueAt(i);
11610                    pw.print("    Bad process "); pw.print(pname);
11611                            pw.print(" uid "); pw.print(puid);
11612                            pw.print(": crashed at time "); pw.println(info.time);
11613                    if (info.shortMsg != null) {
11614                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11615                    }
11616                    if (info.longMsg != null) {
11617                        pw.print("      Long msg: "); pw.println(info.longMsg);
11618                    }
11619                    if (info.stack != null) {
11620                        pw.println("      Stack:");
11621                        int lastPos = 0;
11622                        for (int pos=0; pos<info.stack.length(); pos++) {
11623                            if (info.stack.charAt(pos) == '\n') {
11624                                pw.print("        ");
11625                                pw.write(info.stack, lastPos, pos-lastPos);
11626                                pw.println();
11627                                lastPos = pos+1;
11628                            }
11629                        }
11630                        if (lastPos < info.stack.length()) {
11631                            pw.print("        ");
11632                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11633                            pw.println();
11634                        }
11635                    }
11636                }
11637            }
11638        }
11639
11640        if (dumpPackage == null) {
11641            pw.println();
11642            needSep = false;
11643            pw.println("  mStartedUsers:");
11644            for (int i=0; i<mStartedUsers.size(); i++) {
11645                UserStartedState uss = mStartedUsers.valueAt(i);
11646                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11647                        pw.print(": "); uss.dump("", pw);
11648            }
11649            pw.print("  mStartedUserArray: [");
11650            for (int i=0; i<mStartedUserArray.length; i++) {
11651                if (i > 0) pw.print(", ");
11652                pw.print(mStartedUserArray[i]);
11653            }
11654            pw.println("]");
11655            pw.print("  mUserLru: [");
11656            for (int i=0; i<mUserLru.size(); i++) {
11657                if (i > 0) pw.print(", ");
11658                pw.print(mUserLru.get(i));
11659            }
11660            pw.println("]");
11661            if (dumpAll) {
11662                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11663            }
11664            synchronized (mUserProfileGroupIdsSelfLocked) {
11665                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
11666                    pw.println("  mUserProfileGroupIds:");
11667                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
11668                        pw.print("    User #");
11669                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
11670                        pw.print(" -> profile #");
11671                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
11672                    }
11673                }
11674            }
11675        }
11676        if (mHomeProcess != null && (dumpPackage == null
11677                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11678            if (needSep) {
11679                pw.println();
11680                needSep = false;
11681            }
11682            pw.println("  mHomeProcess: " + mHomeProcess);
11683        }
11684        if (mPreviousProcess != null && (dumpPackage == null
11685                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11686            if (needSep) {
11687                pw.println();
11688                needSep = false;
11689            }
11690            pw.println("  mPreviousProcess: " + mPreviousProcess);
11691        }
11692        if (dumpAll) {
11693            StringBuilder sb = new StringBuilder(128);
11694            sb.append("  mPreviousProcessVisibleTime: ");
11695            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11696            pw.println(sb);
11697        }
11698        if (mHeavyWeightProcess != null && (dumpPackage == null
11699                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11700            if (needSep) {
11701                pw.println();
11702                needSep = false;
11703            }
11704            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11705        }
11706        if (dumpPackage == null) {
11707            pw.println("  mConfiguration: " + mConfiguration);
11708        }
11709        if (dumpAll) {
11710            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11711            if (mCompatModePackages.getPackages().size() > 0) {
11712                boolean printed = false;
11713                for (Map.Entry<String, Integer> entry
11714                        : mCompatModePackages.getPackages().entrySet()) {
11715                    String pkg = entry.getKey();
11716                    int mode = entry.getValue();
11717                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11718                        continue;
11719                    }
11720                    if (!printed) {
11721                        pw.println("  mScreenCompatPackages:");
11722                        printed = true;
11723                    }
11724                    pw.print("    "); pw.print(pkg); pw.print(": ");
11725                            pw.print(mode); pw.println();
11726                }
11727            }
11728        }
11729        if (dumpPackage == null) {
11730            if (mSleeping || mWentToSleep || mLockScreenShown) {
11731                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11732                        + " mLockScreenShown " + mLockScreenShown);
11733            }
11734            if (mShuttingDown || mRunningVoice) {
11735                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11736            }
11737        }
11738        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11739                || mOrigWaitForDebugger) {
11740            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11741                    || dumpPackage.equals(mOrigDebugApp)) {
11742                if (needSep) {
11743                    pw.println();
11744                    needSep = false;
11745                }
11746                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11747                        + " mDebugTransient=" + mDebugTransient
11748                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11749            }
11750        }
11751        if (mOpenGlTraceApp != null) {
11752            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11753                if (needSep) {
11754                    pw.println();
11755                    needSep = false;
11756                }
11757                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11758            }
11759        }
11760        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11761                || mProfileFd != null) {
11762            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11763                if (needSep) {
11764                    pw.println();
11765                    needSep = false;
11766                }
11767                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11768                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11769                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11770                        + mAutoStopProfiler);
11771            }
11772        }
11773        if (dumpPackage == null) {
11774            if (mAlwaysFinishActivities || mController != null) {
11775                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11776                        + " mController=" + mController);
11777            }
11778            if (dumpAll) {
11779                pw.println("  Total persistent processes: " + numPers);
11780                pw.println("  mProcessesReady=" + mProcessesReady
11781                        + " mSystemReady=" + mSystemReady);
11782                pw.println("  mBooting=" + mBooting
11783                        + " mBooted=" + mBooted
11784                        + " mFactoryTest=" + mFactoryTest);
11785                pw.print("  mLastPowerCheckRealtime=");
11786                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11787                        pw.println("");
11788                pw.print("  mLastPowerCheckUptime=");
11789                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11790                        pw.println("");
11791                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11792                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11793                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11794                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11795                        + " (" + mLruProcesses.size() + " total)"
11796                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11797                        + " mNumServiceProcs=" + mNumServiceProcs
11798                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11799                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11800                        + " mLastMemoryLevel" + mLastMemoryLevel
11801                        + " mLastNumProcesses" + mLastNumProcesses);
11802                long now = SystemClock.uptimeMillis();
11803                pw.print("  mLastIdleTime=");
11804                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11805                        pw.print(" mLowRamSinceLastIdle=");
11806                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11807                        pw.println();
11808            }
11809        }
11810
11811        if (!printedAnything) {
11812            pw.println("  (nothing)");
11813        }
11814    }
11815
11816    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11817            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11818        if (mProcessesToGc.size() > 0) {
11819            boolean printed = false;
11820            long now = SystemClock.uptimeMillis();
11821            for (int i=0; i<mProcessesToGc.size(); i++) {
11822                ProcessRecord proc = mProcessesToGc.get(i);
11823                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11824                    continue;
11825                }
11826                if (!printed) {
11827                    if (needSep) pw.println();
11828                    needSep = true;
11829                    pw.println("  Processes that are waiting to GC:");
11830                    printed = true;
11831                }
11832                pw.print("    Process "); pw.println(proc);
11833                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11834                        pw.print(", last gced=");
11835                        pw.print(now-proc.lastRequestedGc);
11836                        pw.print(" ms ago, last lowMem=");
11837                        pw.print(now-proc.lastLowMemory);
11838                        pw.println(" ms ago");
11839
11840            }
11841        }
11842        return needSep;
11843    }
11844
11845    void printOomLevel(PrintWriter pw, String name, int adj) {
11846        pw.print("    ");
11847        if (adj >= 0) {
11848            pw.print(' ');
11849            if (adj < 10) pw.print(' ');
11850        } else {
11851            if (adj > -10) pw.print(' ');
11852        }
11853        pw.print(adj);
11854        pw.print(": ");
11855        pw.print(name);
11856        pw.print(" (");
11857        pw.print(mProcessList.getMemLevel(adj)/1024);
11858        pw.println(" kB)");
11859    }
11860
11861    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11862            int opti, boolean dumpAll) {
11863        boolean needSep = false;
11864
11865        if (mLruProcesses.size() > 0) {
11866            if (needSep) pw.println();
11867            needSep = true;
11868            pw.println("  OOM levels:");
11869            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11870            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11871            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11872            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11873            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11874            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11875            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11876            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11877            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11878            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11879            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11880            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11881            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11882
11883            if (needSep) pw.println();
11884            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11885                    pw.print(" total, non-act at ");
11886                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11887                    pw.print(", non-svc at ");
11888                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11889                    pw.println("):");
11890            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11891            needSep = true;
11892        }
11893
11894        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11895
11896        pw.println();
11897        pw.println("  mHomeProcess: " + mHomeProcess);
11898        pw.println("  mPreviousProcess: " + mPreviousProcess);
11899        if (mHeavyWeightProcess != null) {
11900            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11901        }
11902
11903        return true;
11904    }
11905
11906    /**
11907     * There are three ways to call this:
11908     *  - no provider specified: dump all the providers
11909     *  - a flattened component name that matched an existing provider was specified as the
11910     *    first arg: dump that one provider
11911     *  - the first arg isn't the flattened component name of an existing provider:
11912     *    dump all providers whose component contains the first arg as a substring
11913     */
11914    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11915            int opti, boolean dumpAll) {
11916        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11917    }
11918
11919    static class ItemMatcher {
11920        ArrayList<ComponentName> components;
11921        ArrayList<String> strings;
11922        ArrayList<Integer> objects;
11923        boolean all;
11924
11925        ItemMatcher() {
11926            all = true;
11927        }
11928
11929        void build(String name) {
11930            ComponentName componentName = ComponentName.unflattenFromString(name);
11931            if (componentName != null) {
11932                if (components == null) {
11933                    components = new ArrayList<ComponentName>();
11934                }
11935                components.add(componentName);
11936                all = false;
11937            } else {
11938                int objectId = 0;
11939                // Not a '/' separated full component name; maybe an object ID?
11940                try {
11941                    objectId = Integer.parseInt(name, 16);
11942                    if (objects == null) {
11943                        objects = new ArrayList<Integer>();
11944                    }
11945                    objects.add(objectId);
11946                    all = false;
11947                } catch (RuntimeException e) {
11948                    // Not an integer; just do string match.
11949                    if (strings == null) {
11950                        strings = new ArrayList<String>();
11951                    }
11952                    strings.add(name);
11953                    all = false;
11954                }
11955            }
11956        }
11957
11958        int build(String[] args, int opti) {
11959            for (; opti<args.length; opti++) {
11960                String name = args[opti];
11961                if ("--".equals(name)) {
11962                    return opti+1;
11963                }
11964                build(name);
11965            }
11966            return opti;
11967        }
11968
11969        boolean match(Object object, ComponentName comp) {
11970            if (all) {
11971                return true;
11972            }
11973            if (components != null) {
11974                for (int i=0; i<components.size(); i++) {
11975                    if (components.get(i).equals(comp)) {
11976                        return true;
11977                    }
11978                }
11979            }
11980            if (objects != null) {
11981                for (int i=0; i<objects.size(); i++) {
11982                    if (System.identityHashCode(object) == objects.get(i)) {
11983                        return true;
11984                    }
11985                }
11986            }
11987            if (strings != null) {
11988                String flat = comp.flattenToString();
11989                for (int i=0; i<strings.size(); i++) {
11990                    if (flat.contains(strings.get(i))) {
11991                        return true;
11992                    }
11993                }
11994            }
11995            return false;
11996        }
11997    }
11998
11999    /**
12000     * There are three things that cmd can be:
12001     *  - a flattened component name that matches an existing activity
12002     *  - the cmd arg isn't the flattened component name of an existing activity:
12003     *    dump all activity whose component contains the cmd as a substring
12004     *  - A hex number of the ActivityRecord object instance.
12005     */
12006    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12007            int opti, boolean dumpAll) {
12008        ArrayList<ActivityRecord> activities;
12009
12010        synchronized (this) {
12011            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12012        }
12013
12014        if (activities.size() <= 0) {
12015            return false;
12016        }
12017
12018        String[] newArgs = new String[args.length - opti];
12019        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12020
12021        TaskRecord lastTask = null;
12022        boolean needSep = false;
12023        for (int i=activities.size()-1; i>=0; i--) {
12024            ActivityRecord r = activities.get(i);
12025            if (needSep) {
12026                pw.println();
12027            }
12028            needSep = true;
12029            synchronized (this) {
12030                if (lastTask != r.task) {
12031                    lastTask = r.task;
12032                    pw.print("TASK "); pw.print(lastTask.affinity);
12033                            pw.print(" id="); pw.println(lastTask.taskId);
12034                    if (dumpAll) {
12035                        lastTask.dump(pw, "  ");
12036                    }
12037                }
12038            }
12039            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12040        }
12041        return true;
12042    }
12043
12044    /**
12045     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12046     * there is a thread associated with the activity.
12047     */
12048    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12049            final ActivityRecord r, String[] args, boolean dumpAll) {
12050        String innerPrefix = prefix + "  ";
12051        synchronized (this) {
12052            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12053                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12054                    pw.print(" pid=");
12055                    if (r.app != null) pw.println(r.app.pid);
12056                    else pw.println("(not running)");
12057            if (dumpAll) {
12058                r.dump(pw, innerPrefix);
12059            }
12060        }
12061        if (r.app != null && r.app.thread != null) {
12062            // flush anything that is already in the PrintWriter since the thread is going
12063            // to write to the file descriptor directly
12064            pw.flush();
12065            try {
12066                TransferPipe tp = new TransferPipe();
12067                try {
12068                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12069                            r.appToken, innerPrefix, args);
12070                    tp.go(fd);
12071                } finally {
12072                    tp.kill();
12073                }
12074            } catch (IOException e) {
12075                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12076            } catch (RemoteException e) {
12077                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12078            }
12079        }
12080    }
12081
12082    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12083            int opti, boolean dumpAll, String dumpPackage) {
12084        boolean needSep = false;
12085        boolean onlyHistory = false;
12086        boolean printedAnything = false;
12087
12088        if ("history".equals(dumpPackage)) {
12089            if (opti < args.length && "-s".equals(args[opti])) {
12090                dumpAll = false;
12091            }
12092            onlyHistory = true;
12093            dumpPackage = null;
12094        }
12095
12096        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12097        if (!onlyHistory && dumpAll) {
12098            if (mRegisteredReceivers.size() > 0) {
12099                boolean printed = false;
12100                Iterator it = mRegisteredReceivers.values().iterator();
12101                while (it.hasNext()) {
12102                    ReceiverList r = (ReceiverList)it.next();
12103                    if (dumpPackage != null && (r.app == null ||
12104                            !dumpPackage.equals(r.app.info.packageName))) {
12105                        continue;
12106                    }
12107                    if (!printed) {
12108                        pw.println("  Registered Receivers:");
12109                        needSep = true;
12110                        printed = true;
12111                        printedAnything = true;
12112                    }
12113                    pw.print("  * "); pw.println(r);
12114                    r.dump(pw, "    ");
12115                }
12116            }
12117
12118            if (mReceiverResolver.dump(pw, needSep ?
12119                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12120                    "    ", dumpPackage, false)) {
12121                needSep = true;
12122                printedAnything = true;
12123            }
12124        }
12125
12126        for (BroadcastQueue q : mBroadcastQueues) {
12127            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12128            printedAnything |= needSep;
12129        }
12130
12131        needSep = true;
12132
12133        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12134            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12135                if (needSep) {
12136                    pw.println();
12137                }
12138                needSep = true;
12139                printedAnything = true;
12140                pw.print("  Sticky broadcasts for user ");
12141                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12142                StringBuilder sb = new StringBuilder(128);
12143                for (Map.Entry<String, ArrayList<Intent>> ent
12144                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12145                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12146                    if (dumpAll) {
12147                        pw.println(":");
12148                        ArrayList<Intent> intents = ent.getValue();
12149                        final int N = intents.size();
12150                        for (int i=0; i<N; i++) {
12151                            sb.setLength(0);
12152                            sb.append("    Intent: ");
12153                            intents.get(i).toShortString(sb, false, true, false, false);
12154                            pw.println(sb.toString());
12155                            Bundle bundle = intents.get(i).getExtras();
12156                            if (bundle != null) {
12157                                pw.print("      ");
12158                                pw.println(bundle.toString());
12159                            }
12160                        }
12161                    } else {
12162                        pw.println("");
12163                    }
12164                }
12165            }
12166        }
12167
12168        if (!onlyHistory && dumpAll) {
12169            pw.println();
12170            for (BroadcastQueue queue : mBroadcastQueues) {
12171                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12172                        + queue.mBroadcastsScheduled);
12173            }
12174            pw.println("  mHandler:");
12175            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12176            needSep = true;
12177            printedAnything = true;
12178        }
12179
12180        if (!printedAnything) {
12181            pw.println("  (nothing)");
12182        }
12183    }
12184
12185    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12186            int opti, boolean dumpAll, String dumpPackage) {
12187        boolean needSep;
12188        boolean printedAnything = false;
12189
12190        ItemMatcher matcher = new ItemMatcher();
12191        matcher.build(args, opti);
12192
12193        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12194
12195        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12196        printedAnything |= needSep;
12197
12198        if (mLaunchingProviders.size() > 0) {
12199            boolean printed = false;
12200            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12201                ContentProviderRecord r = mLaunchingProviders.get(i);
12202                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12203                    continue;
12204                }
12205                if (!printed) {
12206                    if (needSep) pw.println();
12207                    needSep = true;
12208                    pw.println("  Launching content providers:");
12209                    printed = true;
12210                    printedAnything = true;
12211                }
12212                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12213                        pw.println(r);
12214            }
12215        }
12216
12217        if (mGrantedUriPermissions.size() > 0) {
12218            boolean printed = false;
12219            int dumpUid = -2;
12220            if (dumpPackage != null) {
12221                try {
12222                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12223                } catch (NameNotFoundException e) {
12224                    dumpUid = -1;
12225                }
12226            }
12227            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12228                int uid = mGrantedUriPermissions.keyAt(i);
12229                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12230                    continue;
12231                }
12232                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12233                if (!printed) {
12234                    if (needSep) pw.println();
12235                    needSep = true;
12236                    pw.println("  Granted Uri Permissions:");
12237                    printed = true;
12238                    printedAnything = true;
12239                }
12240                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12241                for (UriPermission perm : perms.values()) {
12242                    pw.print("    "); pw.println(perm);
12243                    if (dumpAll) {
12244                        perm.dump(pw, "      ");
12245                    }
12246                }
12247            }
12248        }
12249
12250        if (!printedAnything) {
12251            pw.println("  (nothing)");
12252        }
12253    }
12254
12255    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12256            int opti, boolean dumpAll, String dumpPackage) {
12257        boolean printed = false;
12258
12259        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12260
12261        if (mIntentSenderRecords.size() > 0) {
12262            Iterator<WeakReference<PendingIntentRecord>> it
12263                    = mIntentSenderRecords.values().iterator();
12264            while (it.hasNext()) {
12265                WeakReference<PendingIntentRecord> ref = it.next();
12266                PendingIntentRecord rec = ref != null ? ref.get(): null;
12267                if (dumpPackage != null && (rec == null
12268                        || !dumpPackage.equals(rec.key.packageName))) {
12269                    continue;
12270                }
12271                printed = true;
12272                if (rec != null) {
12273                    pw.print("  * "); pw.println(rec);
12274                    if (dumpAll) {
12275                        rec.dump(pw, "    ");
12276                    }
12277                } else {
12278                    pw.print("  * "); pw.println(ref);
12279                }
12280            }
12281        }
12282
12283        if (!printed) {
12284            pw.println("  (nothing)");
12285        }
12286    }
12287
12288    private static final int dumpProcessList(PrintWriter pw,
12289            ActivityManagerService service, List list,
12290            String prefix, String normalLabel, String persistentLabel,
12291            String dumpPackage) {
12292        int numPers = 0;
12293        final int N = list.size()-1;
12294        for (int i=N; i>=0; i--) {
12295            ProcessRecord r = (ProcessRecord)list.get(i);
12296            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12297                continue;
12298            }
12299            pw.println(String.format("%s%s #%2d: %s",
12300                    prefix, (r.persistent ? persistentLabel : normalLabel),
12301                    i, r.toString()));
12302            if (r.persistent) {
12303                numPers++;
12304            }
12305        }
12306        return numPers;
12307    }
12308
12309    private static final boolean dumpProcessOomList(PrintWriter pw,
12310            ActivityManagerService service, List<ProcessRecord> origList,
12311            String prefix, String normalLabel, String persistentLabel,
12312            boolean inclDetails, String dumpPackage) {
12313
12314        ArrayList<Pair<ProcessRecord, Integer>> list
12315                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12316        for (int i=0; i<origList.size(); i++) {
12317            ProcessRecord r = origList.get(i);
12318            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12319                continue;
12320            }
12321            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12322        }
12323
12324        if (list.size() <= 0) {
12325            return false;
12326        }
12327
12328        Comparator<Pair<ProcessRecord, Integer>> comparator
12329                = new Comparator<Pair<ProcessRecord, Integer>>() {
12330            @Override
12331            public int compare(Pair<ProcessRecord, Integer> object1,
12332                    Pair<ProcessRecord, Integer> object2) {
12333                if (object1.first.setAdj != object2.first.setAdj) {
12334                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12335                }
12336                if (object1.second.intValue() != object2.second.intValue()) {
12337                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12338                }
12339                return 0;
12340            }
12341        };
12342
12343        Collections.sort(list, comparator);
12344
12345        final long curRealtime = SystemClock.elapsedRealtime();
12346        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12347        final long curUptime = SystemClock.uptimeMillis();
12348        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12349
12350        for (int i=list.size()-1; i>=0; i--) {
12351            ProcessRecord r = list.get(i).first;
12352            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12353            char schedGroup;
12354            switch (r.setSchedGroup) {
12355                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12356                    schedGroup = 'B';
12357                    break;
12358                case Process.THREAD_GROUP_DEFAULT:
12359                    schedGroup = 'F';
12360                    break;
12361                default:
12362                    schedGroup = '?';
12363                    break;
12364            }
12365            char foreground;
12366            if (r.foregroundActivities) {
12367                foreground = 'A';
12368            } else if (r.foregroundServices) {
12369                foreground = 'S';
12370            } else {
12371                foreground = ' ';
12372            }
12373            String procState = ProcessList.makeProcStateString(r.curProcState);
12374            pw.print(prefix);
12375            pw.print(r.persistent ? persistentLabel : normalLabel);
12376            pw.print(" #");
12377            int num = (origList.size()-1)-list.get(i).second;
12378            if (num < 10) pw.print(' ');
12379            pw.print(num);
12380            pw.print(": ");
12381            pw.print(oomAdj);
12382            pw.print(' ');
12383            pw.print(schedGroup);
12384            pw.print('/');
12385            pw.print(foreground);
12386            pw.print('/');
12387            pw.print(procState);
12388            pw.print(" trm:");
12389            if (r.trimMemoryLevel < 10) pw.print(' ');
12390            pw.print(r.trimMemoryLevel);
12391            pw.print(' ');
12392            pw.print(r.toShortString());
12393            pw.print(" (");
12394            pw.print(r.adjType);
12395            pw.println(')');
12396            if (r.adjSource != null || r.adjTarget != null) {
12397                pw.print(prefix);
12398                pw.print("    ");
12399                if (r.adjTarget instanceof ComponentName) {
12400                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12401                } else if (r.adjTarget != null) {
12402                    pw.print(r.adjTarget.toString());
12403                } else {
12404                    pw.print("{null}");
12405                }
12406                pw.print("<=");
12407                if (r.adjSource instanceof ProcessRecord) {
12408                    pw.print("Proc{");
12409                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12410                    pw.println("}");
12411                } else if (r.adjSource != null) {
12412                    pw.println(r.adjSource.toString());
12413                } else {
12414                    pw.println("{null}");
12415                }
12416            }
12417            if (inclDetails) {
12418                pw.print(prefix);
12419                pw.print("    ");
12420                pw.print("oom: max="); pw.print(r.maxAdj);
12421                pw.print(" curRaw="); pw.print(r.curRawAdj);
12422                pw.print(" setRaw="); pw.print(r.setRawAdj);
12423                pw.print(" cur="); pw.print(r.curAdj);
12424                pw.print(" set="); pw.println(r.setAdj);
12425                pw.print(prefix);
12426                pw.print("    ");
12427                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12428                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12429                pw.print(" lastPss="); pw.print(r.lastPss);
12430                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12431                pw.print(prefix);
12432                pw.print("    ");
12433                pw.print("keeping="); pw.print(r.keeping);
12434                pw.print(" cached="); pw.print(r.cached);
12435                pw.print(" empty="); pw.print(r.empty);
12436                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12437
12438                if (!r.keeping) {
12439                    if (r.lastWakeTime != 0) {
12440                        long wtime;
12441                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12442                        synchronized (stats) {
12443                            wtime = stats.getProcessWakeTime(r.info.uid,
12444                                    r.pid, curRealtime);
12445                        }
12446                        long timeUsed = wtime - r.lastWakeTime;
12447                        pw.print(prefix);
12448                        pw.print("    ");
12449                        pw.print("keep awake over ");
12450                        TimeUtils.formatDuration(realtimeSince, pw);
12451                        pw.print(" used ");
12452                        TimeUtils.formatDuration(timeUsed, pw);
12453                        pw.print(" (");
12454                        pw.print((timeUsed*100)/realtimeSince);
12455                        pw.println("%)");
12456                    }
12457                    if (r.lastCpuTime != 0) {
12458                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12459                        pw.print(prefix);
12460                        pw.print("    ");
12461                        pw.print("run cpu over ");
12462                        TimeUtils.formatDuration(uptimeSince, pw);
12463                        pw.print(" used ");
12464                        TimeUtils.formatDuration(timeUsed, pw);
12465                        pw.print(" (");
12466                        pw.print((timeUsed*100)/uptimeSince);
12467                        pw.println("%)");
12468                    }
12469                }
12470            }
12471        }
12472        return true;
12473    }
12474
12475    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12476        ArrayList<ProcessRecord> procs;
12477        synchronized (this) {
12478            if (args != null && args.length > start
12479                    && args[start].charAt(0) != '-') {
12480                procs = new ArrayList<ProcessRecord>();
12481                int pid = -1;
12482                try {
12483                    pid = Integer.parseInt(args[start]);
12484                } catch (NumberFormatException e) {
12485                }
12486                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12487                    ProcessRecord proc = mLruProcesses.get(i);
12488                    if (proc.pid == pid) {
12489                        procs.add(proc);
12490                    } else if (proc.processName.equals(args[start])) {
12491                        procs.add(proc);
12492                    }
12493                }
12494                if (procs.size() <= 0) {
12495                    return null;
12496                }
12497            } else {
12498                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12499            }
12500        }
12501        return procs;
12502    }
12503
12504    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12505            PrintWriter pw, String[] args) {
12506        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12507        if (procs == null) {
12508            pw.println("No process found for: " + args[0]);
12509            return;
12510        }
12511
12512        long uptime = SystemClock.uptimeMillis();
12513        long realtime = SystemClock.elapsedRealtime();
12514        pw.println("Applications Graphics Acceleration Info:");
12515        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12516
12517        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12518            ProcessRecord r = procs.get(i);
12519            if (r.thread != null) {
12520                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12521                pw.flush();
12522                try {
12523                    TransferPipe tp = new TransferPipe();
12524                    try {
12525                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12526                        tp.go(fd);
12527                    } finally {
12528                        tp.kill();
12529                    }
12530                } catch (IOException e) {
12531                    pw.println("Failure while dumping the app: " + r);
12532                    pw.flush();
12533                } catch (RemoteException e) {
12534                    pw.println("Got a RemoteException while dumping the app " + r);
12535                    pw.flush();
12536                }
12537            }
12538        }
12539    }
12540
12541    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12542        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12543        if (procs == null) {
12544            pw.println("No process found for: " + args[0]);
12545            return;
12546        }
12547
12548        pw.println("Applications Database Info:");
12549
12550        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12551            ProcessRecord r = procs.get(i);
12552            if (r.thread != null) {
12553                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12554                pw.flush();
12555                try {
12556                    TransferPipe tp = new TransferPipe();
12557                    try {
12558                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12559                        tp.go(fd);
12560                    } finally {
12561                        tp.kill();
12562                    }
12563                } catch (IOException e) {
12564                    pw.println("Failure while dumping the app: " + r);
12565                    pw.flush();
12566                } catch (RemoteException e) {
12567                    pw.println("Got a RemoteException while dumping the app " + r);
12568                    pw.flush();
12569                }
12570            }
12571        }
12572    }
12573
12574    final static class MemItem {
12575        final boolean isProc;
12576        final String label;
12577        final String shortLabel;
12578        final long pss;
12579        final int id;
12580        final boolean hasActivities;
12581        ArrayList<MemItem> subitems;
12582
12583        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12584                boolean _hasActivities) {
12585            isProc = true;
12586            label = _label;
12587            shortLabel = _shortLabel;
12588            pss = _pss;
12589            id = _id;
12590            hasActivities = _hasActivities;
12591        }
12592
12593        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12594            isProc = false;
12595            label = _label;
12596            shortLabel = _shortLabel;
12597            pss = _pss;
12598            id = _id;
12599            hasActivities = false;
12600        }
12601    }
12602
12603    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12604            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12605        if (sort && !isCompact) {
12606            Collections.sort(items, new Comparator<MemItem>() {
12607                @Override
12608                public int compare(MemItem lhs, MemItem rhs) {
12609                    if (lhs.pss < rhs.pss) {
12610                        return 1;
12611                    } else if (lhs.pss > rhs.pss) {
12612                        return -1;
12613                    }
12614                    return 0;
12615                }
12616            });
12617        }
12618
12619        for (int i=0; i<items.size(); i++) {
12620            MemItem mi = items.get(i);
12621            if (!isCompact) {
12622                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12623            } else if (mi.isProc) {
12624                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12625                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12626                pw.println(mi.hasActivities ? ",a" : ",e");
12627            } else {
12628                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12629                pw.println(mi.pss);
12630            }
12631            if (mi.subitems != null) {
12632                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12633                        true, isCompact);
12634            }
12635        }
12636    }
12637
12638    // These are in KB.
12639    static final long[] DUMP_MEM_BUCKETS = new long[] {
12640        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12641        120*1024, 160*1024, 200*1024,
12642        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12643        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12644    };
12645
12646    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12647            boolean stackLike) {
12648        int start = label.lastIndexOf('.');
12649        if (start >= 0) start++;
12650        else start = 0;
12651        int end = label.length();
12652        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12653            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12654                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12655                out.append(bucket);
12656                out.append(stackLike ? "MB." : "MB ");
12657                out.append(label, start, end);
12658                return;
12659            }
12660        }
12661        out.append(memKB/1024);
12662        out.append(stackLike ? "MB." : "MB ");
12663        out.append(label, start, end);
12664    }
12665
12666    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12667            ProcessList.NATIVE_ADJ,
12668            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12669            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12670            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12671            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12672            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12673    };
12674    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12675            "Native",
12676            "System", "Persistent", "Foreground",
12677            "Visible", "Perceptible",
12678            "Heavy Weight", "Backup",
12679            "A Services", "Home",
12680            "Previous", "B Services", "Cached"
12681    };
12682    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12683            "native",
12684            "sys", "pers", "fore",
12685            "vis", "percept",
12686            "heavy", "backup",
12687            "servicea", "home",
12688            "prev", "serviceb", "cached"
12689    };
12690
12691    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12692            long realtime, boolean isCheckinRequest, boolean isCompact) {
12693        if (isCheckinRequest || isCompact) {
12694            // short checkin version
12695            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12696        } else {
12697            pw.println("Applications Memory Usage (kB):");
12698            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12699        }
12700    }
12701
12702    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12703            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12704        boolean dumpDetails = false;
12705        boolean dumpFullDetails = false;
12706        boolean dumpDalvik = false;
12707        boolean oomOnly = false;
12708        boolean isCompact = false;
12709        boolean localOnly = false;
12710
12711        int opti = 0;
12712        while (opti < args.length) {
12713            String opt = args[opti];
12714            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12715                break;
12716            }
12717            opti++;
12718            if ("-a".equals(opt)) {
12719                dumpDetails = true;
12720                dumpFullDetails = true;
12721                dumpDalvik = true;
12722            } else if ("-d".equals(opt)) {
12723                dumpDalvik = true;
12724            } else if ("-c".equals(opt)) {
12725                isCompact = true;
12726            } else if ("--oom".equals(opt)) {
12727                oomOnly = true;
12728            } else if ("--local".equals(opt)) {
12729                localOnly = true;
12730            } else if ("-h".equals(opt)) {
12731                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12732                pw.println("  -a: include all available information for each process.");
12733                pw.println("  -d: include dalvik details when dumping process details.");
12734                pw.println("  -c: dump in a compact machine-parseable representation.");
12735                pw.println("  --oom: only show processes organized by oom adj.");
12736                pw.println("  --local: only collect details locally, don't call process.");
12737                pw.println("If [process] is specified it can be the name or ");
12738                pw.println("pid of a specific process to dump.");
12739                return;
12740            } else {
12741                pw.println("Unknown argument: " + opt + "; use -h for help");
12742            }
12743        }
12744
12745        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12746        long uptime = SystemClock.uptimeMillis();
12747        long realtime = SystemClock.elapsedRealtime();
12748        final long[] tmpLong = new long[1];
12749
12750        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12751        if (procs == null) {
12752            // No Java processes.  Maybe they want to print a native process.
12753            if (args != null && args.length > opti
12754                    && args[opti].charAt(0) != '-') {
12755                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12756                        = new ArrayList<ProcessCpuTracker.Stats>();
12757                updateCpuStatsNow();
12758                int findPid = -1;
12759                try {
12760                    findPid = Integer.parseInt(args[opti]);
12761                } catch (NumberFormatException e) {
12762                }
12763                synchronized (mProcessCpuThread) {
12764                    final int N = mProcessCpuTracker.countStats();
12765                    for (int i=0; i<N; i++) {
12766                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12767                        if (st.pid == findPid || (st.baseName != null
12768                                && st.baseName.equals(args[opti]))) {
12769                            nativeProcs.add(st);
12770                        }
12771                    }
12772                }
12773                if (nativeProcs.size() > 0) {
12774                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12775                            isCompact);
12776                    Debug.MemoryInfo mi = null;
12777                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12778                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12779                        final int pid = r.pid;
12780                        if (!isCheckinRequest && dumpDetails) {
12781                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12782                        }
12783                        if (mi == null) {
12784                            mi = new Debug.MemoryInfo();
12785                        }
12786                        if (dumpDetails || (!brief && !oomOnly)) {
12787                            Debug.getMemoryInfo(pid, mi);
12788                        } else {
12789                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12790                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12791                        }
12792                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12793                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12794                        if (isCheckinRequest) {
12795                            pw.println();
12796                        }
12797                    }
12798                    return;
12799                }
12800            }
12801            pw.println("No process found for: " + args[opti]);
12802            return;
12803        }
12804
12805        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12806            dumpDetails = true;
12807        }
12808
12809        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12810
12811        String[] innerArgs = new String[args.length-opti];
12812        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12813
12814        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12815        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12816        long nativePss=0, dalvikPss=0, otherPss=0;
12817        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12818
12819        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12820        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12821                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12822
12823        long totalPss = 0;
12824        long cachedPss = 0;
12825
12826        Debug.MemoryInfo mi = null;
12827        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12828            final ProcessRecord r = procs.get(i);
12829            final IApplicationThread thread;
12830            final int pid;
12831            final int oomAdj;
12832            final boolean hasActivities;
12833            synchronized (this) {
12834                thread = r.thread;
12835                pid = r.pid;
12836                oomAdj = r.getSetAdjWithServices();
12837                hasActivities = r.activities.size() > 0;
12838            }
12839            if (thread != null) {
12840                if (!isCheckinRequest && dumpDetails) {
12841                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12842                }
12843                if (mi == null) {
12844                    mi = new Debug.MemoryInfo();
12845                }
12846                if (dumpDetails || (!brief && !oomOnly)) {
12847                    Debug.getMemoryInfo(pid, mi);
12848                } else {
12849                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12850                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12851                }
12852                if (dumpDetails) {
12853                    if (localOnly) {
12854                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12855                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12856                        if (isCheckinRequest) {
12857                            pw.println();
12858                        }
12859                    } else {
12860                        try {
12861                            pw.flush();
12862                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12863                                    dumpDalvik, innerArgs);
12864                        } catch (RemoteException e) {
12865                            if (!isCheckinRequest) {
12866                                pw.println("Got RemoteException!");
12867                                pw.flush();
12868                            }
12869                        }
12870                    }
12871                }
12872
12873                final long myTotalPss = mi.getTotalPss();
12874                final long myTotalUss = mi.getTotalUss();
12875
12876                synchronized (this) {
12877                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12878                        // Record this for posterity if the process has been stable.
12879                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12880                    }
12881                }
12882
12883                if (!isCheckinRequest && mi != null) {
12884                    totalPss += myTotalPss;
12885                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12886                            (hasActivities ? " / activities)" : ")"),
12887                            r.processName, myTotalPss, pid, hasActivities);
12888                    procMems.add(pssItem);
12889                    procMemsMap.put(pid, pssItem);
12890
12891                    nativePss += mi.nativePss;
12892                    dalvikPss += mi.dalvikPss;
12893                    otherPss += mi.otherPss;
12894                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12895                        long mem = mi.getOtherPss(j);
12896                        miscPss[j] += mem;
12897                        otherPss -= mem;
12898                    }
12899
12900                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12901                        cachedPss += myTotalPss;
12902                    }
12903
12904                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12905                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12906                                || oomIndex == (oomPss.length-1)) {
12907                            oomPss[oomIndex] += myTotalPss;
12908                            if (oomProcs[oomIndex] == null) {
12909                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12910                            }
12911                            oomProcs[oomIndex].add(pssItem);
12912                            break;
12913                        }
12914                    }
12915                }
12916            }
12917        }
12918
12919        long nativeProcTotalPss = 0;
12920
12921        if (!isCheckinRequest && procs.size() > 1) {
12922            // If we are showing aggregations, also look for native processes to
12923            // include so that our aggregations are more accurate.
12924            updateCpuStatsNow();
12925            synchronized (mProcessCpuThread) {
12926                final int N = mProcessCpuTracker.countStats();
12927                for (int i=0; i<N; i++) {
12928                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12929                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12930                        if (mi == null) {
12931                            mi = new Debug.MemoryInfo();
12932                        }
12933                        if (!brief && !oomOnly) {
12934                            Debug.getMemoryInfo(st.pid, mi);
12935                        } else {
12936                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12937                            mi.nativePrivateDirty = (int)tmpLong[0];
12938                        }
12939
12940                        final long myTotalPss = mi.getTotalPss();
12941                        totalPss += myTotalPss;
12942                        nativeProcTotalPss += myTotalPss;
12943
12944                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12945                                st.name, myTotalPss, st.pid, false);
12946                        procMems.add(pssItem);
12947
12948                        nativePss += mi.nativePss;
12949                        dalvikPss += mi.dalvikPss;
12950                        otherPss += mi.otherPss;
12951                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12952                            long mem = mi.getOtherPss(j);
12953                            miscPss[j] += mem;
12954                            otherPss -= mem;
12955                        }
12956                        oomPss[0] += myTotalPss;
12957                        if (oomProcs[0] == null) {
12958                            oomProcs[0] = new ArrayList<MemItem>();
12959                        }
12960                        oomProcs[0].add(pssItem);
12961                    }
12962                }
12963            }
12964
12965            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12966
12967            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12968            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12969            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12970            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12971                String label = Debug.MemoryInfo.getOtherLabel(j);
12972                catMems.add(new MemItem(label, label, miscPss[j], j));
12973            }
12974
12975            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12976            for (int j=0; j<oomPss.length; j++) {
12977                if (oomPss[j] != 0) {
12978                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12979                            : DUMP_MEM_OOM_LABEL[j];
12980                    MemItem item = new MemItem(label, label, oomPss[j],
12981                            DUMP_MEM_OOM_ADJ[j]);
12982                    item.subitems = oomProcs[j];
12983                    oomMems.add(item);
12984                }
12985            }
12986
12987            if (!brief && !oomOnly && !isCompact) {
12988                pw.println();
12989                pw.println("Total PSS by process:");
12990                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12991                pw.println();
12992            }
12993            if (!isCompact) {
12994                pw.println("Total PSS by OOM adjustment:");
12995            }
12996            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12997            if (!brief && !oomOnly) {
12998                PrintWriter out = categoryPw != null ? categoryPw : pw;
12999                if (!isCompact) {
13000                    out.println();
13001                    out.println("Total PSS by category:");
13002                }
13003                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13004            }
13005            if (!isCompact) {
13006                pw.println();
13007            }
13008            MemInfoReader memInfo = new MemInfoReader();
13009            memInfo.readMemInfo();
13010            if (nativeProcTotalPss > 0) {
13011                synchronized (this) {
13012                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13013                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13014                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13015                            nativeProcTotalPss);
13016                }
13017            }
13018            if (!brief) {
13019                if (!isCompact) {
13020                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13021                    pw.print(" kB (status ");
13022                    switch (mLastMemoryLevel) {
13023                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13024                            pw.println("normal)");
13025                            break;
13026                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13027                            pw.println("moderate)");
13028                            break;
13029                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13030                            pw.println("low)");
13031                            break;
13032                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13033                            pw.println("critical)");
13034                            break;
13035                        default:
13036                            pw.print(mLastMemoryLevel);
13037                            pw.println(")");
13038                            break;
13039                    }
13040                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13041                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13042                            pw.print(cachedPss); pw.print(" cached pss + ");
13043                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13044                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13045                } else {
13046                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13047                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13048                            + memInfo.getFreeSizeKb()); pw.print(",");
13049                    pw.println(totalPss - cachedPss);
13050                }
13051            }
13052            if (!isCompact) {
13053                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13054                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13055                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13056                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13057                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13058                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13059                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13060                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13061                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13062                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13063                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13064            }
13065            if (!brief) {
13066                if (memInfo.getZramTotalSizeKb() != 0) {
13067                    if (!isCompact) {
13068                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13069                                pw.print(" kB physical used for ");
13070                                pw.print(memInfo.getSwapTotalSizeKb()
13071                                        - memInfo.getSwapFreeSizeKb());
13072                                pw.print(" kB in swap (");
13073                                pw.print(memInfo.getSwapTotalSizeKb());
13074                                pw.println(" kB total swap)");
13075                    } else {
13076                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13077                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13078                                pw.println(memInfo.getSwapFreeSizeKb());
13079                    }
13080                }
13081                final int[] SINGLE_LONG_FORMAT = new int[] {
13082                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13083                };
13084                long[] longOut = new long[1];
13085                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13086                        SINGLE_LONG_FORMAT, null, longOut, null);
13087                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13088                longOut[0] = 0;
13089                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13090                        SINGLE_LONG_FORMAT, null, longOut, null);
13091                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13092                longOut[0] = 0;
13093                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13094                        SINGLE_LONG_FORMAT, null, longOut, null);
13095                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13096                longOut[0] = 0;
13097                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13098                        SINGLE_LONG_FORMAT, null, longOut, null);
13099                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13100                if (!isCompact) {
13101                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13102                        pw.print("      KSM: "); pw.print(sharing);
13103                                pw.print(" kB saved from shared ");
13104                                pw.print(shared); pw.println(" kB");
13105                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13106                                pw.print(voltile); pw.println(" kB volatile");
13107                    }
13108                    pw.print("   Tuning: ");
13109                    pw.print(ActivityManager.staticGetMemoryClass());
13110                    pw.print(" (large ");
13111                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13112                    pw.print("), oom ");
13113                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13114                    pw.print(" kB");
13115                    pw.print(", restore limit ");
13116                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13117                    pw.print(" kB");
13118                    if (ActivityManager.isLowRamDeviceStatic()) {
13119                        pw.print(" (low-ram)");
13120                    }
13121                    if (ActivityManager.isHighEndGfx()) {
13122                        pw.print(" (high-end-gfx)");
13123                    }
13124                    pw.println();
13125                } else {
13126                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13127                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13128                    pw.println(voltile);
13129                    pw.print("tuning,");
13130                    pw.print(ActivityManager.staticGetMemoryClass());
13131                    pw.print(',');
13132                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13133                    pw.print(',');
13134                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13135                    if (ActivityManager.isLowRamDeviceStatic()) {
13136                        pw.print(",low-ram");
13137                    }
13138                    if (ActivityManager.isHighEndGfx()) {
13139                        pw.print(",high-end-gfx");
13140                    }
13141                    pw.println();
13142                }
13143            }
13144        }
13145    }
13146
13147    /**
13148     * Searches array of arguments for the specified string
13149     * @param args array of argument strings
13150     * @param value value to search for
13151     * @return true if the value is contained in the array
13152     */
13153    private static boolean scanArgs(String[] args, String value) {
13154        if (args != null) {
13155            for (String arg : args) {
13156                if (value.equals(arg)) {
13157                    return true;
13158                }
13159            }
13160        }
13161        return false;
13162    }
13163
13164    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13165            ContentProviderRecord cpr, boolean always) {
13166        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13167
13168        if (!inLaunching || always) {
13169            synchronized (cpr) {
13170                cpr.launchingApp = null;
13171                cpr.notifyAll();
13172            }
13173            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13174            String names[] = cpr.info.authority.split(";");
13175            for (int j = 0; j < names.length; j++) {
13176                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13177            }
13178        }
13179
13180        for (int i=0; i<cpr.connections.size(); i++) {
13181            ContentProviderConnection conn = cpr.connections.get(i);
13182            if (conn.waiting) {
13183                // If this connection is waiting for the provider, then we don't
13184                // need to mess with its process unless we are always removing
13185                // or for some reason the provider is not currently launching.
13186                if (inLaunching && !always) {
13187                    continue;
13188                }
13189            }
13190            ProcessRecord capp = conn.client;
13191            conn.dead = true;
13192            if (conn.stableCount > 0) {
13193                if (!capp.persistent && capp.thread != null
13194                        && capp.pid != 0
13195                        && capp.pid != MY_PID) {
13196                    killUnneededProcessLocked(capp, "depends on provider "
13197                            + cpr.name.flattenToShortString()
13198                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13199                }
13200            } else if (capp.thread != null && conn.provider.provider != null) {
13201                try {
13202                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13203                } catch (RemoteException e) {
13204                }
13205                // In the protocol here, we don't expect the client to correctly
13206                // clean up this connection, we'll just remove it.
13207                cpr.connections.remove(i);
13208                conn.client.conProviders.remove(conn);
13209            }
13210        }
13211
13212        if (inLaunching && always) {
13213            mLaunchingProviders.remove(cpr);
13214        }
13215        return inLaunching;
13216    }
13217
13218    /**
13219     * Main code for cleaning up a process when it has gone away.  This is
13220     * called both as a result of the process dying, or directly when stopping
13221     * a process when running in single process mode.
13222     */
13223    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13224            boolean restarting, boolean allowRestart, int index) {
13225        if (index >= 0) {
13226            removeLruProcessLocked(app);
13227            ProcessList.remove(app.pid);
13228        }
13229
13230        mProcessesToGc.remove(app);
13231        mPendingPssProcesses.remove(app);
13232
13233        // Dismiss any open dialogs.
13234        if (app.crashDialog != null && !app.forceCrashReport) {
13235            app.crashDialog.dismiss();
13236            app.crashDialog = null;
13237        }
13238        if (app.anrDialog != null) {
13239            app.anrDialog.dismiss();
13240            app.anrDialog = null;
13241        }
13242        if (app.waitDialog != null) {
13243            app.waitDialog.dismiss();
13244            app.waitDialog = null;
13245        }
13246
13247        app.crashing = false;
13248        app.notResponding = false;
13249
13250        app.resetPackageList(mProcessStats);
13251        app.unlinkDeathRecipient();
13252        app.makeInactive(mProcessStats);
13253        app.waitingToKill = null;
13254        app.forcingToForeground = null;
13255        updateProcessForegroundLocked(app, false, false);
13256        app.foregroundActivities = false;
13257        app.hasShownUi = false;
13258        app.treatLikeActivity = false;
13259        app.hasAboveClient = false;
13260        app.hasClientActivities = false;
13261
13262        mServices.killServicesLocked(app, allowRestart);
13263
13264        boolean restart = false;
13265
13266        // Remove published content providers.
13267        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13268            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13269            final boolean always = app.bad || !allowRestart;
13270            if (removeDyingProviderLocked(app, cpr, always) || always) {
13271                // We left the provider in the launching list, need to
13272                // restart it.
13273                restart = true;
13274            }
13275
13276            cpr.provider = null;
13277            cpr.proc = null;
13278        }
13279        app.pubProviders.clear();
13280
13281        // Take care of any launching providers waiting for this process.
13282        if (checkAppInLaunchingProvidersLocked(app, false)) {
13283            restart = true;
13284        }
13285
13286        // Unregister from connected content providers.
13287        if (!app.conProviders.isEmpty()) {
13288            for (int i=0; i<app.conProviders.size(); i++) {
13289                ContentProviderConnection conn = app.conProviders.get(i);
13290                conn.provider.connections.remove(conn);
13291            }
13292            app.conProviders.clear();
13293        }
13294
13295        // At this point there may be remaining entries in mLaunchingProviders
13296        // where we were the only one waiting, so they are no longer of use.
13297        // Look for these and clean up if found.
13298        // XXX Commented out for now.  Trying to figure out a way to reproduce
13299        // the actual situation to identify what is actually going on.
13300        if (false) {
13301            for (int i=0; i<mLaunchingProviders.size(); i++) {
13302                ContentProviderRecord cpr = (ContentProviderRecord)
13303                        mLaunchingProviders.get(i);
13304                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13305                    synchronized (cpr) {
13306                        cpr.launchingApp = null;
13307                        cpr.notifyAll();
13308                    }
13309                }
13310            }
13311        }
13312
13313        skipCurrentReceiverLocked(app);
13314
13315        // Unregister any receivers.
13316        for (int i=app.receivers.size()-1; i>=0; i--) {
13317            removeReceiverLocked(app.receivers.valueAt(i));
13318        }
13319        app.receivers.clear();
13320
13321        // If the app is undergoing backup, tell the backup manager about it
13322        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13323            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13324                    + mBackupTarget.appInfo + " died during backup");
13325            try {
13326                IBackupManager bm = IBackupManager.Stub.asInterface(
13327                        ServiceManager.getService(Context.BACKUP_SERVICE));
13328                bm.agentDisconnected(app.info.packageName);
13329            } catch (RemoteException e) {
13330                // can't happen; backup manager is local
13331            }
13332        }
13333
13334        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13335            ProcessChangeItem item = mPendingProcessChanges.get(i);
13336            if (item.pid == app.pid) {
13337                mPendingProcessChanges.remove(i);
13338                mAvailProcessChanges.add(item);
13339            }
13340        }
13341        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13342
13343        // If the caller is restarting this app, then leave it in its
13344        // current lists and let the caller take care of it.
13345        if (restarting) {
13346            return;
13347        }
13348
13349        if (!app.persistent || app.isolated) {
13350            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13351                    "Removing non-persistent process during cleanup: " + app);
13352            mProcessNames.remove(app.processName, app.uid);
13353            mIsolatedProcesses.remove(app.uid);
13354            if (mHeavyWeightProcess == app) {
13355                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13356                        mHeavyWeightProcess.userId, 0));
13357                mHeavyWeightProcess = null;
13358            }
13359        } else if (!app.removed) {
13360            // This app is persistent, so we need to keep its record around.
13361            // If it is not already on the pending app list, add it there
13362            // and start a new process for it.
13363            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13364                mPersistentStartingProcesses.add(app);
13365                restart = true;
13366            }
13367        }
13368        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13369                "Clean-up removing on hold: " + app);
13370        mProcessesOnHold.remove(app);
13371
13372        if (app == mHomeProcess) {
13373            mHomeProcess = null;
13374        }
13375        if (app == mPreviousProcess) {
13376            mPreviousProcess = null;
13377        }
13378
13379        if (restart && !app.isolated) {
13380            // We have components that still need to be running in the
13381            // process, so re-launch it.
13382            mProcessNames.put(app.processName, app.uid, app);
13383            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13384        } else if (app.pid > 0 && app.pid != MY_PID) {
13385            // Goodbye!
13386            boolean removed;
13387            synchronized (mPidsSelfLocked) {
13388                mPidsSelfLocked.remove(app.pid);
13389                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13390            }
13391            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
13392            if (app.isolated) {
13393                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13394            }
13395            app.setPid(0);
13396        }
13397    }
13398
13399    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13400        // Look through the content providers we are waiting to have launched,
13401        // and if any run in this process then either schedule a restart of
13402        // the process or kill the client waiting for it if this process has
13403        // gone bad.
13404        int NL = mLaunchingProviders.size();
13405        boolean restart = false;
13406        for (int i=0; i<NL; i++) {
13407            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13408            if (cpr.launchingApp == app) {
13409                if (!alwaysBad && !app.bad) {
13410                    restart = true;
13411                } else {
13412                    removeDyingProviderLocked(app, cpr, true);
13413                    // cpr should have been removed from mLaunchingProviders
13414                    NL = mLaunchingProviders.size();
13415                    i--;
13416                }
13417            }
13418        }
13419        return restart;
13420    }
13421
13422    // =========================================================
13423    // SERVICES
13424    // =========================================================
13425
13426    @Override
13427    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13428            int flags) {
13429        enforceNotIsolatedCaller("getServices");
13430        synchronized (this) {
13431            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13432        }
13433    }
13434
13435    @Override
13436    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13437        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13438        synchronized (this) {
13439            return mServices.getRunningServiceControlPanelLocked(name);
13440        }
13441    }
13442
13443    @Override
13444    public ComponentName startService(IApplicationThread caller, Intent service,
13445            String resolvedType, int userId) {
13446        enforceNotIsolatedCaller("startService");
13447        // Refuse possible leaked file descriptors
13448        if (service != null && service.hasFileDescriptors() == true) {
13449            throw new IllegalArgumentException("File descriptors passed in Intent");
13450        }
13451
13452        if (DEBUG_SERVICE)
13453            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13454        synchronized(this) {
13455            final int callingPid = Binder.getCallingPid();
13456            final int callingUid = Binder.getCallingUid();
13457            final long origId = Binder.clearCallingIdentity();
13458            ComponentName res = mServices.startServiceLocked(caller, service,
13459                    resolvedType, callingPid, callingUid, userId);
13460            Binder.restoreCallingIdentity(origId);
13461            return res;
13462        }
13463    }
13464
13465    ComponentName startServiceInPackage(int uid,
13466            Intent service, String resolvedType, int userId) {
13467        synchronized(this) {
13468            if (DEBUG_SERVICE)
13469                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13470            final long origId = Binder.clearCallingIdentity();
13471            ComponentName res = mServices.startServiceLocked(null, service,
13472                    resolvedType, -1, uid, userId);
13473            Binder.restoreCallingIdentity(origId);
13474            return res;
13475        }
13476    }
13477
13478    @Override
13479    public int stopService(IApplicationThread caller, Intent service,
13480            String resolvedType, int userId) {
13481        enforceNotIsolatedCaller("stopService");
13482        // Refuse possible leaked file descriptors
13483        if (service != null && service.hasFileDescriptors() == true) {
13484            throw new IllegalArgumentException("File descriptors passed in Intent");
13485        }
13486
13487        synchronized(this) {
13488            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13489        }
13490    }
13491
13492    @Override
13493    public IBinder peekService(Intent service, String resolvedType) {
13494        enforceNotIsolatedCaller("peekService");
13495        // Refuse possible leaked file descriptors
13496        if (service != null && service.hasFileDescriptors() == true) {
13497            throw new IllegalArgumentException("File descriptors passed in Intent");
13498        }
13499        synchronized(this) {
13500            return mServices.peekServiceLocked(service, resolvedType);
13501        }
13502    }
13503
13504    @Override
13505    public boolean stopServiceToken(ComponentName className, IBinder token,
13506            int startId) {
13507        synchronized(this) {
13508            return mServices.stopServiceTokenLocked(className, token, startId);
13509        }
13510    }
13511
13512    @Override
13513    public void setServiceForeground(ComponentName className, IBinder token,
13514            int id, Notification notification, boolean removeNotification) {
13515        synchronized(this) {
13516            mServices.setServiceForegroundLocked(className, token, id, notification,
13517                    removeNotification);
13518        }
13519    }
13520
13521    @Override
13522    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13523            boolean requireFull, String name, String callerPackage) {
13524        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
13525                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
13526    }
13527
13528    int unsafeConvertIncomingUser(int userId) {
13529        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
13530                ? mCurrentUserId : userId;
13531    }
13532
13533    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13534            int allowMode, String name, String callerPackage) {
13535        final int callingUserId = UserHandle.getUserId(callingUid);
13536        if (callingUserId == userId) {
13537            return userId;
13538        }
13539
13540        // Note that we may be accessing mCurrentUserId outside of a lock...
13541        // shouldn't be a big deal, if this is being called outside
13542        // of a locked context there is intrinsically a race with
13543        // the value the caller will receive and someone else changing it.
13544        // We assume that USER_CURRENT_OR_SELF will use the current user; later
13545        // we will switch to the calling user if access to the current user fails.
13546        int targetUserId = unsafeConvertIncomingUser(userId);
13547
13548        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13549            final boolean allow;
13550            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
13551                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
13552                // If the caller has this permission, they always pass go.  And collect $200.
13553                allow = true;
13554            } else if (allowMode == ALLOW_FULL_ONLY) {
13555                // We require full access, sucks to be you.
13556                allow = false;
13557            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
13558                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
13559                // If the caller does not have either permission, they are always doomed.
13560                allow = false;
13561            } else if (allowMode == ALLOW_NON_FULL) {
13562                // We are blanket allowing non-full access, you lucky caller!
13563                allow = true;
13564            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
13565                // We may or may not allow this depending on whether the two users are
13566                // in the same profile.
13567                synchronized (mUserProfileGroupIdsSelfLocked) {
13568                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
13569                            UserInfo.NO_PROFILE_GROUP_ID);
13570                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
13571                            UserInfo.NO_PROFILE_GROUP_ID);
13572                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
13573                            && callingProfile == targetProfile;
13574                }
13575            } else {
13576                throw new IllegalArgumentException("Unknown mode: " + allowMode);
13577            }
13578            if (!allow) {
13579                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13580                    // In this case, they would like to just execute as their
13581                    // owner user instead of failing.
13582                    targetUserId = callingUserId;
13583                } else {
13584                    StringBuilder builder = new StringBuilder(128);
13585                    builder.append("Permission Denial: ");
13586                    builder.append(name);
13587                    if (callerPackage != null) {
13588                        builder.append(" from ");
13589                        builder.append(callerPackage);
13590                    }
13591                    builder.append(" asks to run as user ");
13592                    builder.append(userId);
13593                    builder.append(" but is calling from user ");
13594                    builder.append(UserHandle.getUserId(callingUid));
13595                    builder.append("; this requires ");
13596                    builder.append(INTERACT_ACROSS_USERS_FULL);
13597                    if (allowMode != ALLOW_FULL_ONLY) {
13598                        builder.append(" or ");
13599                        builder.append(INTERACT_ACROSS_USERS);
13600                    }
13601                    String msg = builder.toString();
13602                    Slog.w(TAG, msg);
13603                    throw new SecurityException(msg);
13604                }
13605            }
13606        }
13607        if (!allowAll && targetUserId < 0) {
13608            throw new IllegalArgumentException(
13609                    "Call does not support special user #" + targetUserId);
13610        }
13611        return targetUserId;
13612    }
13613
13614    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13615            String className, int flags) {
13616        boolean result = false;
13617        // For apps that don't have pre-defined UIDs, check for permission
13618        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13619            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13620                if (ActivityManager.checkUidPermission(
13621                        INTERACT_ACROSS_USERS,
13622                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13623                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13624                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13625                            + " requests FLAG_SINGLE_USER, but app does not hold "
13626                            + INTERACT_ACROSS_USERS;
13627                    Slog.w(TAG, msg);
13628                    throw new SecurityException(msg);
13629                }
13630                // Permission passed
13631                result = true;
13632            }
13633        } else if ("system".equals(componentProcessName)) {
13634            result = true;
13635        } else {
13636            // App with pre-defined UID, check if it's a persistent app
13637            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13638        }
13639        if (DEBUG_MU) {
13640            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13641                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13642        }
13643        return result;
13644    }
13645
13646    /**
13647     * Checks to see if the caller is in the same app as the singleton
13648     * component, or the component is in a special app. It allows special apps
13649     * to export singleton components but prevents exporting singleton
13650     * components for regular apps.
13651     */
13652    boolean isValidSingletonCall(int callingUid, int componentUid) {
13653        int componentAppId = UserHandle.getAppId(componentUid);
13654        return UserHandle.isSameApp(callingUid, componentUid)
13655                || componentAppId == Process.SYSTEM_UID
13656                || componentAppId == Process.PHONE_UID
13657                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13658                        == PackageManager.PERMISSION_GRANTED;
13659    }
13660
13661    public int bindService(IApplicationThread caller, IBinder token,
13662            Intent service, String resolvedType,
13663            IServiceConnection connection, int flags, int userId) {
13664        enforceNotIsolatedCaller("bindService");
13665        // Refuse possible leaked file descriptors
13666        if (service != null && service.hasFileDescriptors() == true) {
13667            throw new IllegalArgumentException("File descriptors passed in Intent");
13668        }
13669
13670        synchronized(this) {
13671            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13672                    connection, flags, userId);
13673        }
13674    }
13675
13676    public boolean unbindService(IServiceConnection connection) {
13677        synchronized (this) {
13678            return mServices.unbindServiceLocked(connection);
13679        }
13680    }
13681
13682    public void publishService(IBinder token, Intent intent, IBinder service) {
13683        // Refuse possible leaked file descriptors
13684        if (intent != null && intent.hasFileDescriptors() == true) {
13685            throw new IllegalArgumentException("File descriptors passed in Intent");
13686        }
13687
13688        synchronized(this) {
13689            if (!(token instanceof ServiceRecord)) {
13690                throw new IllegalArgumentException("Invalid service token");
13691            }
13692            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13693        }
13694    }
13695
13696    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13697        // Refuse possible leaked file descriptors
13698        if (intent != null && intent.hasFileDescriptors() == true) {
13699            throw new IllegalArgumentException("File descriptors passed in Intent");
13700        }
13701
13702        synchronized(this) {
13703            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13704        }
13705    }
13706
13707    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13708        synchronized(this) {
13709            if (!(token instanceof ServiceRecord)) {
13710                throw new IllegalArgumentException("Invalid service token");
13711            }
13712            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13713        }
13714    }
13715
13716    // =========================================================
13717    // BACKUP AND RESTORE
13718    // =========================================================
13719
13720    // Cause the target app to be launched if necessary and its backup agent
13721    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13722    // activity manager to announce its creation.
13723    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13724        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13725        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
13726
13727        synchronized(this) {
13728            // !!! TODO: currently no check here that we're already bound
13729            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13730            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13731            synchronized (stats) {
13732                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13733            }
13734
13735            // Backup agent is now in use, its package can't be stopped.
13736            try {
13737                AppGlobals.getPackageManager().setPackageStoppedState(
13738                        app.packageName, false, UserHandle.getUserId(app.uid));
13739            } catch (RemoteException e) {
13740            } catch (IllegalArgumentException e) {
13741                Slog.w(TAG, "Failed trying to unstop package "
13742                        + app.packageName + ": " + e);
13743            }
13744
13745            BackupRecord r = new BackupRecord(ss, app, backupMode);
13746            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13747                    ? new ComponentName(app.packageName, app.backupAgentName)
13748                    : new ComponentName("android", "FullBackupAgent");
13749            // startProcessLocked() returns existing proc's record if it's already running
13750            ProcessRecord proc = startProcessLocked(app.processName, app,
13751                    false, 0, "backup", hostingName, false, false, false);
13752            if (proc == null) {
13753                Slog.e(TAG, "Unable to start backup agent process " + r);
13754                return false;
13755            }
13756
13757            r.app = proc;
13758            mBackupTarget = r;
13759            mBackupAppName = app.packageName;
13760
13761            // Try not to kill the process during backup
13762            updateOomAdjLocked(proc);
13763
13764            // If the process is already attached, schedule the creation of the backup agent now.
13765            // If it is not yet live, this will be done when it attaches to the framework.
13766            if (proc.thread != null) {
13767                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13768                try {
13769                    proc.thread.scheduleCreateBackupAgent(app,
13770                            compatibilityInfoForPackageLocked(app), backupMode);
13771                } catch (RemoteException e) {
13772                    // Will time out on the backup manager side
13773                }
13774            } else {
13775                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13776            }
13777            // Invariants: at this point, the target app process exists and the application
13778            // is either already running or in the process of coming up.  mBackupTarget and
13779            // mBackupAppName describe the app, so that when it binds back to the AM we
13780            // know that it's scheduled for a backup-agent operation.
13781        }
13782
13783        return true;
13784    }
13785
13786    @Override
13787    public void clearPendingBackup() {
13788        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13789        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13790
13791        synchronized (this) {
13792            mBackupTarget = null;
13793            mBackupAppName = null;
13794        }
13795    }
13796
13797    // A backup agent has just come up
13798    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13799        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13800                + " = " + agent);
13801
13802        synchronized(this) {
13803            if (!agentPackageName.equals(mBackupAppName)) {
13804                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13805                return;
13806            }
13807        }
13808
13809        long oldIdent = Binder.clearCallingIdentity();
13810        try {
13811            IBackupManager bm = IBackupManager.Stub.asInterface(
13812                    ServiceManager.getService(Context.BACKUP_SERVICE));
13813            bm.agentConnected(agentPackageName, agent);
13814        } catch (RemoteException e) {
13815            // can't happen; the backup manager service is local
13816        } catch (Exception e) {
13817            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13818            e.printStackTrace();
13819        } finally {
13820            Binder.restoreCallingIdentity(oldIdent);
13821        }
13822    }
13823
13824    // done with this agent
13825    public void unbindBackupAgent(ApplicationInfo appInfo) {
13826        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13827        if (appInfo == null) {
13828            Slog.w(TAG, "unbind backup agent for null app");
13829            return;
13830        }
13831
13832        synchronized(this) {
13833            try {
13834                if (mBackupAppName == null) {
13835                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13836                    return;
13837                }
13838
13839                if (!mBackupAppName.equals(appInfo.packageName)) {
13840                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13841                    return;
13842                }
13843
13844                // Not backing this app up any more; reset its OOM adjustment
13845                final ProcessRecord proc = mBackupTarget.app;
13846                updateOomAdjLocked(proc);
13847
13848                // If the app crashed during backup, 'thread' will be null here
13849                if (proc.thread != null) {
13850                    try {
13851                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13852                                compatibilityInfoForPackageLocked(appInfo));
13853                    } catch (Exception e) {
13854                        Slog.e(TAG, "Exception when unbinding backup agent:");
13855                        e.printStackTrace();
13856                    }
13857                }
13858            } finally {
13859                mBackupTarget = null;
13860                mBackupAppName = null;
13861            }
13862        }
13863    }
13864    // =========================================================
13865    // BROADCASTS
13866    // =========================================================
13867
13868    private final List getStickiesLocked(String action, IntentFilter filter,
13869            List cur, int userId) {
13870        final ContentResolver resolver = mContext.getContentResolver();
13871        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13872        if (stickies == null) {
13873            return cur;
13874        }
13875        final ArrayList<Intent> list = stickies.get(action);
13876        if (list == null) {
13877            return cur;
13878        }
13879        int N = list.size();
13880        for (int i=0; i<N; i++) {
13881            Intent intent = list.get(i);
13882            if (filter.match(resolver, intent, true, TAG) >= 0) {
13883                if (cur == null) {
13884                    cur = new ArrayList<Intent>();
13885                }
13886                cur.add(intent);
13887            }
13888        }
13889        return cur;
13890    }
13891
13892    boolean isPendingBroadcastProcessLocked(int pid) {
13893        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13894                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13895    }
13896
13897    void skipPendingBroadcastLocked(int pid) {
13898            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13899            for (BroadcastQueue queue : mBroadcastQueues) {
13900                queue.skipPendingBroadcastLocked(pid);
13901            }
13902    }
13903
13904    // The app just attached; send any pending broadcasts that it should receive
13905    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13906        boolean didSomething = false;
13907        for (BroadcastQueue queue : mBroadcastQueues) {
13908            didSomething |= queue.sendPendingBroadcastsLocked(app);
13909        }
13910        return didSomething;
13911    }
13912
13913    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13914            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13915        enforceNotIsolatedCaller("registerReceiver");
13916        int callingUid;
13917        int callingPid;
13918        synchronized(this) {
13919            ProcessRecord callerApp = null;
13920            if (caller != null) {
13921                callerApp = getRecordForAppLocked(caller);
13922                if (callerApp == null) {
13923                    throw new SecurityException(
13924                            "Unable to find app for caller " + caller
13925                            + " (pid=" + Binder.getCallingPid()
13926                            + ") when registering receiver " + receiver);
13927                }
13928                if (callerApp.info.uid != Process.SYSTEM_UID &&
13929                        !callerApp.pkgList.containsKey(callerPackage) &&
13930                        !"android".equals(callerPackage)) {
13931                    throw new SecurityException("Given caller package " + callerPackage
13932                            + " is not running in process " + callerApp);
13933                }
13934                callingUid = callerApp.info.uid;
13935                callingPid = callerApp.pid;
13936            } else {
13937                callerPackage = null;
13938                callingUid = Binder.getCallingUid();
13939                callingPid = Binder.getCallingPid();
13940            }
13941
13942            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13943                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
13944
13945            List allSticky = null;
13946
13947            // Look for any matching sticky broadcasts...
13948            Iterator actions = filter.actionsIterator();
13949            if (actions != null) {
13950                while (actions.hasNext()) {
13951                    String action = (String)actions.next();
13952                    allSticky = getStickiesLocked(action, filter, allSticky,
13953                            UserHandle.USER_ALL);
13954                    allSticky = getStickiesLocked(action, filter, allSticky,
13955                            UserHandle.getUserId(callingUid));
13956                }
13957            } else {
13958                allSticky = getStickiesLocked(null, filter, allSticky,
13959                        UserHandle.USER_ALL);
13960                allSticky = getStickiesLocked(null, filter, allSticky,
13961                        UserHandle.getUserId(callingUid));
13962            }
13963
13964            // The first sticky in the list is returned directly back to
13965            // the client.
13966            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13967
13968            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13969                    + ": " + sticky);
13970
13971            if (receiver == null) {
13972                return sticky;
13973            }
13974
13975            ReceiverList rl
13976                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13977            if (rl == null) {
13978                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13979                        userId, receiver);
13980                if (rl.app != null) {
13981                    rl.app.receivers.add(rl);
13982                } else {
13983                    try {
13984                        receiver.asBinder().linkToDeath(rl, 0);
13985                    } catch (RemoteException e) {
13986                        return sticky;
13987                    }
13988                    rl.linkedToDeath = true;
13989                }
13990                mRegisteredReceivers.put(receiver.asBinder(), rl);
13991            } else if (rl.uid != callingUid) {
13992                throw new IllegalArgumentException(
13993                        "Receiver requested to register for uid " + callingUid
13994                        + " was previously registered for uid " + rl.uid);
13995            } else if (rl.pid != callingPid) {
13996                throw new IllegalArgumentException(
13997                        "Receiver requested to register for pid " + callingPid
13998                        + " was previously registered for pid " + rl.pid);
13999            } else if (rl.userId != userId) {
14000                throw new IllegalArgumentException(
14001                        "Receiver requested to register for user " + userId
14002                        + " was previously registered for user " + rl.userId);
14003            }
14004            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14005                    permission, callingUid, userId);
14006            rl.add(bf);
14007            if (!bf.debugCheck()) {
14008                Slog.w(TAG, "==> For Dynamic broadast");
14009            }
14010            mReceiverResolver.addFilter(bf);
14011
14012            // Enqueue broadcasts for all existing stickies that match
14013            // this filter.
14014            if (allSticky != null) {
14015                ArrayList receivers = new ArrayList();
14016                receivers.add(bf);
14017
14018                int N = allSticky.size();
14019                for (int i=0; i<N; i++) {
14020                    Intent intent = (Intent)allSticky.get(i);
14021                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14022                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14023                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14024                            null, null, false, true, true, -1);
14025                    queue.enqueueParallelBroadcastLocked(r);
14026                    queue.scheduleBroadcastsLocked();
14027                }
14028            }
14029
14030            return sticky;
14031        }
14032    }
14033
14034    public void unregisterReceiver(IIntentReceiver receiver) {
14035        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14036
14037        final long origId = Binder.clearCallingIdentity();
14038        try {
14039            boolean doTrim = false;
14040
14041            synchronized(this) {
14042                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14043                if (rl != null) {
14044                    if (rl.curBroadcast != null) {
14045                        BroadcastRecord r = rl.curBroadcast;
14046                        final boolean doNext = finishReceiverLocked(
14047                                receiver.asBinder(), r.resultCode, r.resultData,
14048                                r.resultExtras, r.resultAbort);
14049                        if (doNext) {
14050                            doTrim = true;
14051                            r.queue.processNextBroadcast(false);
14052                        }
14053                    }
14054
14055                    if (rl.app != null) {
14056                        rl.app.receivers.remove(rl);
14057                    }
14058                    removeReceiverLocked(rl);
14059                    if (rl.linkedToDeath) {
14060                        rl.linkedToDeath = false;
14061                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14062                    }
14063                }
14064            }
14065
14066            // If we actually concluded any broadcasts, we might now be able
14067            // to trim the recipients' apps from our working set
14068            if (doTrim) {
14069                trimApplications();
14070                return;
14071            }
14072
14073        } finally {
14074            Binder.restoreCallingIdentity(origId);
14075        }
14076    }
14077
14078    void removeReceiverLocked(ReceiverList rl) {
14079        mRegisteredReceivers.remove(rl.receiver.asBinder());
14080        int N = rl.size();
14081        for (int i=0; i<N; i++) {
14082            mReceiverResolver.removeFilter(rl.get(i));
14083        }
14084    }
14085
14086    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14087        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14088            ProcessRecord r = mLruProcesses.get(i);
14089            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14090                try {
14091                    r.thread.dispatchPackageBroadcast(cmd, packages);
14092                } catch (RemoteException ex) {
14093                }
14094            }
14095        }
14096    }
14097
14098    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14099            int[] users) {
14100        List<ResolveInfo> receivers = null;
14101        try {
14102            HashSet<ComponentName> singleUserReceivers = null;
14103            boolean scannedFirstReceivers = false;
14104            for (int user : users) {
14105                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14106                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14107                if (user != 0 && newReceivers != null) {
14108                    // If this is not the primary user, we need to check for
14109                    // any receivers that should be filtered out.
14110                    for (int i=0; i<newReceivers.size(); i++) {
14111                        ResolveInfo ri = newReceivers.get(i);
14112                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14113                            newReceivers.remove(i);
14114                            i--;
14115                        }
14116                    }
14117                }
14118                if (newReceivers != null && newReceivers.size() == 0) {
14119                    newReceivers = null;
14120                }
14121                if (receivers == null) {
14122                    receivers = newReceivers;
14123                } else if (newReceivers != null) {
14124                    // We need to concatenate the additional receivers
14125                    // found with what we have do far.  This would be easy,
14126                    // but we also need to de-dup any receivers that are
14127                    // singleUser.
14128                    if (!scannedFirstReceivers) {
14129                        // Collect any single user receivers we had already retrieved.
14130                        scannedFirstReceivers = true;
14131                        for (int i=0; i<receivers.size(); i++) {
14132                            ResolveInfo ri = receivers.get(i);
14133                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14134                                ComponentName cn = new ComponentName(
14135                                        ri.activityInfo.packageName, ri.activityInfo.name);
14136                                if (singleUserReceivers == null) {
14137                                    singleUserReceivers = new HashSet<ComponentName>();
14138                                }
14139                                singleUserReceivers.add(cn);
14140                            }
14141                        }
14142                    }
14143                    // Add the new results to the existing results, tracking
14144                    // and de-dupping single user receivers.
14145                    for (int i=0; i<newReceivers.size(); i++) {
14146                        ResolveInfo ri = newReceivers.get(i);
14147                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14148                            ComponentName cn = new ComponentName(
14149                                    ri.activityInfo.packageName, ri.activityInfo.name);
14150                            if (singleUserReceivers == null) {
14151                                singleUserReceivers = new HashSet<ComponentName>();
14152                            }
14153                            if (!singleUserReceivers.contains(cn)) {
14154                                singleUserReceivers.add(cn);
14155                                receivers.add(ri);
14156                            }
14157                        } else {
14158                            receivers.add(ri);
14159                        }
14160                    }
14161                }
14162            }
14163        } catch (RemoteException ex) {
14164            // pm is in same process, this will never happen.
14165        }
14166        return receivers;
14167    }
14168
14169    private final int broadcastIntentLocked(ProcessRecord callerApp,
14170            String callerPackage, Intent intent, String resolvedType,
14171            IIntentReceiver resultTo, int resultCode, String resultData,
14172            Bundle map, String requiredPermission, int appOp,
14173            boolean ordered, boolean sticky, int callingPid, int callingUid,
14174            int userId) {
14175        intent = new Intent(intent);
14176
14177        // By default broadcasts do not go to stopped apps.
14178        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
14179
14180        if (DEBUG_BROADCAST_LIGHT) Slog.v(
14181            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
14182            + " ordered=" + ordered + " userid=" + userId);
14183        if ((resultTo != null) && !ordered) {
14184            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
14185        }
14186
14187        userId = handleIncomingUser(callingPid, callingUid, userId,
14188                true, ALLOW_NON_FULL, "broadcast", callerPackage);
14189
14190        // Make sure that the user who is receiving this broadcast is started.
14191        // If not, we will just skip it.
14192
14193
14194        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
14195            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14196                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14197                Slog.w(TAG, "Skipping broadcast of " + intent
14198                        + ": user " + userId + " is stopped");
14199                return ActivityManager.BROADCAST_SUCCESS;
14200            }
14201        }
14202
14203        /*
14204         * Prevent non-system code (defined here to be non-persistent
14205         * processes) from sending protected broadcasts.
14206         */
14207        int callingAppId = UserHandle.getAppId(callingUid);
14208        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14209            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14210            || callingAppId == Process.NFC_UID || callingUid == 0) {
14211            // Always okay.
14212        } else if (callerApp == null || !callerApp.persistent) {
14213            try {
14214                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14215                        intent.getAction())) {
14216                    String msg = "Permission Denial: not allowed to send broadcast "
14217                            + intent.getAction() + " from pid="
14218                            + callingPid + ", uid=" + callingUid;
14219                    Slog.w(TAG, msg);
14220                    throw new SecurityException(msg);
14221                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14222                    // Special case for compatibility: we don't want apps to send this,
14223                    // but historically it has not been protected and apps may be using it
14224                    // to poke their own app widget.  So, instead of making it protected,
14225                    // just limit it to the caller.
14226                    if (callerApp == null) {
14227                        String msg = "Permission Denial: not allowed to send broadcast "
14228                                + intent.getAction() + " from unknown caller.";
14229                        Slog.w(TAG, msg);
14230                        throw new SecurityException(msg);
14231                    } else if (intent.getComponent() != null) {
14232                        // They are good enough to send to an explicit component...  verify
14233                        // it is being sent to the calling app.
14234                        if (!intent.getComponent().getPackageName().equals(
14235                                callerApp.info.packageName)) {
14236                            String msg = "Permission Denial: not allowed to send broadcast "
14237                                    + intent.getAction() + " to "
14238                                    + intent.getComponent().getPackageName() + " from "
14239                                    + callerApp.info.packageName;
14240                            Slog.w(TAG, msg);
14241                            throw new SecurityException(msg);
14242                        }
14243                    } else {
14244                        // Limit broadcast to their own package.
14245                        intent.setPackage(callerApp.info.packageName);
14246                    }
14247                }
14248            } catch (RemoteException e) {
14249                Slog.w(TAG, "Remote exception", e);
14250                return ActivityManager.BROADCAST_SUCCESS;
14251            }
14252        }
14253
14254        // Handle special intents: if this broadcast is from the package
14255        // manager about a package being removed, we need to remove all of
14256        // its activities from the history stack.
14257        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14258                intent.getAction());
14259        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14260                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14261                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14262                || uidRemoved) {
14263            if (checkComponentPermission(
14264                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14265                    callingPid, callingUid, -1, true)
14266                    == PackageManager.PERMISSION_GRANTED) {
14267                if (uidRemoved) {
14268                    final Bundle intentExtras = intent.getExtras();
14269                    final int uid = intentExtras != null
14270                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14271                    if (uid >= 0) {
14272                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14273                        synchronized (bs) {
14274                            bs.removeUidStatsLocked(uid);
14275                        }
14276                        mAppOpsService.uidRemoved(uid);
14277                    }
14278                } else {
14279                    // If resources are unavailable just force stop all
14280                    // those packages and flush the attribute cache as well.
14281                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14282                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14283                        if (list != null && (list.length > 0)) {
14284                            for (String pkg : list) {
14285                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14286                                        "storage unmount");
14287                            }
14288                            sendPackageBroadcastLocked(
14289                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14290                        }
14291                    } else {
14292                        Uri data = intent.getData();
14293                        String ssp;
14294                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14295                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14296                                    intent.getAction());
14297                            boolean fullUninstall = removed &&
14298                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14299                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14300                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14301                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14302                                        false, fullUninstall, userId,
14303                                        removed ? "pkg removed" : "pkg changed");
14304                            }
14305                            if (removed) {
14306                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14307                                        new String[] {ssp}, userId);
14308                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14309                                    mAppOpsService.packageRemoved(
14310                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14311
14312                                    // Remove all permissions granted from/to this package
14313                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14314                                }
14315                            }
14316                        }
14317                    }
14318                }
14319            } else {
14320                String msg = "Permission Denial: " + intent.getAction()
14321                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14322                        + ", uid=" + callingUid + ")"
14323                        + " requires "
14324                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14325                Slog.w(TAG, msg);
14326                throw new SecurityException(msg);
14327            }
14328
14329        // Special case for adding a package: by default turn on compatibility
14330        // mode.
14331        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14332            Uri data = intent.getData();
14333            String ssp;
14334            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14335                mCompatModePackages.handlePackageAddedLocked(ssp,
14336                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14337            }
14338        }
14339
14340        /*
14341         * If this is the time zone changed action, queue up a message that will reset the timezone
14342         * of all currently running processes. This message will get queued up before the broadcast
14343         * happens.
14344         */
14345        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14346            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14347        }
14348
14349        /*
14350         * If the user set the time, let all running processes know.
14351         */
14352        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14353            final int is24Hour = intent.getBooleanExtra(
14354                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14355            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14356        }
14357
14358        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14359            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14360        }
14361
14362        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14363            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14364            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14365        }
14366
14367        // Add to the sticky list if requested.
14368        if (sticky) {
14369            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14370                    callingPid, callingUid)
14371                    != PackageManager.PERMISSION_GRANTED) {
14372                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14373                        + callingPid + ", uid=" + callingUid
14374                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14375                Slog.w(TAG, msg);
14376                throw new SecurityException(msg);
14377            }
14378            if (requiredPermission != null) {
14379                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14380                        + " and enforce permission " + requiredPermission);
14381                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14382            }
14383            if (intent.getComponent() != null) {
14384                throw new SecurityException(
14385                        "Sticky broadcasts can't target a specific component");
14386            }
14387            // We use userId directly here, since the "all" target is maintained
14388            // as a separate set of sticky broadcasts.
14389            if (userId != UserHandle.USER_ALL) {
14390                // But first, if this is not a broadcast to all users, then
14391                // make sure it doesn't conflict with an existing broadcast to
14392                // all users.
14393                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14394                        UserHandle.USER_ALL);
14395                if (stickies != null) {
14396                    ArrayList<Intent> list = stickies.get(intent.getAction());
14397                    if (list != null) {
14398                        int N = list.size();
14399                        int i;
14400                        for (i=0; i<N; i++) {
14401                            if (intent.filterEquals(list.get(i))) {
14402                                throw new IllegalArgumentException(
14403                                        "Sticky broadcast " + intent + " for user "
14404                                        + userId + " conflicts with existing global broadcast");
14405                            }
14406                        }
14407                    }
14408                }
14409            }
14410            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14411            if (stickies == null) {
14412                stickies = new ArrayMap<String, ArrayList<Intent>>();
14413                mStickyBroadcasts.put(userId, stickies);
14414            }
14415            ArrayList<Intent> list = stickies.get(intent.getAction());
14416            if (list == null) {
14417                list = new ArrayList<Intent>();
14418                stickies.put(intent.getAction(), list);
14419            }
14420            int N = list.size();
14421            int i;
14422            for (i=0; i<N; i++) {
14423                if (intent.filterEquals(list.get(i))) {
14424                    // This sticky already exists, replace it.
14425                    list.set(i, new Intent(intent));
14426                    break;
14427                }
14428            }
14429            if (i >= N) {
14430                list.add(new Intent(intent));
14431            }
14432        }
14433
14434        int[] users;
14435        if (userId == UserHandle.USER_ALL) {
14436            // Caller wants broadcast to go to all started users.
14437            users = mStartedUserArray;
14438        } else {
14439            // Caller wants broadcast to go to one specific user.
14440            users = new int[] {userId};
14441        }
14442
14443        // Figure out who all will receive this broadcast.
14444        List receivers = null;
14445        List<BroadcastFilter> registeredReceivers = null;
14446        // Need to resolve the intent to interested receivers...
14447        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14448                 == 0) {
14449            receivers = collectReceiverComponents(intent, resolvedType, users);
14450        }
14451        if (intent.getComponent() == null) {
14452            registeredReceivers = mReceiverResolver.queryIntent(intent,
14453                    resolvedType, false, userId);
14454        }
14455
14456        final boolean replacePending =
14457                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14458
14459        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14460                + " replacePending=" + replacePending);
14461
14462        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14463        if (!ordered && NR > 0) {
14464            // If we are not serializing this broadcast, then send the
14465            // registered receivers separately so they don't wait for the
14466            // components to be launched.
14467            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14468            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14469                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14470                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14471                    ordered, sticky, false, userId);
14472            if (DEBUG_BROADCAST) Slog.v(
14473                    TAG, "Enqueueing parallel broadcast " + r);
14474            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14475            if (!replaced) {
14476                queue.enqueueParallelBroadcastLocked(r);
14477                queue.scheduleBroadcastsLocked();
14478            }
14479            registeredReceivers = null;
14480            NR = 0;
14481        }
14482
14483        // Merge into one list.
14484        int ir = 0;
14485        if (receivers != null) {
14486            // A special case for PACKAGE_ADDED: do not allow the package
14487            // being added to see this broadcast.  This prevents them from
14488            // using this as a back door to get run as soon as they are
14489            // installed.  Maybe in the future we want to have a special install
14490            // broadcast or such for apps, but we'd like to deliberately make
14491            // this decision.
14492            String skipPackages[] = null;
14493            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14494                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14495                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14496                Uri data = intent.getData();
14497                if (data != null) {
14498                    String pkgName = data.getSchemeSpecificPart();
14499                    if (pkgName != null) {
14500                        skipPackages = new String[] { pkgName };
14501                    }
14502                }
14503            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14504                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14505            }
14506            if (skipPackages != null && (skipPackages.length > 0)) {
14507                for (String skipPackage : skipPackages) {
14508                    if (skipPackage != null) {
14509                        int NT = receivers.size();
14510                        for (int it=0; it<NT; it++) {
14511                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14512                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14513                                receivers.remove(it);
14514                                it--;
14515                                NT--;
14516                            }
14517                        }
14518                    }
14519                }
14520            }
14521
14522            int NT = receivers != null ? receivers.size() : 0;
14523            int it = 0;
14524            ResolveInfo curt = null;
14525            BroadcastFilter curr = null;
14526            while (it < NT && ir < NR) {
14527                if (curt == null) {
14528                    curt = (ResolveInfo)receivers.get(it);
14529                }
14530                if (curr == null) {
14531                    curr = registeredReceivers.get(ir);
14532                }
14533                if (curr.getPriority() >= curt.priority) {
14534                    // Insert this broadcast record into the final list.
14535                    receivers.add(it, curr);
14536                    ir++;
14537                    curr = null;
14538                    it++;
14539                    NT++;
14540                } else {
14541                    // Skip to the next ResolveInfo in the final list.
14542                    it++;
14543                    curt = null;
14544                }
14545            }
14546        }
14547        while (ir < NR) {
14548            if (receivers == null) {
14549                receivers = new ArrayList();
14550            }
14551            receivers.add(registeredReceivers.get(ir));
14552            ir++;
14553        }
14554
14555        if ((receivers != null && receivers.size() > 0)
14556                || resultTo != null) {
14557            BroadcastQueue queue = broadcastQueueForIntent(intent);
14558            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14559                    callerPackage, callingPid, callingUid, resolvedType,
14560                    requiredPermission, appOp, receivers, resultTo, resultCode,
14561                    resultData, map, ordered, sticky, false, userId);
14562            if (DEBUG_BROADCAST) Slog.v(
14563                    TAG, "Enqueueing ordered broadcast " + r
14564                    + ": prev had " + queue.mOrderedBroadcasts.size());
14565            if (DEBUG_BROADCAST) {
14566                int seq = r.intent.getIntExtra("seq", -1);
14567                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14568            }
14569            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14570            if (!replaced) {
14571                queue.enqueueOrderedBroadcastLocked(r);
14572                queue.scheduleBroadcastsLocked();
14573            }
14574        }
14575
14576        return ActivityManager.BROADCAST_SUCCESS;
14577    }
14578
14579    final Intent verifyBroadcastLocked(Intent intent) {
14580        // Refuse possible leaked file descriptors
14581        if (intent != null && intent.hasFileDescriptors() == true) {
14582            throw new IllegalArgumentException("File descriptors passed in Intent");
14583        }
14584
14585        int flags = intent.getFlags();
14586
14587        if (!mProcessesReady) {
14588            // if the caller really truly claims to know what they're doing, go
14589            // ahead and allow the broadcast without launching any receivers
14590            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14591                intent = new Intent(intent);
14592                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14593            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14594                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14595                        + " before boot completion");
14596                throw new IllegalStateException("Cannot broadcast before boot completed");
14597            }
14598        }
14599
14600        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14601            throw new IllegalArgumentException(
14602                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14603        }
14604
14605        return intent;
14606    }
14607
14608    public final int broadcastIntent(IApplicationThread caller,
14609            Intent intent, String resolvedType, IIntentReceiver resultTo,
14610            int resultCode, String resultData, Bundle map,
14611            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14612        enforceNotIsolatedCaller("broadcastIntent");
14613        synchronized(this) {
14614            intent = verifyBroadcastLocked(intent);
14615
14616            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14617            final int callingPid = Binder.getCallingPid();
14618            final int callingUid = Binder.getCallingUid();
14619            final long origId = Binder.clearCallingIdentity();
14620            int res = broadcastIntentLocked(callerApp,
14621                    callerApp != null ? callerApp.info.packageName : null,
14622                    intent, resolvedType, resultTo,
14623                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14624                    callingPid, callingUid, userId);
14625            Binder.restoreCallingIdentity(origId);
14626            return res;
14627        }
14628    }
14629
14630    int broadcastIntentInPackage(String packageName, int uid,
14631            Intent intent, String resolvedType, IIntentReceiver resultTo,
14632            int resultCode, String resultData, Bundle map,
14633            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14634        synchronized(this) {
14635            intent = verifyBroadcastLocked(intent);
14636
14637            final long origId = Binder.clearCallingIdentity();
14638            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14639                    resultTo, resultCode, resultData, map, requiredPermission,
14640                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14641            Binder.restoreCallingIdentity(origId);
14642            return res;
14643        }
14644    }
14645
14646    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14647        // Refuse possible leaked file descriptors
14648        if (intent != null && intent.hasFileDescriptors() == true) {
14649            throw new IllegalArgumentException("File descriptors passed in Intent");
14650        }
14651
14652        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14653                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
14654
14655        synchronized(this) {
14656            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14657                    != PackageManager.PERMISSION_GRANTED) {
14658                String msg = "Permission Denial: unbroadcastIntent() from pid="
14659                        + Binder.getCallingPid()
14660                        + ", uid=" + Binder.getCallingUid()
14661                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14662                Slog.w(TAG, msg);
14663                throw new SecurityException(msg);
14664            }
14665            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14666            if (stickies != null) {
14667                ArrayList<Intent> list = stickies.get(intent.getAction());
14668                if (list != null) {
14669                    int N = list.size();
14670                    int i;
14671                    for (i=0; i<N; i++) {
14672                        if (intent.filterEquals(list.get(i))) {
14673                            list.remove(i);
14674                            break;
14675                        }
14676                    }
14677                    if (list.size() <= 0) {
14678                        stickies.remove(intent.getAction());
14679                    }
14680                }
14681                if (stickies.size() <= 0) {
14682                    mStickyBroadcasts.remove(userId);
14683                }
14684            }
14685        }
14686    }
14687
14688    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14689            String resultData, Bundle resultExtras, boolean resultAbort) {
14690        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14691        if (r == null) {
14692            Slog.w(TAG, "finishReceiver called but not found on queue");
14693            return false;
14694        }
14695
14696        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14697    }
14698
14699    void backgroundServicesFinishedLocked(int userId) {
14700        for (BroadcastQueue queue : mBroadcastQueues) {
14701            queue.backgroundServicesFinishedLocked(userId);
14702        }
14703    }
14704
14705    public void finishReceiver(IBinder who, int resultCode, String resultData,
14706            Bundle resultExtras, boolean resultAbort) {
14707        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14708
14709        // Refuse possible leaked file descriptors
14710        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14711            throw new IllegalArgumentException("File descriptors passed in Bundle");
14712        }
14713
14714        final long origId = Binder.clearCallingIdentity();
14715        try {
14716            boolean doNext = false;
14717            BroadcastRecord r;
14718
14719            synchronized(this) {
14720                r = broadcastRecordForReceiverLocked(who);
14721                if (r != null) {
14722                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14723                        resultData, resultExtras, resultAbort, true);
14724                }
14725            }
14726
14727            if (doNext) {
14728                r.queue.processNextBroadcast(false);
14729            }
14730            trimApplications();
14731        } finally {
14732            Binder.restoreCallingIdentity(origId);
14733        }
14734    }
14735
14736    // =========================================================
14737    // INSTRUMENTATION
14738    // =========================================================
14739
14740    public boolean startInstrumentation(ComponentName className,
14741            String profileFile, int flags, Bundle arguments,
14742            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14743            int userId, String abiOverride) {
14744        enforceNotIsolatedCaller("startInstrumentation");
14745        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14746                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
14747        // Refuse possible leaked file descriptors
14748        if (arguments != null && arguments.hasFileDescriptors()) {
14749            throw new IllegalArgumentException("File descriptors passed in Bundle");
14750        }
14751
14752        synchronized(this) {
14753            InstrumentationInfo ii = null;
14754            ApplicationInfo ai = null;
14755            try {
14756                ii = mContext.getPackageManager().getInstrumentationInfo(
14757                    className, STOCK_PM_FLAGS);
14758                ai = AppGlobals.getPackageManager().getApplicationInfo(
14759                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14760            } catch (PackageManager.NameNotFoundException e) {
14761            } catch (RemoteException e) {
14762            }
14763            if (ii == null) {
14764                reportStartInstrumentationFailure(watcher, className,
14765                        "Unable to find instrumentation info for: " + className);
14766                return false;
14767            }
14768            if (ai == null) {
14769                reportStartInstrumentationFailure(watcher, className,
14770                        "Unable to find instrumentation target package: " + ii.targetPackage);
14771                return false;
14772            }
14773
14774            int match = mContext.getPackageManager().checkSignatures(
14775                    ii.targetPackage, ii.packageName);
14776            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14777                String msg = "Permission Denial: starting instrumentation "
14778                        + className + " from pid="
14779                        + Binder.getCallingPid()
14780                        + ", uid=" + Binder.getCallingPid()
14781                        + " not allowed because package " + ii.packageName
14782                        + " does not have a signature matching the target "
14783                        + ii.targetPackage;
14784                reportStartInstrumentationFailure(watcher, className, msg);
14785                throw new SecurityException(msg);
14786            }
14787
14788            final long origId = Binder.clearCallingIdentity();
14789            // Instrumentation can kill and relaunch even persistent processes
14790            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14791                    "start instr");
14792            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14793            app.instrumentationClass = className;
14794            app.instrumentationInfo = ai;
14795            app.instrumentationProfileFile = profileFile;
14796            app.instrumentationArguments = arguments;
14797            app.instrumentationWatcher = watcher;
14798            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14799            app.instrumentationResultClass = className;
14800            Binder.restoreCallingIdentity(origId);
14801        }
14802
14803        return true;
14804    }
14805
14806    /**
14807     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14808     * error to the logs, but if somebody is watching, send the report there too.  This enables
14809     * the "am" command to report errors with more information.
14810     *
14811     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14812     * @param cn The component name of the instrumentation.
14813     * @param report The error report.
14814     */
14815    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14816            ComponentName cn, String report) {
14817        Slog.w(TAG, report);
14818        try {
14819            if (watcher != null) {
14820                Bundle results = new Bundle();
14821                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14822                results.putString("Error", report);
14823                watcher.instrumentationStatus(cn, -1, results);
14824            }
14825        } catch (RemoteException e) {
14826            Slog.w(TAG, e);
14827        }
14828    }
14829
14830    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14831        if (app.instrumentationWatcher != null) {
14832            try {
14833                // NOTE:  IInstrumentationWatcher *must* be oneway here
14834                app.instrumentationWatcher.instrumentationFinished(
14835                    app.instrumentationClass,
14836                    resultCode,
14837                    results);
14838            } catch (RemoteException e) {
14839            }
14840        }
14841        if (app.instrumentationUiAutomationConnection != null) {
14842            try {
14843                app.instrumentationUiAutomationConnection.shutdown();
14844            } catch (RemoteException re) {
14845                /* ignore */
14846            }
14847            // Only a UiAutomation can set this flag and now that
14848            // it is finished we make sure it is reset to its default.
14849            mUserIsMonkey = false;
14850        }
14851        app.instrumentationWatcher = null;
14852        app.instrumentationUiAutomationConnection = null;
14853        app.instrumentationClass = null;
14854        app.instrumentationInfo = null;
14855        app.instrumentationProfileFile = null;
14856        app.instrumentationArguments = null;
14857
14858        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14859                "finished inst");
14860    }
14861
14862    public void finishInstrumentation(IApplicationThread target,
14863            int resultCode, Bundle results) {
14864        int userId = UserHandle.getCallingUserId();
14865        // Refuse possible leaked file descriptors
14866        if (results != null && results.hasFileDescriptors()) {
14867            throw new IllegalArgumentException("File descriptors passed in Intent");
14868        }
14869
14870        synchronized(this) {
14871            ProcessRecord app = getRecordForAppLocked(target);
14872            if (app == null) {
14873                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14874                return;
14875            }
14876            final long origId = Binder.clearCallingIdentity();
14877            finishInstrumentationLocked(app, resultCode, results);
14878            Binder.restoreCallingIdentity(origId);
14879        }
14880    }
14881
14882    // =========================================================
14883    // CONFIGURATION
14884    // =========================================================
14885
14886    public ConfigurationInfo getDeviceConfigurationInfo() {
14887        ConfigurationInfo config = new ConfigurationInfo();
14888        synchronized (this) {
14889            config.reqTouchScreen = mConfiguration.touchscreen;
14890            config.reqKeyboardType = mConfiguration.keyboard;
14891            config.reqNavigation = mConfiguration.navigation;
14892            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14893                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14894                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14895            }
14896            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14897                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14898                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14899            }
14900            config.reqGlEsVersion = GL_ES_VERSION;
14901        }
14902        return config;
14903    }
14904
14905    ActivityStack getFocusedStack() {
14906        return mStackSupervisor.getFocusedStack();
14907    }
14908
14909    public Configuration getConfiguration() {
14910        Configuration ci;
14911        synchronized(this) {
14912            ci = new Configuration(mConfiguration);
14913        }
14914        return ci;
14915    }
14916
14917    public void updatePersistentConfiguration(Configuration values) {
14918        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14919                "updateConfiguration()");
14920        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14921                "updateConfiguration()");
14922        if (values == null) {
14923            throw new NullPointerException("Configuration must not be null");
14924        }
14925
14926        synchronized(this) {
14927            final long origId = Binder.clearCallingIdentity();
14928            updateConfigurationLocked(values, null, true, false);
14929            Binder.restoreCallingIdentity(origId);
14930        }
14931    }
14932
14933    public void updateConfiguration(Configuration values) {
14934        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14935                "updateConfiguration()");
14936
14937        synchronized(this) {
14938            if (values == null && mWindowManager != null) {
14939                // sentinel: fetch the current configuration from the window manager
14940                values = mWindowManager.computeNewConfiguration();
14941            }
14942
14943            if (mWindowManager != null) {
14944                mProcessList.applyDisplaySize(mWindowManager);
14945            }
14946
14947            final long origId = Binder.clearCallingIdentity();
14948            if (values != null) {
14949                Settings.System.clearConfiguration(values);
14950            }
14951            updateConfigurationLocked(values, null, false, false);
14952            Binder.restoreCallingIdentity(origId);
14953        }
14954    }
14955
14956    /**
14957     * Do either or both things: (1) change the current configuration, and (2)
14958     * make sure the given activity is running with the (now) current
14959     * configuration.  Returns true if the activity has been left running, or
14960     * false if <var>starting</var> is being destroyed to match the new
14961     * configuration.
14962     * @param persistent TODO
14963     */
14964    boolean updateConfigurationLocked(Configuration values,
14965            ActivityRecord starting, boolean persistent, boolean initLocale) {
14966        int changes = 0;
14967
14968        if (values != null) {
14969            Configuration newConfig = new Configuration(mConfiguration);
14970            changes = newConfig.updateFrom(values);
14971            if (changes != 0) {
14972                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14973                    Slog.i(TAG, "Updating configuration to: " + values);
14974                }
14975
14976                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14977
14978                if (values.locale != null && !initLocale) {
14979                    saveLocaleLocked(values.locale,
14980                                     !values.locale.equals(mConfiguration.locale),
14981                                     values.userSetLocale);
14982                }
14983
14984                mConfigurationSeq++;
14985                if (mConfigurationSeq <= 0) {
14986                    mConfigurationSeq = 1;
14987                }
14988                newConfig.seq = mConfigurationSeq;
14989                mConfiguration = newConfig;
14990                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14991                mUsageStatsService.noteStartConfig(newConfig);
14992
14993                final Configuration configCopy = new Configuration(mConfiguration);
14994
14995                // TODO: If our config changes, should we auto dismiss any currently
14996                // showing dialogs?
14997                mShowDialogs = shouldShowDialogs(newConfig);
14998
14999                AttributeCache ac = AttributeCache.instance();
15000                if (ac != null) {
15001                    ac.updateConfiguration(configCopy);
15002                }
15003
15004                // Make sure all resources in our process are updated
15005                // right now, so that anyone who is going to retrieve
15006                // resource values after we return will be sure to get
15007                // the new ones.  This is especially important during
15008                // boot, where the first config change needs to guarantee
15009                // all resources have that config before following boot
15010                // code is executed.
15011                mSystemThread.applyConfigurationToResources(configCopy);
15012
15013                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15014                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15015                    msg.obj = new Configuration(configCopy);
15016                    mHandler.sendMessage(msg);
15017                }
15018
15019                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15020                    ProcessRecord app = mLruProcesses.get(i);
15021                    try {
15022                        if (app.thread != null) {
15023                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15024                                    + app.processName + " new config " + mConfiguration);
15025                            app.thread.scheduleConfigurationChanged(configCopy);
15026                        }
15027                    } catch (Exception e) {
15028                    }
15029                }
15030                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15031                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15032                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15033                        | Intent.FLAG_RECEIVER_FOREGROUND);
15034                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15035                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15036                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15037                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15038                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15039                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15040                    broadcastIntentLocked(null, null, intent,
15041                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15042                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15043                }
15044            }
15045        }
15046
15047        boolean kept = true;
15048        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15049        // mainStack is null during startup.
15050        if (mainStack != null) {
15051            if (changes != 0 && starting == null) {
15052                // If the configuration changed, and the caller is not already
15053                // in the process of starting an activity, then find the top
15054                // activity to check if its configuration needs to change.
15055                starting = mainStack.topRunningActivityLocked(null);
15056            }
15057
15058            if (starting != null) {
15059                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15060                // And we need to make sure at this point that all other activities
15061                // are made visible with the correct configuration.
15062                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15063            }
15064        }
15065
15066        if (values != null && mWindowManager != null) {
15067            mWindowManager.setNewConfiguration(mConfiguration);
15068        }
15069
15070        return kept;
15071    }
15072
15073    /**
15074     * Decide based on the configuration whether we should shouw the ANR,
15075     * crash, etc dialogs.  The idea is that if there is no affordnace to
15076     * press the on-screen buttons, we shouldn't show the dialog.
15077     *
15078     * A thought: SystemUI might also want to get told about this, the Power
15079     * dialog / global actions also might want different behaviors.
15080     */
15081    private static final boolean shouldShowDialogs(Configuration config) {
15082        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15083                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15084    }
15085
15086    /**
15087     * Save the locale.  You must be inside a synchronized (this) block.
15088     */
15089    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15090        if(isDiff) {
15091            SystemProperties.set("user.language", l.getLanguage());
15092            SystemProperties.set("user.region", l.getCountry());
15093        }
15094
15095        if(isPersist) {
15096            SystemProperties.set("persist.sys.language", l.getLanguage());
15097            SystemProperties.set("persist.sys.country", l.getCountry());
15098            SystemProperties.set("persist.sys.localevar", l.getVariant());
15099        }
15100    }
15101
15102    @Override
15103    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
15104        ActivityRecord srec = ActivityRecord.forToken(token);
15105        return srec != null && srec.task.affinity != null &&
15106                srec.task.affinity.equals(destAffinity);
15107    }
15108
15109    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15110            Intent resultData) {
15111
15112        synchronized (this) {
15113            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15114            if (stack != null) {
15115                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15116            }
15117            return false;
15118        }
15119    }
15120
15121    public int getLaunchedFromUid(IBinder activityToken) {
15122        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15123        if (srec == null) {
15124            return -1;
15125        }
15126        return srec.launchedFromUid;
15127    }
15128
15129    public String getLaunchedFromPackage(IBinder activityToken) {
15130        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15131        if (srec == null) {
15132            return null;
15133        }
15134        return srec.launchedFromPackage;
15135    }
15136
15137    // =========================================================
15138    // LIFETIME MANAGEMENT
15139    // =========================================================
15140
15141    // Returns which broadcast queue the app is the current [or imminent] receiver
15142    // on, or 'null' if the app is not an active broadcast recipient.
15143    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
15144        BroadcastRecord r = app.curReceiver;
15145        if (r != null) {
15146            return r.queue;
15147        }
15148
15149        // It's not the current receiver, but it might be starting up to become one
15150        synchronized (this) {
15151            for (BroadcastQueue queue : mBroadcastQueues) {
15152                r = queue.mPendingBroadcast;
15153                if (r != null && r.curApp == app) {
15154                    // found it; report which queue it's in
15155                    return queue;
15156                }
15157            }
15158        }
15159
15160        return null;
15161    }
15162
15163    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
15164            boolean doingAll, long now) {
15165        if (mAdjSeq == app.adjSeq) {
15166            // This adjustment has already been computed.
15167            return app.curRawAdj;
15168        }
15169
15170        if (app.thread == null) {
15171            app.adjSeq = mAdjSeq;
15172            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15173            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15174            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
15175        }
15176
15177        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
15178        app.adjSource = null;
15179        app.adjTarget = null;
15180        app.empty = false;
15181        app.cached = false;
15182
15183        final int activitiesSize = app.activities.size();
15184
15185        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15186            // The max adjustment doesn't allow this app to be anything
15187            // below foreground, so it is not worth doing work for it.
15188            app.adjType = "fixed";
15189            app.adjSeq = mAdjSeq;
15190            app.curRawAdj = app.maxAdj;
15191            app.foregroundActivities = false;
15192            app.keeping = true;
15193            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
15194            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
15195            // System processes can do UI, and when they do we want to have
15196            // them trim their memory after the user leaves the UI.  To
15197            // facilitate this, here we need to determine whether or not it
15198            // is currently showing UI.
15199            app.systemNoUi = true;
15200            if (app == TOP_APP) {
15201                app.systemNoUi = false;
15202            } else if (activitiesSize > 0) {
15203                for (int j = 0; j < activitiesSize; j++) {
15204                    final ActivityRecord r = app.activities.get(j);
15205                    if (r.visible) {
15206                        app.systemNoUi = false;
15207                    }
15208                }
15209            }
15210            if (!app.systemNoUi) {
15211                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15212            }
15213            return (app.curAdj=app.maxAdj);
15214        }
15215
15216        app.keeping = false;
15217        app.systemNoUi = false;
15218
15219        // Determine the importance of the process, starting with most
15220        // important to least, and assign an appropriate OOM adjustment.
15221        int adj;
15222        int schedGroup;
15223        int procState;
15224        boolean foregroundActivities = false;
15225        BroadcastQueue queue;
15226        if (app == TOP_APP) {
15227            // The last app on the list is the foreground app.
15228            adj = ProcessList.FOREGROUND_APP_ADJ;
15229            schedGroup = Process.THREAD_GROUP_DEFAULT;
15230            app.adjType = "top-activity";
15231            foregroundActivities = true;
15232            procState = ActivityManager.PROCESS_STATE_TOP;
15233        } else if (app.instrumentationClass != null) {
15234            // Don't want to kill running instrumentation.
15235            adj = ProcessList.FOREGROUND_APP_ADJ;
15236            schedGroup = Process.THREAD_GROUP_DEFAULT;
15237            app.adjType = "instrumentation";
15238            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15239        } else if ((queue = isReceivingBroadcast(app)) != null) {
15240            // An app that is currently receiving a broadcast also
15241            // counts as being in the foreground for OOM killer purposes.
15242            // It's placed in a sched group based on the nature of the
15243            // broadcast as reflected by which queue it's active in.
15244            adj = ProcessList.FOREGROUND_APP_ADJ;
15245            schedGroup = (queue == mFgBroadcastQueue)
15246                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15247            app.adjType = "broadcast";
15248            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15249        } else if (app.executingServices.size() > 0) {
15250            // An app that is currently executing a service callback also
15251            // counts as being in the foreground.
15252            adj = ProcessList.FOREGROUND_APP_ADJ;
15253            schedGroup = app.execServicesFg ?
15254                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15255            app.adjType = "exec-service";
15256            procState = ActivityManager.PROCESS_STATE_SERVICE;
15257            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15258        } else {
15259            // As far as we know the process is empty.  We may change our mind later.
15260            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15261            // At this point we don't actually know the adjustment.  Use the cached adj
15262            // value that the caller wants us to.
15263            adj = cachedAdj;
15264            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15265            app.cached = true;
15266            app.empty = true;
15267            app.adjType = "cch-empty";
15268        }
15269
15270        // Examine all activities if not already foreground.
15271        if (!foregroundActivities && activitiesSize > 0) {
15272            for (int j = 0; j < activitiesSize; j++) {
15273                final ActivityRecord r = app.activities.get(j);
15274                if (r.app != app) {
15275                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15276                            + app + "?!?");
15277                    continue;
15278                }
15279                if (r.visible) {
15280                    // App has a visible activity; only upgrade adjustment.
15281                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15282                        adj = ProcessList.VISIBLE_APP_ADJ;
15283                        app.adjType = "visible";
15284                    }
15285                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15286                        procState = ActivityManager.PROCESS_STATE_TOP;
15287                    }
15288                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15289                    app.cached = false;
15290                    app.empty = false;
15291                    foregroundActivities = true;
15292                    break;
15293                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15294                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15295                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15296                        app.adjType = "pausing";
15297                    }
15298                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15299                        procState = ActivityManager.PROCESS_STATE_TOP;
15300                    }
15301                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15302                    app.cached = false;
15303                    app.empty = false;
15304                    foregroundActivities = true;
15305                } else if (r.state == ActivityState.STOPPING) {
15306                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15307                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15308                        app.adjType = "stopping";
15309                    }
15310                    // For the process state, we will at this point consider the
15311                    // process to be cached.  It will be cached either as an activity
15312                    // or empty depending on whether the activity is finishing.  We do
15313                    // this so that we can treat the process as cached for purposes of
15314                    // memory trimming (determing current memory level, trim command to
15315                    // send to process) since there can be an arbitrary number of stopping
15316                    // processes and they should soon all go into the cached state.
15317                    if (!r.finishing) {
15318                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15319                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15320                        }
15321                    }
15322                    app.cached = false;
15323                    app.empty = false;
15324                    foregroundActivities = true;
15325                } else {
15326                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15327                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15328                        app.adjType = "cch-act";
15329                    }
15330                }
15331            }
15332        }
15333
15334        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15335            if (app.foregroundServices) {
15336                // The user is aware of this app, so make it visible.
15337                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15338                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15339                app.cached = false;
15340                app.adjType = "fg-service";
15341                schedGroup = Process.THREAD_GROUP_DEFAULT;
15342            } else if (app.forcingToForeground != null) {
15343                // The user is aware of this app, so make it visible.
15344                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15345                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15346                app.cached = false;
15347                app.adjType = "force-fg";
15348                app.adjSource = app.forcingToForeground;
15349                schedGroup = Process.THREAD_GROUP_DEFAULT;
15350            }
15351        }
15352
15353        if (app == mHeavyWeightProcess) {
15354            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15355                // We don't want to kill the current heavy-weight process.
15356                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15357                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15358                app.cached = false;
15359                app.adjType = "heavy";
15360            }
15361            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15362                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15363            }
15364        }
15365
15366        if (app == mHomeProcess) {
15367            if (adj > ProcessList.HOME_APP_ADJ) {
15368                // This process is hosting what we currently consider to be the
15369                // home app, so we don't want to let it go into the background.
15370                adj = ProcessList.HOME_APP_ADJ;
15371                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15372                app.cached = false;
15373                app.adjType = "home";
15374            }
15375            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15376                procState = ActivityManager.PROCESS_STATE_HOME;
15377            }
15378        }
15379
15380        if (app == mPreviousProcess && app.activities.size() > 0) {
15381            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15382                // This was the previous process that showed UI to the user.
15383                // We want to try to keep it around more aggressively, to give
15384                // a good experience around switching between two apps.
15385                adj = ProcessList.PREVIOUS_APP_ADJ;
15386                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15387                app.cached = false;
15388                app.adjType = "previous";
15389            }
15390            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15391                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15392            }
15393        }
15394
15395        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15396                + " reason=" + app.adjType);
15397
15398        // By default, we use the computed adjustment.  It may be changed if
15399        // there are applications dependent on our services or providers, but
15400        // this gives us a baseline and makes sure we don't get into an
15401        // infinite recursion.
15402        app.adjSeq = mAdjSeq;
15403        app.curRawAdj = adj;
15404        app.hasStartedServices = false;
15405
15406        if (mBackupTarget != null && app == mBackupTarget.app) {
15407            // If possible we want to avoid killing apps while they're being backed up
15408            if (adj > ProcessList.BACKUP_APP_ADJ) {
15409                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15410                adj = ProcessList.BACKUP_APP_ADJ;
15411                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15412                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15413                }
15414                app.adjType = "backup";
15415                app.cached = false;
15416            }
15417            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15418                procState = ActivityManager.PROCESS_STATE_BACKUP;
15419            }
15420        }
15421
15422        boolean mayBeTop = false;
15423
15424        for (int is = app.services.size()-1;
15425                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15426                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15427                        || procState > ActivityManager.PROCESS_STATE_TOP);
15428                is--) {
15429            ServiceRecord s = app.services.valueAt(is);
15430            if (s.startRequested) {
15431                app.hasStartedServices = true;
15432                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15433                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15434                }
15435                if (app.hasShownUi && app != mHomeProcess) {
15436                    // If this process has shown some UI, let it immediately
15437                    // go to the LRU list because it may be pretty heavy with
15438                    // UI stuff.  We'll tag it with a label just to help
15439                    // debug and understand what is going on.
15440                    if (adj > ProcessList.SERVICE_ADJ) {
15441                        app.adjType = "cch-started-ui-services";
15442                    }
15443                } else {
15444                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15445                        // This service has seen some activity within
15446                        // recent memory, so we will keep its process ahead
15447                        // of the background processes.
15448                        if (adj > ProcessList.SERVICE_ADJ) {
15449                            adj = ProcessList.SERVICE_ADJ;
15450                            app.adjType = "started-services";
15451                            app.cached = false;
15452                        }
15453                    }
15454                    // If we have let the service slide into the background
15455                    // state, still have some text describing what it is doing
15456                    // even though the service no longer has an impact.
15457                    if (adj > ProcessList.SERVICE_ADJ) {
15458                        app.adjType = "cch-started-services";
15459                    }
15460                }
15461                // Don't kill this process because it is doing work; it
15462                // has said it is doing work.
15463                app.keeping = true;
15464            }
15465            for (int conni = s.connections.size()-1;
15466                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15467                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15468                            || procState > ActivityManager.PROCESS_STATE_TOP);
15469                    conni--) {
15470                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15471                for (int i = 0;
15472                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15473                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15474                                || procState > ActivityManager.PROCESS_STATE_TOP);
15475                        i++) {
15476                    // XXX should compute this based on the max of
15477                    // all connected clients.
15478                    ConnectionRecord cr = clist.get(i);
15479                    if (cr.binding.client == app) {
15480                        // Binding to ourself is not interesting.
15481                        continue;
15482                    }
15483                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15484                        ProcessRecord client = cr.binding.client;
15485                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15486                                TOP_APP, doingAll, now);
15487                        int clientProcState = client.curProcState;
15488                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15489                            // If the other app is cached for any reason, for purposes here
15490                            // we are going to consider it empty.  The specific cached state
15491                            // doesn't propagate except under certain conditions.
15492                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15493                        }
15494                        String adjType = null;
15495                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15496                            // Not doing bind OOM management, so treat
15497                            // this guy more like a started service.
15498                            if (app.hasShownUi && app != mHomeProcess) {
15499                                // If this process has shown some UI, let it immediately
15500                                // go to the LRU list because it may be pretty heavy with
15501                                // UI stuff.  We'll tag it with a label just to help
15502                                // debug and understand what is going on.
15503                                if (adj > clientAdj) {
15504                                    adjType = "cch-bound-ui-services";
15505                                }
15506                                app.cached = false;
15507                                clientAdj = adj;
15508                                clientProcState = procState;
15509                            } else {
15510                                if (now >= (s.lastActivity
15511                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15512                                    // This service has not seen activity within
15513                                    // recent memory, so allow it to drop to the
15514                                    // LRU list if there is no other reason to keep
15515                                    // it around.  We'll also tag it with a label just
15516                                    // to help debug and undertand what is going on.
15517                                    if (adj > clientAdj) {
15518                                        adjType = "cch-bound-services";
15519                                    }
15520                                    clientAdj = adj;
15521                                }
15522                            }
15523                        }
15524                        if (adj > clientAdj) {
15525                            // If this process has recently shown UI, and
15526                            // the process that is binding to it is less
15527                            // important than being visible, then we don't
15528                            // care about the binding as much as we care
15529                            // about letting this process get into the LRU
15530                            // list to be killed and restarted if needed for
15531                            // memory.
15532                            if (app.hasShownUi && app != mHomeProcess
15533                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15534                                adjType = "cch-bound-ui-services";
15535                            } else {
15536                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15537                                        |Context.BIND_IMPORTANT)) != 0) {
15538                                    adj = clientAdj;
15539                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15540                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15541                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15542                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15543                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15544                                    adj = clientAdj;
15545                                } else {
15546                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15547                                        adj = ProcessList.VISIBLE_APP_ADJ;
15548                                    }
15549                                }
15550                                if (!client.cached) {
15551                                    app.cached = false;
15552                                }
15553                                if (client.keeping) {
15554                                    app.keeping = true;
15555                                }
15556                                adjType = "service";
15557                            }
15558                        }
15559                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15560                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15561                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15562                            }
15563                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15564                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15565                                    // Special handling of clients who are in the top state.
15566                                    // We *may* want to consider this process to be in the
15567                                    // top state as well, but only if there is not another
15568                                    // reason for it to be running.  Being on the top is a
15569                                    // special state, meaning you are specifically running
15570                                    // for the current top app.  If the process is already
15571                                    // running in the background for some other reason, it
15572                                    // is more important to continue considering it to be
15573                                    // in the background state.
15574                                    mayBeTop = true;
15575                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15576                                } else {
15577                                    // Special handling for above-top states (persistent
15578                                    // processes).  These should not bring the current process
15579                                    // into the top state, since they are not on top.  Instead
15580                                    // give them the best state after that.
15581                                    clientProcState =
15582                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15583                                }
15584                            }
15585                        } else {
15586                            if (clientProcState <
15587                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15588                                clientProcState =
15589                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15590                            }
15591                        }
15592                        if (procState > clientProcState) {
15593                            procState = clientProcState;
15594                        }
15595                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15596                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15597                            app.pendingUiClean = true;
15598                        }
15599                        if (adjType != null) {
15600                            app.adjType = adjType;
15601                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15602                                    .REASON_SERVICE_IN_USE;
15603                            app.adjSource = cr.binding.client;
15604                            app.adjSourceOom = clientAdj;
15605                            app.adjTarget = s.name;
15606                        }
15607                    }
15608                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15609                        app.treatLikeActivity = true;
15610                    }
15611                    final ActivityRecord a = cr.activity;
15612                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15613                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15614                                (a.visible || a.state == ActivityState.RESUMED
15615                                 || a.state == ActivityState.PAUSING)) {
15616                            adj = ProcessList.FOREGROUND_APP_ADJ;
15617                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15618                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15619                            }
15620                            app.cached = false;
15621                            app.adjType = "service";
15622                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15623                                    .REASON_SERVICE_IN_USE;
15624                            app.adjSource = a;
15625                            app.adjSourceOom = adj;
15626                            app.adjTarget = s.name;
15627                        }
15628                    }
15629                }
15630            }
15631        }
15632
15633        for (int provi = app.pubProviders.size()-1;
15634                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15635                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15636                        || procState > ActivityManager.PROCESS_STATE_TOP);
15637                provi--) {
15638            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15639            for (int i = cpr.connections.size()-1;
15640                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15641                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15642                            || procState > ActivityManager.PROCESS_STATE_TOP);
15643                    i--) {
15644                ContentProviderConnection conn = cpr.connections.get(i);
15645                ProcessRecord client = conn.client;
15646                if (client == app) {
15647                    // Being our own client is not interesting.
15648                    continue;
15649                }
15650                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15651                int clientProcState = client.curProcState;
15652                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15653                    // If the other app is cached for any reason, for purposes here
15654                    // we are going to consider it empty.
15655                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15656                }
15657                if (adj > clientAdj) {
15658                    if (app.hasShownUi && app != mHomeProcess
15659                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15660                        app.adjType = "cch-ui-provider";
15661                    } else {
15662                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15663                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15664                        app.adjType = "provider";
15665                    }
15666                    app.cached &= client.cached;
15667                    app.keeping |= client.keeping;
15668                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15669                            .REASON_PROVIDER_IN_USE;
15670                    app.adjSource = client;
15671                    app.adjSourceOom = clientAdj;
15672                    app.adjTarget = cpr.name;
15673                }
15674                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15675                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15676                        // Special handling of clients who are in the top state.
15677                        // We *may* want to consider this process to be in the
15678                        // top state as well, but only if there is not another
15679                        // reason for it to be running.  Being on the top is a
15680                        // special state, meaning you are specifically running
15681                        // for the current top app.  If the process is already
15682                        // running in the background for some other reason, it
15683                        // is more important to continue considering it to be
15684                        // in the background state.
15685                        mayBeTop = true;
15686                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15687                    } else {
15688                        // Special handling for above-top states (persistent
15689                        // processes).  These should not bring the current process
15690                        // into the top state, since they are not on top.  Instead
15691                        // give them the best state after that.
15692                        clientProcState =
15693                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15694                    }
15695                }
15696                if (procState > clientProcState) {
15697                    procState = clientProcState;
15698                }
15699                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15700                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15701                }
15702            }
15703            // If the provider has external (non-framework) process
15704            // dependencies, ensure that its adjustment is at least
15705            // FOREGROUND_APP_ADJ.
15706            if (cpr.hasExternalProcessHandles()) {
15707                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15708                    adj = ProcessList.FOREGROUND_APP_ADJ;
15709                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15710                    app.cached = false;
15711                    app.keeping = true;
15712                    app.adjType = "provider";
15713                    app.adjTarget = cpr.name;
15714                }
15715                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15716                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15717                }
15718            }
15719        }
15720
15721        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15722            // A client of one of our services or providers is in the top state.  We
15723            // *may* want to be in the top state, but not if we are already running in
15724            // the background for some other reason.  For the decision here, we are going
15725            // to pick out a few specific states that we want to remain in when a client
15726            // is top (states that tend to be longer-term) and otherwise allow it to go
15727            // to the top state.
15728            switch (procState) {
15729                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15730                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15731                case ActivityManager.PROCESS_STATE_SERVICE:
15732                    // These all are longer-term states, so pull them up to the top
15733                    // of the background states, but not all the way to the top state.
15734                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15735                    break;
15736                default:
15737                    // Otherwise, top is a better choice, so take it.
15738                    procState = ActivityManager.PROCESS_STATE_TOP;
15739                    break;
15740            }
15741        }
15742
15743        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15744            if (app.hasClientActivities) {
15745                // This is a cached process, but with client activities.  Mark it so.
15746                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15747                app.adjType = "cch-client-act";
15748            } else if (app.treatLikeActivity) {
15749                // This is a cached process, but somebody wants us to treat it like it has
15750                // an activity, okay!
15751                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15752                app.adjType = "cch-as-act";
15753            }
15754        }
15755
15756        if (adj == ProcessList.SERVICE_ADJ) {
15757            if (doingAll) {
15758                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15759                mNewNumServiceProcs++;
15760                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15761                if (!app.serviceb) {
15762                    // This service isn't far enough down on the LRU list to
15763                    // normally be a B service, but if we are low on RAM and it
15764                    // is large we want to force it down since we would prefer to
15765                    // keep launcher over it.
15766                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15767                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15768                        app.serviceHighRam = true;
15769                        app.serviceb = true;
15770                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15771                    } else {
15772                        mNewNumAServiceProcs++;
15773                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15774                    }
15775                } else {
15776                    app.serviceHighRam = false;
15777                }
15778            }
15779            if (app.serviceb) {
15780                adj = ProcessList.SERVICE_B_ADJ;
15781            }
15782        }
15783
15784        app.curRawAdj = adj;
15785
15786        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15787        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15788        if (adj > app.maxAdj) {
15789            adj = app.maxAdj;
15790            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15791                schedGroup = Process.THREAD_GROUP_DEFAULT;
15792            }
15793        }
15794        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15795            app.keeping = true;
15796        }
15797
15798        // Do final modification to adj.  Everything we do between here and applying
15799        // the final setAdj must be done in this function, because we will also use
15800        // it when computing the final cached adj later.  Note that we don't need to
15801        // worry about this for max adj above, since max adj will always be used to
15802        // keep it out of the cached vaues.
15803        app.curAdj = app.modifyRawOomAdj(adj);
15804        app.curSchedGroup = schedGroup;
15805        app.curProcState = procState;
15806        app.foregroundActivities = foregroundActivities;
15807
15808        return app.curRawAdj;
15809    }
15810
15811    /**
15812     * Schedule PSS collection of a process.
15813     */
15814    void requestPssLocked(ProcessRecord proc, int procState) {
15815        if (mPendingPssProcesses.contains(proc)) {
15816            return;
15817        }
15818        if (mPendingPssProcesses.size() == 0) {
15819            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15820        }
15821        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15822        proc.pssProcState = procState;
15823        mPendingPssProcesses.add(proc);
15824    }
15825
15826    /**
15827     * Schedule PSS collection of all processes.
15828     */
15829    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15830        if (!always) {
15831            if (now < (mLastFullPssTime +
15832                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15833                return;
15834            }
15835        }
15836        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15837        mLastFullPssTime = now;
15838        mFullPssPending = true;
15839        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15840        mPendingPssProcesses.clear();
15841        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15842            ProcessRecord app = mLruProcesses.get(i);
15843            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15844                app.pssProcState = app.setProcState;
15845                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15846                        isSleeping(), now);
15847                mPendingPssProcesses.add(app);
15848            }
15849        }
15850        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15851    }
15852
15853    /**
15854     * Ask a given process to GC right now.
15855     */
15856    final void performAppGcLocked(ProcessRecord app) {
15857        try {
15858            app.lastRequestedGc = SystemClock.uptimeMillis();
15859            if (app.thread != null) {
15860                if (app.reportLowMemory) {
15861                    app.reportLowMemory = false;
15862                    app.thread.scheduleLowMemory();
15863                } else {
15864                    app.thread.processInBackground();
15865                }
15866            }
15867        } catch (Exception e) {
15868            // whatever.
15869        }
15870    }
15871
15872    /**
15873     * Returns true if things are idle enough to perform GCs.
15874     */
15875    private final boolean canGcNowLocked() {
15876        boolean processingBroadcasts = false;
15877        for (BroadcastQueue q : mBroadcastQueues) {
15878            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15879                processingBroadcasts = true;
15880            }
15881        }
15882        return !processingBroadcasts
15883                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15884    }
15885
15886    /**
15887     * Perform GCs on all processes that are waiting for it, but only
15888     * if things are idle.
15889     */
15890    final void performAppGcsLocked() {
15891        final int N = mProcessesToGc.size();
15892        if (N <= 0) {
15893            return;
15894        }
15895        if (canGcNowLocked()) {
15896            while (mProcessesToGc.size() > 0) {
15897                ProcessRecord proc = mProcessesToGc.remove(0);
15898                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15899                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15900                            <= SystemClock.uptimeMillis()) {
15901                        // To avoid spamming the system, we will GC processes one
15902                        // at a time, waiting a few seconds between each.
15903                        performAppGcLocked(proc);
15904                        scheduleAppGcsLocked();
15905                        return;
15906                    } else {
15907                        // It hasn't been long enough since we last GCed this
15908                        // process...  put it in the list to wait for its time.
15909                        addProcessToGcListLocked(proc);
15910                        break;
15911                    }
15912                }
15913            }
15914
15915            scheduleAppGcsLocked();
15916        }
15917    }
15918
15919    /**
15920     * If all looks good, perform GCs on all processes waiting for them.
15921     */
15922    final void performAppGcsIfAppropriateLocked() {
15923        if (canGcNowLocked()) {
15924            performAppGcsLocked();
15925            return;
15926        }
15927        // Still not idle, wait some more.
15928        scheduleAppGcsLocked();
15929    }
15930
15931    /**
15932     * Schedule the execution of all pending app GCs.
15933     */
15934    final void scheduleAppGcsLocked() {
15935        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15936
15937        if (mProcessesToGc.size() > 0) {
15938            // Schedule a GC for the time to the next process.
15939            ProcessRecord proc = mProcessesToGc.get(0);
15940            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15941
15942            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15943            long now = SystemClock.uptimeMillis();
15944            if (when < (now+GC_TIMEOUT)) {
15945                when = now + GC_TIMEOUT;
15946            }
15947            mHandler.sendMessageAtTime(msg, when);
15948        }
15949    }
15950
15951    /**
15952     * Add a process to the array of processes waiting to be GCed.  Keeps the
15953     * list in sorted order by the last GC time.  The process can't already be
15954     * on the list.
15955     */
15956    final void addProcessToGcListLocked(ProcessRecord proc) {
15957        boolean added = false;
15958        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15959            if (mProcessesToGc.get(i).lastRequestedGc <
15960                    proc.lastRequestedGc) {
15961                added = true;
15962                mProcessesToGc.add(i+1, proc);
15963                break;
15964            }
15965        }
15966        if (!added) {
15967            mProcessesToGc.add(0, proc);
15968        }
15969    }
15970
15971    /**
15972     * Set up to ask a process to GC itself.  This will either do it
15973     * immediately, or put it on the list of processes to gc the next
15974     * time things are idle.
15975     */
15976    final void scheduleAppGcLocked(ProcessRecord app) {
15977        long now = SystemClock.uptimeMillis();
15978        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15979            return;
15980        }
15981        if (!mProcessesToGc.contains(app)) {
15982            addProcessToGcListLocked(app);
15983            scheduleAppGcsLocked();
15984        }
15985    }
15986
15987    final void checkExcessivePowerUsageLocked(boolean doKills) {
15988        updateCpuStatsNow();
15989
15990        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15991        boolean doWakeKills = doKills;
15992        boolean doCpuKills = doKills;
15993        if (mLastPowerCheckRealtime == 0) {
15994            doWakeKills = false;
15995        }
15996        if (mLastPowerCheckUptime == 0) {
15997            doCpuKills = false;
15998        }
15999        if (stats.isScreenOn()) {
16000            doWakeKills = false;
16001        }
16002        final long curRealtime = SystemClock.elapsedRealtime();
16003        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16004        final long curUptime = SystemClock.uptimeMillis();
16005        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16006        mLastPowerCheckRealtime = curRealtime;
16007        mLastPowerCheckUptime = curUptime;
16008        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16009            doWakeKills = false;
16010        }
16011        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16012            doCpuKills = false;
16013        }
16014        int i = mLruProcesses.size();
16015        while (i > 0) {
16016            i--;
16017            ProcessRecord app = mLruProcesses.get(i);
16018            if (!app.keeping) {
16019                long wtime;
16020                synchronized (stats) {
16021                    wtime = stats.getProcessWakeTime(app.info.uid,
16022                            app.pid, curRealtime);
16023                }
16024                long wtimeUsed = wtime - app.lastWakeTime;
16025                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16026                if (DEBUG_POWER) {
16027                    StringBuilder sb = new StringBuilder(128);
16028                    sb.append("Wake for ");
16029                    app.toShortString(sb);
16030                    sb.append(": over ");
16031                    TimeUtils.formatDuration(realtimeSince, sb);
16032                    sb.append(" used ");
16033                    TimeUtils.formatDuration(wtimeUsed, sb);
16034                    sb.append(" (");
16035                    sb.append((wtimeUsed*100)/realtimeSince);
16036                    sb.append("%)");
16037                    Slog.i(TAG, sb.toString());
16038                    sb.setLength(0);
16039                    sb.append("CPU for ");
16040                    app.toShortString(sb);
16041                    sb.append(": over ");
16042                    TimeUtils.formatDuration(uptimeSince, sb);
16043                    sb.append(" used ");
16044                    TimeUtils.formatDuration(cputimeUsed, sb);
16045                    sb.append(" (");
16046                    sb.append((cputimeUsed*100)/uptimeSince);
16047                    sb.append("%)");
16048                    Slog.i(TAG, sb.toString());
16049                }
16050                // If a process has held a wake lock for more
16051                // than 50% of the time during this period,
16052                // that sounds bad.  Kill!
16053                if (doWakeKills && realtimeSince > 0
16054                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16055                    synchronized (stats) {
16056                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16057                                realtimeSince, wtimeUsed);
16058                    }
16059                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
16060                            + " during " + realtimeSince);
16061                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16062                } else if (doCpuKills && uptimeSince > 0
16063                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
16064                    synchronized (stats) {
16065                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16066                                uptimeSince, cputimeUsed);
16067                    }
16068                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
16069                            + " during " + uptimeSince);
16070                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16071                } else {
16072                    app.lastWakeTime = wtime;
16073                    app.lastCpuTime = app.curCpuTime;
16074                }
16075            }
16076        }
16077    }
16078
16079    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
16080            ProcessRecord TOP_APP, boolean doingAll, long now) {
16081        boolean success = true;
16082
16083        if (app.curRawAdj != app.setRawAdj) {
16084            if (wasKeeping && !app.keeping) {
16085                // This app is no longer something we want to keep.  Note
16086                // its current wake lock time to later know to kill it if
16087                // it is not behaving well.
16088                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16089                synchronized (stats) {
16090                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
16091                            app.pid, SystemClock.elapsedRealtime());
16092                }
16093                app.lastCpuTime = app.curCpuTime;
16094            }
16095
16096            app.setRawAdj = app.curRawAdj;
16097        }
16098
16099        int changes = 0;
16100
16101        if (app.curAdj != app.setAdj) {
16102            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16103            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16104                TAG, "Set " + app.pid + " " + app.processName +
16105                " adj " + app.curAdj + ": " + app.adjType);
16106            app.setAdj = app.curAdj;
16107        }
16108
16109        if (app.setSchedGroup != app.curSchedGroup) {
16110            app.setSchedGroup = app.curSchedGroup;
16111            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16112                    "Setting process group of " + app.processName
16113                    + " to " + app.curSchedGroup);
16114            if (app.waitingToKill != null &&
16115                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16116                killUnneededProcessLocked(app, app.waitingToKill);
16117                success = false;
16118            } else {
16119                if (true) {
16120                    long oldId = Binder.clearCallingIdentity();
16121                    try {
16122                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16123                    } catch (Exception e) {
16124                        Slog.w(TAG, "Failed setting process group of " + app.pid
16125                                + " to " + app.curSchedGroup);
16126                        e.printStackTrace();
16127                    } finally {
16128                        Binder.restoreCallingIdentity(oldId);
16129                    }
16130                } else {
16131                    if (app.thread != null) {
16132                        try {
16133                            app.thread.setSchedulingGroup(app.curSchedGroup);
16134                        } catch (RemoteException e) {
16135                        }
16136                    }
16137                }
16138                Process.setSwappiness(app.pid,
16139                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16140            }
16141        }
16142        if (app.repForegroundActivities != app.foregroundActivities) {
16143            app.repForegroundActivities = app.foregroundActivities;
16144            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16145        }
16146        if (app.repProcState != app.curProcState) {
16147            app.repProcState = app.curProcState;
16148            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16149            if (app.thread != null) {
16150                try {
16151                    if (false) {
16152                        //RuntimeException h = new RuntimeException("here");
16153                        Slog.i(TAG, "Sending new process state " + app.repProcState
16154                                + " to " + app /*, h*/);
16155                    }
16156                    app.thread.setProcessState(app.repProcState);
16157                } catch (RemoteException e) {
16158                }
16159            }
16160        }
16161        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16162                app.setProcState)) {
16163            app.lastStateTime = now;
16164            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16165                    isSleeping(), now);
16166            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16167                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16168                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16169                    + (app.nextPssTime-now) + ": " + app);
16170        } else {
16171            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16172                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16173                requestPssLocked(app, app.setProcState);
16174                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16175                        isSleeping(), now);
16176            } else if (false && DEBUG_PSS) {
16177                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16178            }
16179        }
16180        if (app.setProcState != app.curProcState) {
16181            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16182                    "Proc state change of " + app.processName
16183                    + " to " + app.curProcState);
16184            app.setProcState = app.curProcState;
16185            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16186                app.notCachedSinceIdle = false;
16187            }
16188            if (!doingAll) {
16189                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
16190            } else {
16191                app.procStateChanged = true;
16192            }
16193        }
16194
16195        if (changes != 0) {
16196            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16197            int i = mPendingProcessChanges.size()-1;
16198            ProcessChangeItem item = null;
16199            while (i >= 0) {
16200                item = mPendingProcessChanges.get(i);
16201                if (item.pid == app.pid) {
16202                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16203                    break;
16204                }
16205                i--;
16206            }
16207            if (i < 0) {
16208                // No existing item in pending changes; need a new one.
16209                final int NA = mAvailProcessChanges.size();
16210                if (NA > 0) {
16211                    item = mAvailProcessChanges.remove(NA-1);
16212                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16213                } else {
16214                    item = new ProcessChangeItem();
16215                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16216                }
16217                item.changes = 0;
16218                item.pid = app.pid;
16219                item.uid = app.info.uid;
16220                if (mPendingProcessChanges.size() == 0) {
16221                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16222                            "*** Enqueueing dispatch processes changed!");
16223                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16224                }
16225                mPendingProcessChanges.add(item);
16226            }
16227            item.changes |= changes;
16228            item.processState = app.repProcState;
16229            item.foregroundActivities = app.repForegroundActivities;
16230            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16231                    + Integer.toHexString(System.identityHashCode(item))
16232                    + " " + app.toShortString() + ": changes=" + item.changes
16233                    + " procState=" + item.processState
16234                    + " foreground=" + item.foregroundActivities
16235                    + " type=" + app.adjType + " source=" + app.adjSource
16236                    + " target=" + app.adjTarget);
16237        }
16238
16239        return success;
16240    }
16241
16242    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
16243        if (proc.thread != null) {
16244            if (proc.baseProcessTracker != null) {
16245                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16246            }
16247            if (proc.repProcState >= 0) {
16248                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
16249                        proc.repProcState);
16250            }
16251        }
16252    }
16253
16254    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16255            ProcessRecord TOP_APP, boolean doingAll, long now) {
16256        if (app.thread == null) {
16257            return false;
16258        }
16259
16260        final boolean wasKeeping = app.keeping;
16261
16262        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16263
16264        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
16265    }
16266
16267    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16268            boolean oomAdj) {
16269        if (isForeground != proc.foregroundServices) {
16270            proc.foregroundServices = isForeground;
16271            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16272                    proc.info.uid);
16273            if (isForeground) {
16274                if (curProcs == null) {
16275                    curProcs = new ArrayList<ProcessRecord>();
16276                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16277                }
16278                if (!curProcs.contains(proc)) {
16279                    curProcs.add(proc);
16280                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16281                            proc.info.packageName, proc.info.uid);
16282                }
16283            } else {
16284                if (curProcs != null) {
16285                    if (curProcs.remove(proc)) {
16286                        mBatteryStatsService.noteEvent(
16287                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16288                                proc.info.packageName, proc.info.uid);
16289                        if (curProcs.size() <= 0) {
16290                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16291                        }
16292                    }
16293                }
16294            }
16295            if (oomAdj) {
16296                updateOomAdjLocked();
16297            }
16298        }
16299    }
16300
16301    private final ActivityRecord resumedAppLocked() {
16302        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16303        String pkg;
16304        int uid;
16305        if (act != null) {
16306            pkg = act.packageName;
16307            uid = act.info.applicationInfo.uid;
16308        } else {
16309            pkg = null;
16310            uid = -1;
16311        }
16312        // Has the UID or resumed package name changed?
16313        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16314                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16315            if (mCurResumedPackage != null) {
16316                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16317                        mCurResumedPackage, mCurResumedUid);
16318            }
16319            mCurResumedPackage = pkg;
16320            mCurResumedUid = uid;
16321            if (mCurResumedPackage != null) {
16322                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16323                        mCurResumedPackage, mCurResumedUid);
16324            }
16325        }
16326        return act;
16327    }
16328
16329    final boolean updateOomAdjLocked(ProcessRecord app) {
16330        final ActivityRecord TOP_ACT = resumedAppLocked();
16331        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16332        final boolean wasCached = app.cached;
16333
16334        mAdjSeq++;
16335
16336        // This is the desired cached adjusment we want to tell it to use.
16337        // If our app is currently cached, we know it, and that is it.  Otherwise,
16338        // we don't know it yet, and it needs to now be cached we will then
16339        // need to do a complete oom adj.
16340        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16341                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16342        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16343                SystemClock.uptimeMillis());
16344        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16345            // Changed to/from cached state, so apps after it in the LRU
16346            // list may also be changed.
16347            updateOomAdjLocked();
16348        }
16349        return success;
16350    }
16351
16352    final void updateOomAdjLocked() {
16353        final ActivityRecord TOP_ACT = resumedAppLocked();
16354        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16355        final long now = SystemClock.uptimeMillis();
16356        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16357        final int N = mLruProcesses.size();
16358
16359        if (false) {
16360            RuntimeException e = new RuntimeException();
16361            e.fillInStackTrace();
16362            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16363        }
16364
16365        mAdjSeq++;
16366        mNewNumServiceProcs = 0;
16367        mNewNumAServiceProcs = 0;
16368
16369        final int emptyProcessLimit;
16370        final int cachedProcessLimit;
16371        if (mProcessLimit <= 0) {
16372            emptyProcessLimit = cachedProcessLimit = 0;
16373        } else if (mProcessLimit == 1) {
16374            emptyProcessLimit = 1;
16375            cachedProcessLimit = 0;
16376        } else {
16377            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16378            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16379        }
16380
16381        // Let's determine how many processes we have running vs.
16382        // how many slots we have for background processes; we may want
16383        // to put multiple processes in a slot of there are enough of
16384        // them.
16385        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16386                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16387        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16388        if (numEmptyProcs > cachedProcessLimit) {
16389            // If there are more empty processes than our limit on cached
16390            // processes, then use the cached process limit for the factor.
16391            // This ensures that the really old empty processes get pushed
16392            // down to the bottom, so if we are running low on memory we will
16393            // have a better chance at keeping around more cached processes
16394            // instead of a gazillion empty processes.
16395            numEmptyProcs = cachedProcessLimit;
16396        }
16397        int emptyFactor = numEmptyProcs/numSlots;
16398        if (emptyFactor < 1) emptyFactor = 1;
16399        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16400        if (cachedFactor < 1) cachedFactor = 1;
16401        int stepCached = 0;
16402        int stepEmpty = 0;
16403        int numCached = 0;
16404        int numEmpty = 0;
16405        int numTrimming = 0;
16406
16407        mNumNonCachedProcs = 0;
16408        mNumCachedHiddenProcs = 0;
16409
16410        // First update the OOM adjustment for each of the
16411        // application processes based on their current state.
16412        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16413        int nextCachedAdj = curCachedAdj+1;
16414        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16415        int nextEmptyAdj = curEmptyAdj+2;
16416        for (int i=N-1; i>=0; i--) {
16417            ProcessRecord app = mLruProcesses.get(i);
16418            if (!app.killedByAm && app.thread != null) {
16419                app.procStateChanged = false;
16420                final boolean wasKeeping = app.keeping;
16421                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16422
16423                // If we haven't yet assigned the final cached adj
16424                // to the process, do that now.
16425                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16426                    switch (app.curProcState) {
16427                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16428                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16429                            // This process is a cached process holding activities...
16430                            // assign it the next cached value for that type, and then
16431                            // step that cached level.
16432                            app.curRawAdj = curCachedAdj;
16433                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16434                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16435                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16436                                    + ")");
16437                            if (curCachedAdj != nextCachedAdj) {
16438                                stepCached++;
16439                                if (stepCached >= cachedFactor) {
16440                                    stepCached = 0;
16441                                    curCachedAdj = nextCachedAdj;
16442                                    nextCachedAdj += 2;
16443                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16444                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16445                                    }
16446                                }
16447                            }
16448                            break;
16449                        default:
16450                            // For everything else, assign next empty cached process
16451                            // level and bump that up.  Note that this means that
16452                            // long-running services that have dropped down to the
16453                            // cached level will be treated as empty (since their process
16454                            // state is still as a service), which is what we want.
16455                            app.curRawAdj = curEmptyAdj;
16456                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16457                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16458                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16459                                    + ")");
16460                            if (curEmptyAdj != nextEmptyAdj) {
16461                                stepEmpty++;
16462                                if (stepEmpty >= emptyFactor) {
16463                                    stepEmpty = 0;
16464                                    curEmptyAdj = nextEmptyAdj;
16465                                    nextEmptyAdj += 2;
16466                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16467                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16468                                    }
16469                                }
16470                            }
16471                            break;
16472                    }
16473                }
16474
16475                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
16476
16477                // Count the number of process types.
16478                switch (app.curProcState) {
16479                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16480                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16481                        mNumCachedHiddenProcs++;
16482                        numCached++;
16483                        if (numCached > cachedProcessLimit) {
16484                            killUnneededProcessLocked(app, "cached #" + numCached);
16485                        }
16486                        break;
16487                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16488                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16489                                && app.lastActivityTime < oldTime) {
16490                            killUnneededProcessLocked(app, "empty for "
16491                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16492                                    / 1000) + "s");
16493                        } else {
16494                            numEmpty++;
16495                            if (numEmpty > emptyProcessLimit) {
16496                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16497                            }
16498                        }
16499                        break;
16500                    default:
16501                        mNumNonCachedProcs++;
16502                        break;
16503                }
16504
16505                if (app.isolated && app.services.size() <= 0) {
16506                    // If this is an isolated process, and there are no
16507                    // services running in it, then the process is no longer
16508                    // needed.  We agressively kill these because we can by
16509                    // definition not re-use the same process again, and it is
16510                    // good to avoid having whatever code was running in them
16511                    // left sitting around after no longer needed.
16512                    killUnneededProcessLocked(app, "isolated not needed");
16513                }
16514
16515                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16516                        && !app.killedByAm) {
16517                    numTrimming++;
16518                }
16519            }
16520        }
16521
16522        mNumServiceProcs = mNewNumServiceProcs;
16523
16524        // Now determine the memory trimming level of background processes.
16525        // Unfortunately we need to start at the back of the list to do this
16526        // properly.  We only do this if the number of background apps we
16527        // are managing to keep around is less than half the maximum we desire;
16528        // if we are keeping a good number around, we'll let them use whatever
16529        // memory they want.
16530        final int numCachedAndEmpty = numCached + numEmpty;
16531        int memFactor;
16532        if (numCached <= ProcessList.TRIM_CACHED_APPS
16533                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16534            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16535                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16536            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16537                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16538            } else {
16539                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16540            }
16541        } else {
16542            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16543        }
16544        // We always allow the memory level to go up (better).  We only allow it to go
16545        // down if we are in a state where that is allowed, *and* the total number of processes
16546        // has gone down since last time.
16547        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16548                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16549                + " last=" + mLastNumProcesses);
16550        if (memFactor > mLastMemoryLevel) {
16551            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16552                memFactor = mLastMemoryLevel;
16553                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16554            }
16555        }
16556        mLastMemoryLevel = memFactor;
16557        mLastNumProcesses = mLruProcesses.size();
16558        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16559        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16560        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16561            if (mLowRamStartTime == 0) {
16562                mLowRamStartTime = now;
16563            }
16564            int step = 0;
16565            int fgTrimLevel;
16566            switch (memFactor) {
16567                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16568                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16569                    break;
16570                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16571                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16572                    break;
16573                default:
16574                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16575                    break;
16576            }
16577            int factor = numTrimming/3;
16578            int minFactor = 2;
16579            if (mHomeProcess != null) minFactor++;
16580            if (mPreviousProcess != null) minFactor++;
16581            if (factor < minFactor) factor = minFactor;
16582            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16583            for (int i=N-1; i>=0; i--) {
16584                ProcessRecord app = mLruProcesses.get(i);
16585                if (allChanged || app.procStateChanged) {
16586                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16587                    app.procStateChanged = false;
16588                }
16589                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16590                        && !app.killedByAm) {
16591                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16592                        try {
16593                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16594                                    "Trimming memory of " + app.processName
16595                                    + " to " + curLevel);
16596                            app.thread.scheduleTrimMemory(curLevel);
16597                        } catch (RemoteException e) {
16598                        }
16599                        if (false) {
16600                            // For now we won't do this; our memory trimming seems
16601                            // to be good enough at this point that destroying
16602                            // activities causes more harm than good.
16603                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16604                                    && app != mHomeProcess && app != mPreviousProcess) {
16605                                // Need to do this on its own message because the stack may not
16606                                // be in a consistent state at this point.
16607                                // For these apps we will also finish their activities
16608                                // to help them free memory.
16609                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16610                            }
16611                        }
16612                    }
16613                    app.trimMemoryLevel = curLevel;
16614                    step++;
16615                    if (step >= factor) {
16616                        step = 0;
16617                        switch (curLevel) {
16618                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16619                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16620                                break;
16621                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16622                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16623                                break;
16624                        }
16625                    }
16626                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16627                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16628                            && app.thread != null) {
16629                        try {
16630                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16631                                    "Trimming memory of heavy-weight " + app.processName
16632                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16633                            app.thread.scheduleTrimMemory(
16634                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16635                        } catch (RemoteException e) {
16636                        }
16637                    }
16638                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16639                } else {
16640                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16641                            || app.systemNoUi) && app.pendingUiClean) {
16642                        // If this application is now in the background and it
16643                        // had done UI, then give it the special trim level to
16644                        // have it free UI resources.
16645                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16646                        if (app.trimMemoryLevel < level && app.thread != null) {
16647                            try {
16648                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16649                                        "Trimming memory of bg-ui " + app.processName
16650                                        + " to " + level);
16651                                app.thread.scheduleTrimMemory(level);
16652                            } catch (RemoteException e) {
16653                            }
16654                        }
16655                        app.pendingUiClean = false;
16656                    }
16657                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16658                        try {
16659                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16660                                    "Trimming memory of fg " + app.processName
16661                                    + " to " + fgTrimLevel);
16662                            app.thread.scheduleTrimMemory(fgTrimLevel);
16663                        } catch (RemoteException e) {
16664                        }
16665                    }
16666                    app.trimMemoryLevel = fgTrimLevel;
16667                }
16668            }
16669        } else {
16670            if (mLowRamStartTime != 0) {
16671                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16672                mLowRamStartTime = 0;
16673            }
16674            for (int i=N-1; i>=0; i--) {
16675                ProcessRecord app = mLruProcesses.get(i);
16676                if (allChanged || app.procStateChanged) {
16677                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16678                    app.procStateChanged = false;
16679                }
16680                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16681                        || app.systemNoUi) && app.pendingUiClean) {
16682                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16683                            && app.thread != null) {
16684                        try {
16685                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16686                                    "Trimming memory of ui hidden " + app.processName
16687                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16688                            app.thread.scheduleTrimMemory(
16689                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16690                        } catch (RemoteException e) {
16691                        }
16692                    }
16693                    app.pendingUiClean = false;
16694                }
16695                app.trimMemoryLevel = 0;
16696            }
16697        }
16698
16699        if (mAlwaysFinishActivities) {
16700            // Need to do this on its own message because the stack may not
16701            // be in a consistent state at this point.
16702            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16703        }
16704
16705        if (allChanged) {
16706            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16707        }
16708
16709        if (mProcessStats.shouldWriteNowLocked(now)) {
16710            mHandler.post(new Runnable() {
16711                @Override public void run() {
16712                    synchronized (ActivityManagerService.this) {
16713                        mProcessStats.writeStateAsyncLocked();
16714                    }
16715                }
16716            });
16717        }
16718
16719        if (DEBUG_OOM_ADJ) {
16720            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16721        }
16722    }
16723
16724    final void trimApplications() {
16725        synchronized (this) {
16726            int i;
16727
16728            // First remove any unused application processes whose package
16729            // has been removed.
16730            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16731                final ProcessRecord app = mRemovedProcesses.get(i);
16732                if (app.activities.size() == 0
16733                        && app.curReceiver == null && app.services.size() == 0) {
16734                    Slog.i(
16735                        TAG, "Exiting empty application process "
16736                        + app.processName + " ("
16737                        + (app.thread != null ? app.thread.asBinder() : null)
16738                        + ")\n");
16739                    if (app.pid > 0 && app.pid != MY_PID) {
16740                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16741                                app.processName, app.setAdj, "empty");
16742                        app.killedByAm = true;
16743                        Process.killProcessQuiet(app.pid);
16744                        Process.killProcessGroup(app.info.uid, app.pid);
16745                    } else {
16746                        try {
16747                            app.thread.scheduleExit();
16748                        } catch (Exception e) {
16749                            // Ignore exceptions.
16750                        }
16751                    }
16752                    cleanUpApplicationRecordLocked(app, false, true, -1);
16753                    mRemovedProcesses.remove(i);
16754
16755                    if (app.persistent) {
16756                        addAppLocked(app.info, false, null /* ABI override */);
16757                    }
16758                }
16759            }
16760
16761            // Now update the oom adj for all processes.
16762            updateOomAdjLocked();
16763        }
16764    }
16765
16766    /** This method sends the specified signal to each of the persistent apps */
16767    public void signalPersistentProcesses(int sig) throws RemoteException {
16768        if (sig != Process.SIGNAL_USR1) {
16769            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16770        }
16771
16772        synchronized (this) {
16773            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16774                    != PackageManager.PERMISSION_GRANTED) {
16775                throw new SecurityException("Requires permission "
16776                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16777            }
16778
16779            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16780                ProcessRecord r = mLruProcesses.get(i);
16781                if (r.thread != null && r.persistent) {
16782                    Process.sendSignal(r.pid, sig);
16783                }
16784            }
16785        }
16786    }
16787
16788    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16789        if (proc == null || proc == mProfileProc) {
16790            proc = mProfileProc;
16791            path = mProfileFile;
16792            profileType = mProfileType;
16793            clearProfilerLocked();
16794        }
16795        if (proc == null) {
16796            return;
16797        }
16798        try {
16799            proc.thread.profilerControl(false, path, null, profileType);
16800        } catch (RemoteException e) {
16801            throw new IllegalStateException("Process disappeared");
16802        }
16803    }
16804
16805    private void clearProfilerLocked() {
16806        if (mProfileFd != null) {
16807            try {
16808                mProfileFd.close();
16809            } catch (IOException e) {
16810            }
16811        }
16812        mProfileApp = null;
16813        mProfileProc = null;
16814        mProfileFile = null;
16815        mProfileType = 0;
16816        mAutoStopProfiler = false;
16817    }
16818
16819    public boolean profileControl(String process, int userId, boolean start,
16820            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16821
16822        try {
16823            synchronized (this) {
16824                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16825                // its own permission.
16826                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16827                        != PackageManager.PERMISSION_GRANTED) {
16828                    throw new SecurityException("Requires permission "
16829                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16830                }
16831
16832                if (start && fd == null) {
16833                    throw new IllegalArgumentException("null fd");
16834                }
16835
16836                ProcessRecord proc = null;
16837                if (process != null) {
16838                    proc = findProcessLocked(process, userId, "profileControl");
16839                }
16840
16841                if (start && (proc == null || proc.thread == null)) {
16842                    throw new IllegalArgumentException("Unknown process: " + process);
16843                }
16844
16845                if (start) {
16846                    stopProfilerLocked(null, null, 0);
16847                    setProfileApp(proc.info, proc.processName, path, fd, false);
16848                    mProfileProc = proc;
16849                    mProfileType = profileType;
16850                    try {
16851                        fd = fd.dup();
16852                    } catch (IOException e) {
16853                        fd = null;
16854                    }
16855                    proc.thread.profilerControl(start, path, fd, profileType);
16856                    fd = null;
16857                    mProfileFd = null;
16858                } else {
16859                    stopProfilerLocked(proc, path, profileType);
16860                    if (fd != null) {
16861                        try {
16862                            fd.close();
16863                        } catch (IOException e) {
16864                        }
16865                    }
16866                }
16867
16868                return true;
16869            }
16870        } catch (RemoteException e) {
16871            throw new IllegalStateException("Process disappeared");
16872        } finally {
16873            if (fd != null) {
16874                try {
16875                    fd.close();
16876                } catch (IOException e) {
16877                }
16878            }
16879        }
16880    }
16881
16882    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16883        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16884                userId, true, ALLOW_FULL_ONLY, callName, null);
16885        ProcessRecord proc = null;
16886        try {
16887            int pid = Integer.parseInt(process);
16888            synchronized (mPidsSelfLocked) {
16889                proc = mPidsSelfLocked.get(pid);
16890            }
16891        } catch (NumberFormatException e) {
16892        }
16893
16894        if (proc == null) {
16895            ArrayMap<String, SparseArray<ProcessRecord>> all
16896                    = mProcessNames.getMap();
16897            SparseArray<ProcessRecord> procs = all.get(process);
16898            if (procs != null && procs.size() > 0) {
16899                proc = procs.valueAt(0);
16900                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16901                    for (int i=1; i<procs.size(); i++) {
16902                        ProcessRecord thisProc = procs.valueAt(i);
16903                        if (thisProc.userId == userId) {
16904                            proc = thisProc;
16905                            break;
16906                        }
16907                    }
16908                }
16909            }
16910        }
16911
16912        return proc;
16913    }
16914
16915    public boolean dumpHeap(String process, int userId, boolean managed,
16916            String path, ParcelFileDescriptor fd) throws RemoteException {
16917
16918        try {
16919            synchronized (this) {
16920                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16921                // its own permission (same as profileControl).
16922                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16923                        != PackageManager.PERMISSION_GRANTED) {
16924                    throw new SecurityException("Requires permission "
16925                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16926                }
16927
16928                if (fd == null) {
16929                    throw new IllegalArgumentException("null fd");
16930                }
16931
16932                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16933                if (proc == null || proc.thread == null) {
16934                    throw new IllegalArgumentException("Unknown process: " + process);
16935                }
16936
16937                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16938                if (!isDebuggable) {
16939                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16940                        throw new SecurityException("Process not debuggable: " + proc);
16941                    }
16942                }
16943
16944                proc.thread.dumpHeap(managed, path, fd);
16945                fd = null;
16946                return true;
16947            }
16948        } catch (RemoteException e) {
16949            throw new IllegalStateException("Process disappeared");
16950        } finally {
16951            if (fd != null) {
16952                try {
16953                    fd.close();
16954                } catch (IOException e) {
16955                }
16956            }
16957        }
16958    }
16959
16960    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16961    public void monitor() {
16962        synchronized (this) { }
16963    }
16964
16965    void onCoreSettingsChange(Bundle settings) {
16966        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16967            ProcessRecord processRecord = mLruProcesses.get(i);
16968            try {
16969                if (processRecord.thread != null) {
16970                    processRecord.thread.setCoreSettings(settings);
16971                }
16972            } catch (RemoteException re) {
16973                /* ignore */
16974            }
16975        }
16976    }
16977
16978    // Multi-user methods
16979
16980    /**
16981     * Start user, if its not already running, but don't bring it to foreground.
16982     */
16983    @Override
16984    public boolean startUserInBackground(final int userId) {
16985        return startUser(userId, /* foreground */ false);
16986    }
16987
16988    /**
16989     * Refreshes the list of users related to the current user when either a
16990     * user switch happens or when a new related user is started in the
16991     * background.
16992     */
16993    private void updateCurrentProfileIdsLocked() {
16994        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16995                mCurrentUserId, false /* enabledOnly */);
16996        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16997        for (int i = 0; i < currentProfileIds.length; i++) {
16998            currentProfileIds[i] = profiles.get(i).id;
16999        }
17000        mCurrentProfileIds = currentProfileIds;
17001
17002        synchronized (mUserProfileGroupIdsSelfLocked) {
17003            mUserProfileGroupIdsSelfLocked.clear();
17004            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17005            for (int i = 0; i < users.size(); i++) {
17006                UserInfo user = users.get(i);
17007                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17008                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17009                }
17010            }
17011        }
17012    }
17013
17014    private Set getProfileIdsLocked(int userId) {
17015        Set userIds = new HashSet<Integer>();
17016        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17017                userId, false /* enabledOnly */);
17018        for (UserInfo user : profiles) {
17019            userIds.add(Integer.valueOf(user.id));
17020        }
17021        return userIds;
17022    }
17023
17024    @Override
17025    public boolean switchUser(final int userId) {
17026        return startUser(userId, /* foregound */ true);
17027    }
17028
17029    private boolean startUser(final int userId, boolean foreground) {
17030        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17031                != PackageManager.PERMISSION_GRANTED) {
17032            String msg = "Permission Denial: switchUser() from pid="
17033                    + Binder.getCallingPid()
17034                    + ", uid=" + Binder.getCallingUid()
17035                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17036            Slog.w(TAG, msg);
17037            throw new SecurityException(msg);
17038        }
17039
17040        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17041
17042        final long ident = Binder.clearCallingIdentity();
17043        try {
17044            synchronized (this) {
17045                final int oldUserId = mCurrentUserId;
17046                if (oldUserId == userId) {
17047                    return true;
17048                }
17049
17050                mStackSupervisor.setLockTaskModeLocked(null, false);
17051
17052                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17053                if (userInfo == null) {
17054                    Slog.w(TAG, "No user info for user #" + userId);
17055                    return false;
17056                }
17057
17058                if (foreground) {
17059                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17060                            R.anim.screen_user_enter);
17061                }
17062
17063                boolean needStart = false;
17064
17065                // If the user we are switching to is not currently started, then
17066                // we need to start it now.
17067                if (mStartedUsers.get(userId) == null) {
17068                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17069                    updateStartedUserArrayLocked();
17070                    needStart = true;
17071                }
17072
17073                final Integer userIdInt = Integer.valueOf(userId);
17074                mUserLru.remove(userIdInt);
17075                mUserLru.add(userIdInt);
17076
17077                if (foreground) {
17078                    mCurrentUserId = userId;
17079                    updateCurrentProfileIdsLocked();
17080                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17081                    // Once the internal notion of the active user has switched, we lock the device
17082                    // with the option to show the user switcher on the keyguard.
17083                    mWindowManager.lockNow(null);
17084                } else {
17085                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17086                    updateCurrentProfileIdsLocked();
17087                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17088                    mUserLru.remove(currentUserIdInt);
17089                    mUserLru.add(currentUserIdInt);
17090                }
17091
17092                final UserStartedState uss = mStartedUsers.get(userId);
17093
17094                // Make sure user is in the started state.  If it is currently
17095                // stopping, we need to knock that off.
17096                if (uss.mState == UserStartedState.STATE_STOPPING) {
17097                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17098                    // so we can just fairly silently bring the user back from
17099                    // the almost-dead.
17100                    uss.mState = UserStartedState.STATE_RUNNING;
17101                    updateStartedUserArrayLocked();
17102                    needStart = true;
17103                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17104                    // This means ACTION_SHUTDOWN has been sent, so we will
17105                    // need to treat this as a new boot of the user.
17106                    uss.mState = UserStartedState.STATE_BOOTING;
17107                    updateStartedUserArrayLocked();
17108                    needStart = true;
17109                }
17110
17111                if (uss.mState == UserStartedState.STATE_BOOTING) {
17112                    // Booting up a new user, need to tell system services about it.
17113                    // Note that this is on the same handler as scheduling of broadcasts,
17114                    // which is important because it needs to go first.
17115                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
17116                }
17117
17118                if (foreground) {
17119                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
17120                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17121                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17122                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
17123                            oldUserId, userId, uss));
17124                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
17125                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
17126                }
17127
17128                if (needStart) {
17129                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
17130                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17131                            | Intent.FLAG_RECEIVER_FOREGROUND);
17132                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17133                    broadcastIntentLocked(null, null, intent,
17134                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17135                            false, false, MY_PID, Process.SYSTEM_UID, userId);
17136                }
17137
17138                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
17139                    if (userId != UserHandle.USER_OWNER) {
17140                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
17141                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17142                        broadcastIntentLocked(null, null, intent, null,
17143                                new IIntentReceiver.Stub() {
17144                                    public void performReceive(Intent intent, int resultCode,
17145                                            String data, Bundle extras, boolean ordered,
17146                                            boolean sticky, int sendingUser) {
17147                                        userInitialized(uss, userId);
17148                                    }
17149                                }, 0, null, null, null, AppOpsManager.OP_NONE,
17150                                true, false, MY_PID, Process.SYSTEM_UID,
17151                                userId);
17152                        uss.initializing = true;
17153                    } else {
17154                        getUserManagerLocked().makeInitialized(userInfo.id);
17155                    }
17156                }
17157
17158                if (foreground) {
17159                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
17160                    if (homeInFront) {
17161                        startHomeActivityLocked(userId);
17162                    } else {
17163                        mStackSupervisor.resumeTopActivitiesLocked();
17164                    }
17165                    EventLogTags.writeAmSwitchUser(userId);
17166                    getUserManagerLocked().userForeground(userId);
17167                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
17168                } else {
17169                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
17170                }
17171
17172                if (needStart) {
17173                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
17174                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17175                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17176                    broadcastIntentLocked(null, null, intent,
17177                            null, new IIntentReceiver.Stub() {
17178                                @Override
17179                                public void performReceive(Intent intent, int resultCode, String data,
17180                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
17181                                        throws RemoteException {
17182                                }
17183                            }, 0, null, null,
17184                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17185                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17186                }
17187            }
17188        } finally {
17189            Binder.restoreCallingIdentity(ident);
17190        }
17191
17192        return true;
17193    }
17194
17195    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
17196        long ident = Binder.clearCallingIdentity();
17197        try {
17198            Intent intent;
17199            if (oldUserId >= 0) {
17200                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
17201                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
17202                int count = profiles.size();
17203                for (int i = 0; i < count; i++) {
17204                    int profileUserId = profiles.get(i).id;
17205                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
17206                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17207                            | Intent.FLAG_RECEIVER_FOREGROUND);
17208                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17209                    broadcastIntentLocked(null, null, intent,
17210                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17211                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17212                }
17213            }
17214            if (newUserId >= 0) {
17215                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
17216                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
17217                int count = profiles.size();
17218                for (int i = 0; i < count; i++) {
17219                    int profileUserId = profiles.get(i).id;
17220                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
17221                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17222                            | Intent.FLAG_RECEIVER_FOREGROUND);
17223                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17224                    broadcastIntentLocked(null, null, intent,
17225                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17226                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17227                }
17228                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17229                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17230                        | Intent.FLAG_RECEIVER_FOREGROUND);
17231                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17232                broadcastIntentLocked(null, null, intent,
17233                        null, null, 0, null, null,
17234                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17235                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17236            }
17237        } finally {
17238            Binder.restoreCallingIdentity(ident);
17239        }
17240    }
17241
17242    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17243            final int newUserId) {
17244        final int N = mUserSwitchObservers.beginBroadcast();
17245        if (N > 0) {
17246            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17247                int mCount = 0;
17248                @Override
17249                public void sendResult(Bundle data) throws RemoteException {
17250                    synchronized (ActivityManagerService.this) {
17251                        if (mCurUserSwitchCallback == this) {
17252                            mCount++;
17253                            if (mCount == N) {
17254                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17255                            }
17256                        }
17257                    }
17258                }
17259            };
17260            synchronized (this) {
17261                uss.switching = true;
17262                mCurUserSwitchCallback = callback;
17263            }
17264            for (int i=0; i<N; i++) {
17265                try {
17266                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17267                            newUserId, callback);
17268                } catch (RemoteException e) {
17269                }
17270            }
17271        } else {
17272            synchronized (this) {
17273                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17274            }
17275        }
17276        mUserSwitchObservers.finishBroadcast();
17277    }
17278
17279    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17280        synchronized (this) {
17281            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17282            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17283        }
17284    }
17285
17286    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17287        mCurUserSwitchCallback = null;
17288        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17289        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17290                oldUserId, newUserId, uss));
17291    }
17292
17293    void userInitialized(UserStartedState uss, int newUserId) {
17294        completeSwitchAndInitalize(uss, newUserId, true, false);
17295    }
17296
17297    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17298        completeSwitchAndInitalize(uss, newUserId, false, true);
17299    }
17300
17301    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17302            boolean clearInitializing, boolean clearSwitching) {
17303        boolean unfrozen = false;
17304        synchronized (this) {
17305            if (clearInitializing) {
17306                uss.initializing = false;
17307                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17308            }
17309            if (clearSwitching) {
17310                uss.switching = false;
17311            }
17312            if (!uss.switching && !uss.initializing) {
17313                mWindowManager.stopFreezingScreen();
17314                unfrozen = true;
17315            }
17316        }
17317        if (unfrozen) {
17318            final int N = mUserSwitchObservers.beginBroadcast();
17319            for (int i=0; i<N; i++) {
17320                try {
17321                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17322                } catch (RemoteException e) {
17323                }
17324            }
17325            mUserSwitchObservers.finishBroadcast();
17326        }
17327    }
17328
17329    void scheduleStartProfilesLocked() {
17330        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17331            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17332                    DateUtils.SECOND_IN_MILLIS);
17333        }
17334    }
17335
17336    void startProfilesLocked() {
17337        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17338        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17339                mCurrentUserId, false /* enabledOnly */);
17340        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17341        for (UserInfo user : profiles) {
17342            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17343                    && user.id != mCurrentUserId) {
17344                toStart.add(user);
17345            }
17346        }
17347        final int n = toStart.size();
17348        int i = 0;
17349        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17350            startUserInBackground(toStart.get(i).id);
17351        }
17352        if (i < n) {
17353            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17354        }
17355    }
17356
17357    void finishUserBoot(UserStartedState uss) {
17358        synchronized (this) {
17359            if (uss.mState == UserStartedState.STATE_BOOTING
17360                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17361                uss.mState = UserStartedState.STATE_RUNNING;
17362                final int userId = uss.mHandle.getIdentifier();
17363                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17364                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17365                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17366                broadcastIntentLocked(null, null, intent,
17367                        null, null, 0, null, null,
17368                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17369                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17370            }
17371        }
17372    }
17373
17374    void finishUserSwitch(UserStartedState uss) {
17375        synchronized (this) {
17376            finishUserBoot(uss);
17377
17378            startProfilesLocked();
17379
17380            int num = mUserLru.size();
17381            int i = 0;
17382            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17383                Integer oldUserId = mUserLru.get(i);
17384                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17385                if (oldUss == null) {
17386                    // Shouldn't happen, but be sane if it does.
17387                    mUserLru.remove(i);
17388                    num--;
17389                    continue;
17390                }
17391                if (oldUss.mState == UserStartedState.STATE_STOPPING
17392                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17393                    // This user is already stopping, doesn't count.
17394                    num--;
17395                    i++;
17396                    continue;
17397                }
17398                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17399                    // Owner and current can't be stopped, but count as running.
17400                    i++;
17401                    continue;
17402                }
17403                // This is a user to be stopped.
17404                stopUserLocked(oldUserId, null);
17405                num--;
17406                i++;
17407            }
17408        }
17409    }
17410
17411    @Override
17412    public int stopUser(final int userId, final IStopUserCallback callback) {
17413        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17414                != PackageManager.PERMISSION_GRANTED) {
17415            String msg = "Permission Denial: switchUser() from pid="
17416                    + Binder.getCallingPid()
17417                    + ", uid=" + Binder.getCallingUid()
17418                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17419            Slog.w(TAG, msg);
17420            throw new SecurityException(msg);
17421        }
17422        if (userId <= 0) {
17423            throw new IllegalArgumentException("Can't stop primary user " + userId);
17424        }
17425        synchronized (this) {
17426            return stopUserLocked(userId, callback);
17427        }
17428    }
17429
17430    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17431        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17432        if (mCurrentUserId == userId) {
17433            return ActivityManager.USER_OP_IS_CURRENT;
17434        }
17435
17436        final UserStartedState uss = mStartedUsers.get(userId);
17437        if (uss == null) {
17438            // User is not started, nothing to do...  but we do need to
17439            // callback if requested.
17440            if (callback != null) {
17441                mHandler.post(new Runnable() {
17442                    @Override
17443                    public void run() {
17444                        try {
17445                            callback.userStopped(userId);
17446                        } catch (RemoteException e) {
17447                        }
17448                    }
17449                });
17450            }
17451            return ActivityManager.USER_OP_SUCCESS;
17452        }
17453
17454        if (callback != null) {
17455            uss.mStopCallbacks.add(callback);
17456        }
17457
17458        if (uss.mState != UserStartedState.STATE_STOPPING
17459                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17460            uss.mState = UserStartedState.STATE_STOPPING;
17461            updateStartedUserArrayLocked();
17462
17463            long ident = Binder.clearCallingIdentity();
17464            try {
17465                // We are going to broadcast ACTION_USER_STOPPING and then
17466                // once that is done send a final ACTION_SHUTDOWN and then
17467                // stop the user.
17468                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17469                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17470                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17471                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17472                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17473                // This is the result receiver for the final shutdown broadcast.
17474                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17475                    @Override
17476                    public void performReceive(Intent intent, int resultCode, String data,
17477                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17478                        finishUserStop(uss);
17479                    }
17480                };
17481                // This is the result receiver for the initial stopping broadcast.
17482                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17483                    @Override
17484                    public void performReceive(Intent intent, int resultCode, String data,
17485                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17486                        // On to the next.
17487                        synchronized (ActivityManagerService.this) {
17488                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17489                                // Whoops, we are being started back up.  Abort, abort!
17490                                return;
17491                            }
17492                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17493                        }
17494                        mSystemServiceManager.stopUser(userId);
17495                        broadcastIntentLocked(null, null, shutdownIntent,
17496                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17497                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17498                    }
17499                };
17500                // Kick things off.
17501                broadcastIntentLocked(null, null, stoppingIntent,
17502                        null, stoppingReceiver, 0, null, null,
17503                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17504                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17505            } finally {
17506                Binder.restoreCallingIdentity(ident);
17507            }
17508        }
17509
17510        return ActivityManager.USER_OP_SUCCESS;
17511    }
17512
17513    void finishUserStop(UserStartedState uss) {
17514        final int userId = uss.mHandle.getIdentifier();
17515        boolean stopped;
17516        ArrayList<IStopUserCallback> callbacks;
17517        synchronized (this) {
17518            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17519            if (mStartedUsers.get(userId) != uss) {
17520                stopped = false;
17521            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17522                stopped = false;
17523            } else {
17524                stopped = true;
17525                // User can no longer run.
17526                mStartedUsers.remove(userId);
17527                mUserLru.remove(Integer.valueOf(userId));
17528                updateStartedUserArrayLocked();
17529
17530                // Clean up all state and processes associated with the user.
17531                // Kill all the processes for the user.
17532                forceStopUserLocked(userId, "finish user");
17533            }
17534        }
17535
17536        for (int i=0; i<callbacks.size(); i++) {
17537            try {
17538                if (stopped) callbacks.get(i).userStopped(userId);
17539                else callbacks.get(i).userStopAborted(userId);
17540            } catch (RemoteException e) {
17541            }
17542        }
17543
17544        if (stopped) {
17545            mSystemServiceManager.cleanupUser(userId);
17546            synchronized (this) {
17547                mStackSupervisor.removeUserLocked(userId);
17548            }
17549        }
17550    }
17551
17552    @Override
17553    public UserInfo getCurrentUser() {
17554        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
17555                != PackageManager.PERMISSION_GRANTED) && (
17556                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17557                != PackageManager.PERMISSION_GRANTED)) {
17558            String msg = "Permission Denial: getCurrentUser() from pid="
17559                    + Binder.getCallingPid()
17560                    + ", uid=" + Binder.getCallingUid()
17561                    + " requires " + INTERACT_ACROSS_USERS;
17562            Slog.w(TAG, msg);
17563            throw new SecurityException(msg);
17564        }
17565        synchronized (this) {
17566            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17567        }
17568    }
17569
17570    int getCurrentUserIdLocked() {
17571        return mCurrentUserId;
17572    }
17573
17574    @Override
17575    public boolean isUserRunning(int userId, boolean orStopped) {
17576        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17577                != PackageManager.PERMISSION_GRANTED) {
17578            String msg = "Permission Denial: isUserRunning() from pid="
17579                    + Binder.getCallingPid()
17580                    + ", uid=" + Binder.getCallingUid()
17581                    + " requires " + INTERACT_ACROSS_USERS;
17582            Slog.w(TAG, msg);
17583            throw new SecurityException(msg);
17584        }
17585        synchronized (this) {
17586            return isUserRunningLocked(userId, orStopped);
17587        }
17588    }
17589
17590    boolean isUserRunningLocked(int userId, boolean orStopped) {
17591        UserStartedState state = mStartedUsers.get(userId);
17592        if (state == null) {
17593            return false;
17594        }
17595        if (orStopped) {
17596            return true;
17597        }
17598        return state.mState != UserStartedState.STATE_STOPPING
17599                && state.mState != UserStartedState.STATE_SHUTDOWN;
17600    }
17601
17602    @Override
17603    public int[] getRunningUserIds() {
17604        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17605                != PackageManager.PERMISSION_GRANTED) {
17606            String msg = "Permission Denial: isUserRunning() from pid="
17607                    + Binder.getCallingPid()
17608                    + ", uid=" + Binder.getCallingUid()
17609                    + " requires " + INTERACT_ACROSS_USERS;
17610            Slog.w(TAG, msg);
17611            throw new SecurityException(msg);
17612        }
17613        synchronized (this) {
17614            return mStartedUserArray;
17615        }
17616    }
17617
17618    private void updateStartedUserArrayLocked() {
17619        int num = 0;
17620        for (int i=0; i<mStartedUsers.size();  i++) {
17621            UserStartedState uss = mStartedUsers.valueAt(i);
17622            // This list does not include stopping users.
17623            if (uss.mState != UserStartedState.STATE_STOPPING
17624                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17625                num++;
17626            }
17627        }
17628        mStartedUserArray = new int[num];
17629        num = 0;
17630        for (int i=0; i<mStartedUsers.size();  i++) {
17631            UserStartedState uss = mStartedUsers.valueAt(i);
17632            if (uss.mState != UserStartedState.STATE_STOPPING
17633                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17634                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17635                num++;
17636            }
17637        }
17638    }
17639
17640    @Override
17641    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17642        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17643                != PackageManager.PERMISSION_GRANTED) {
17644            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17645                    + Binder.getCallingPid()
17646                    + ", uid=" + Binder.getCallingUid()
17647                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17648            Slog.w(TAG, msg);
17649            throw new SecurityException(msg);
17650        }
17651
17652        mUserSwitchObservers.register(observer);
17653    }
17654
17655    @Override
17656    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17657        mUserSwitchObservers.unregister(observer);
17658    }
17659
17660    private boolean userExists(int userId) {
17661        if (userId == 0) {
17662            return true;
17663        }
17664        UserManagerService ums = getUserManagerLocked();
17665        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17666    }
17667
17668    int[] getUsersLocked() {
17669        UserManagerService ums = getUserManagerLocked();
17670        return ums != null ? ums.getUserIds() : new int[] { 0 };
17671    }
17672
17673    UserManagerService getUserManagerLocked() {
17674        if (mUserManager == null) {
17675            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17676            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17677        }
17678        return mUserManager;
17679    }
17680
17681    private int applyUserId(int uid, int userId) {
17682        return UserHandle.getUid(userId, uid);
17683    }
17684
17685    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17686        if (info == null) return null;
17687        ApplicationInfo newInfo = new ApplicationInfo(info);
17688        newInfo.uid = applyUserId(info.uid, userId);
17689        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17690                + info.packageName;
17691        return newInfo;
17692    }
17693
17694    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17695        if (aInfo == null
17696                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17697            return aInfo;
17698        }
17699
17700        ActivityInfo info = new ActivityInfo(aInfo);
17701        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17702        return info;
17703    }
17704
17705    private final class LocalService extends ActivityManagerInternal {
17706        @Override
17707        public void goingToSleep() {
17708            ActivityManagerService.this.goingToSleep();
17709        }
17710
17711        @Override
17712        public void wakingUp() {
17713            ActivityManagerService.this.wakingUp();
17714        }
17715    }
17716
17717    /**
17718     * An implementation of IAppTask, that allows an app to manage its own tasks via
17719     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17720     * only the process that calls getAppTasks() can call the AppTask methods.
17721     */
17722    class AppTaskImpl extends IAppTask.Stub {
17723        private int mTaskId;
17724        private int mCallingUid;
17725
17726        public AppTaskImpl(int taskId, int callingUid) {
17727            mTaskId = taskId;
17728            mCallingUid = callingUid;
17729        }
17730
17731        @Override
17732        public void finishAndRemoveTask() {
17733            // Ensure that we are called from the same process that created this AppTask
17734            if (mCallingUid != Binder.getCallingUid()) {
17735                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17736                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17737                return;
17738            }
17739
17740            synchronized (ActivityManagerService.this) {
17741                long origId = Binder.clearCallingIdentity();
17742                try {
17743                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17744                    if (tr != null) {
17745                        // Only kill the process if we are not a new document
17746                        int flags = tr.getBaseIntent().getFlags();
17747                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17748                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17749                        removeTaskByIdLocked(mTaskId,
17750                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17751                    }
17752                } finally {
17753                    Binder.restoreCallingIdentity(origId);
17754                }
17755            }
17756        }
17757
17758        @Override
17759        public ActivityManager.RecentTaskInfo getTaskInfo() {
17760            // Ensure that we are called from the same process that created this AppTask
17761            if (mCallingUid != Binder.getCallingUid()) {
17762                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17763                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17764                return null;
17765            }
17766
17767            synchronized (ActivityManagerService.this) {
17768                long origId = Binder.clearCallingIdentity();
17769                try {
17770                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17771                    if (tr != null) {
17772                        return createRecentTaskInfoFromTaskRecord(tr);
17773                    }
17774                } finally {
17775                    Binder.restoreCallingIdentity(origId);
17776                }
17777                return null;
17778            }
17779        }
17780    }
17781}
17782