ActivityManagerService.java revision ebf1fd99d67875c36c7dcd09b2246b6c3e22e9ae
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    /** Flag whether the device has a recents UI */
1193    final boolean mHasRecents;
1194
1195    final ServiceThread mHandlerThread;
1196    final MainHandler mHandler;
1197
1198    final class MainHandler extends Handler {
1199        public MainHandler(Looper looper) {
1200            super(looper, null, true);
1201        }
1202
1203        @Override
1204        public void handleMessage(Message msg) {
1205            switch (msg.what) {
1206            case SHOW_ERROR_MSG: {
1207                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1208                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1209                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1210                synchronized (ActivityManagerService.this) {
1211                    ProcessRecord proc = (ProcessRecord)data.get("app");
1212                    AppErrorResult res = (AppErrorResult) data.get("result");
1213                    if (proc != null && proc.crashDialog != null) {
1214                        Slog.e(TAG, "App already has crash dialog: " + proc);
1215                        if (res != null) {
1216                            res.set(0);
1217                        }
1218                        return;
1219                    }
1220                    if (!showBackground && UserHandle.getAppId(proc.uid)
1221                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1222                            && proc.pid != MY_PID) {
1223                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1224                        if (res != null) {
1225                            res.set(0);
1226                        }
1227                        return;
1228                    }
1229                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1230                        Dialog d = new AppErrorDialog(mContext,
1231                                ActivityManagerService.this, res, proc);
1232                        d.show();
1233                        proc.crashDialog = d;
1234                    } else {
1235                        // The device is asleep, so just pretend that the user
1236                        // saw a crash dialog and hit "force quit".
1237                        if (res != null) {
1238                            res.set(0);
1239                        }
1240                    }
1241                }
1242
1243                ensureBootCompleted();
1244            } break;
1245            case SHOW_NOT_RESPONDING_MSG: {
1246                synchronized (ActivityManagerService.this) {
1247                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1248                    ProcessRecord proc = (ProcessRecord)data.get("app");
1249                    if (proc != null && proc.anrDialog != null) {
1250                        Slog.e(TAG, "App already has anr dialog: " + proc);
1251                        return;
1252                    }
1253
1254                    Intent intent = new Intent("android.intent.action.ANR");
1255                    if (!mProcessesReady) {
1256                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1257                                | Intent.FLAG_RECEIVER_FOREGROUND);
1258                    }
1259                    broadcastIntentLocked(null, null, intent,
1260                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1261                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1262
1263                    if (mShowDialogs) {
1264                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1265                                mContext, proc, (ActivityRecord)data.get("activity"),
1266                                msg.arg1 != 0);
1267                        d.show();
1268                        proc.anrDialog = d;
1269                    } else {
1270                        // Just kill the app if there is no dialog to be shown.
1271                        killAppAtUsersRequest(proc, null);
1272                    }
1273                }
1274
1275                ensureBootCompleted();
1276            } break;
1277            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1278                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1279                synchronized (ActivityManagerService.this) {
1280                    ProcessRecord proc = (ProcessRecord) data.get("app");
1281                    if (proc == null) {
1282                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1283                        break;
1284                    }
1285                    if (proc.crashDialog != null) {
1286                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1287                        return;
1288                    }
1289                    AppErrorResult res = (AppErrorResult) data.get("result");
1290                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1291                        Dialog d = new StrictModeViolationDialog(mContext,
1292                                ActivityManagerService.this, res, proc);
1293                        d.show();
1294                        proc.crashDialog = d;
1295                    } else {
1296                        // The device is asleep, so just pretend that the user
1297                        // saw a crash dialog and hit "force quit".
1298                        res.set(0);
1299                    }
1300                }
1301                ensureBootCompleted();
1302            } break;
1303            case SHOW_FACTORY_ERROR_MSG: {
1304                Dialog d = new FactoryErrorDialog(
1305                    mContext, msg.getData().getCharSequence("msg"));
1306                d.show();
1307                ensureBootCompleted();
1308            } break;
1309            case UPDATE_CONFIGURATION_MSG: {
1310                final ContentResolver resolver = mContext.getContentResolver();
1311                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1312            } break;
1313            case GC_BACKGROUND_PROCESSES_MSG: {
1314                synchronized (ActivityManagerService.this) {
1315                    performAppGcsIfAppropriateLocked();
1316                }
1317            } break;
1318            case WAIT_FOR_DEBUGGER_MSG: {
1319                synchronized (ActivityManagerService.this) {
1320                    ProcessRecord app = (ProcessRecord)msg.obj;
1321                    if (msg.arg1 != 0) {
1322                        if (!app.waitedForDebugger) {
1323                            Dialog d = new AppWaitingForDebuggerDialog(
1324                                    ActivityManagerService.this,
1325                                    mContext, app);
1326                            app.waitDialog = d;
1327                            app.waitedForDebugger = true;
1328                            d.show();
1329                        }
1330                    } else {
1331                        if (app.waitDialog != null) {
1332                            app.waitDialog.dismiss();
1333                            app.waitDialog = null;
1334                        }
1335                    }
1336                }
1337            } break;
1338            case SERVICE_TIMEOUT_MSG: {
1339                if (mDidDexOpt) {
1340                    mDidDexOpt = false;
1341                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1342                    nmsg.obj = msg.obj;
1343                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1344                    return;
1345                }
1346                mServices.serviceTimeout((ProcessRecord)msg.obj);
1347            } break;
1348            case UPDATE_TIME_ZONE: {
1349                synchronized (ActivityManagerService.this) {
1350                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1351                        ProcessRecord r = mLruProcesses.get(i);
1352                        if (r.thread != null) {
1353                            try {
1354                                r.thread.updateTimeZone();
1355                            } catch (RemoteException ex) {
1356                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1357                            }
1358                        }
1359                    }
1360                }
1361            } break;
1362            case CLEAR_DNS_CACHE_MSG: {
1363                synchronized (ActivityManagerService.this) {
1364                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1365                        ProcessRecord r = mLruProcesses.get(i);
1366                        if (r.thread != null) {
1367                            try {
1368                                r.thread.clearDnsCache();
1369                            } catch (RemoteException ex) {
1370                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1371                            }
1372                        }
1373                    }
1374                }
1375            } break;
1376            case UPDATE_HTTP_PROXY_MSG: {
1377                ProxyInfo proxy = (ProxyInfo)msg.obj;
1378                String host = "";
1379                String port = "";
1380                String exclList = "";
1381                Uri pacFileUrl = Uri.EMPTY;
1382                if (proxy != null) {
1383                    host = proxy.getHost();
1384                    port = Integer.toString(proxy.getPort());
1385                    exclList = proxy.getExclusionListAsString();
1386                    pacFileUrl = proxy.getPacFileUrl();
1387                }
1388                synchronized (ActivityManagerService.this) {
1389                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1390                        ProcessRecord r = mLruProcesses.get(i);
1391                        if (r.thread != null) {
1392                            try {
1393                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1394                            } catch (RemoteException ex) {
1395                                Slog.w(TAG, "Failed to update http proxy for: " +
1396                                        r.info.processName);
1397                            }
1398                        }
1399                    }
1400                }
1401            } break;
1402            case SHOW_UID_ERROR_MSG: {
1403                String title = "System UIDs Inconsistent";
1404                String text = "UIDs on the system are inconsistent, you need to wipe your"
1405                        + " data partition or your device will be unstable.";
1406                Log.e(TAG, title + ": " + text);
1407                if (mShowDialogs) {
1408                    // XXX This is a temporary dialog, no need to localize.
1409                    AlertDialog d = new BaseErrorDialog(mContext);
1410                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1411                    d.setCancelable(false);
1412                    d.setTitle(title);
1413                    d.setMessage(text);
1414                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1415                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1416                    mUidAlert = d;
1417                    d.show();
1418                }
1419            } break;
1420            case IM_FEELING_LUCKY_MSG: {
1421                if (mUidAlert != null) {
1422                    mUidAlert.dismiss();
1423                    mUidAlert = null;
1424                }
1425            } break;
1426            case PROC_START_TIMEOUT_MSG: {
1427                if (mDidDexOpt) {
1428                    mDidDexOpt = false;
1429                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1430                    nmsg.obj = msg.obj;
1431                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1432                    return;
1433                }
1434                ProcessRecord app = (ProcessRecord)msg.obj;
1435                synchronized (ActivityManagerService.this) {
1436                    processStartTimedOutLocked(app);
1437                }
1438            } break;
1439            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1440                synchronized (ActivityManagerService.this) {
1441                    doPendingActivityLaunchesLocked(true);
1442                }
1443            } break;
1444            case KILL_APPLICATION_MSG: {
1445                synchronized (ActivityManagerService.this) {
1446                    int appid = msg.arg1;
1447                    boolean restart = (msg.arg2 == 1);
1448                    Bundle bundle = (Bundle)msg.obj;
1449                    String pkg = bundle.getString("pkg");
1450                    String reason = bundle.getString("reason");
1451                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1452                            false, UserHandle.USER_ALL, reason);
1453                }
1454            } break;
1455            case FINALIZE_PENDING_INTENT_MSG: {
1456                ((PendingIntentRecord)msg.obj).completeFinalize();
1457            } break;
1458            case POST_HEAVY_NOTIFICATION_MSG: {
1459                INotificationManager inm = NotificationManager.getService();
1460                if (inm == null) {
1461                    return;
1462                }
1463
1464                ActivityRecord root = (ActivityRecord)msg.obj;
1465                ProcessRecord process = root.app;
1466                if (process == null) {
1467                    return;
1468                }
1469
1470                try {
1471                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1472                    String text = mContext.getString(R.string.heavy_weight_notification,
1473                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1474                    Notification notification = new Notification();
1475                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1476                    notification.when = 0;
1477                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1478                    notification.tickerText = text;
1479                    notification.defaults = 0; // please be quiet
1480                    notification.sound = null;
1481                    notification.vibrate = null;
1482                    notification.setLatestEventInfo(context, text,
1483                            mContext.getText(R.string.heavy_weight_notification_detail),
1484                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1485                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1486                                    new UserHandle(root.userId)));
1487
1488                    try {
1489                        int[] outId = new int[1];
1490                        inm.enqueueNotificationWithTag("android", "android", null,
1491                                R.string.heavy_weight_notification,
1492                                notification, outId, root.userId);
1493                    } catch (RuntimeException e) {
1494                        Slog.w(ActivityManagerService.TAG,
1495                                "Error showing notification for heavy-weight app", e);
1496                    } catch (RemoteException e) {
1497                    }
1498                } catch (NameNotFoundException e) {
1499                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1500                }
1501            } break;
1502            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1503                INotificationManager inm = NotificationManager.getService();
1504                if (inm == null) {
1505                    return;
1506                }
1507                try {
1508                    inm.cancelNotificationWithTag("android", null,
1509                            R.string.heavy_weight_notification,  msg.arg1);
1510                } catch (RuntimeException e) {
1511                    Slog.w(ActivityManagerService.TAG,
1512                            "Error canceling notification for service", e);
1513                } catch (RemoteException e) {
1514                }
1515            } break;
1516            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1517                synchronized (ActivityManagerService.this) {
1518                    checkExcessivePowerUsageLocked(true);
1519                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1520                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1521                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1522                }
1523            } break;
1524            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1525                synchronized (ActivityManagerService.this) {
1526                    ActivityRecord ar = (ActivityRecord)msg.obj;
1527                    if (mCompatModeDialog != null) {
1528                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1529                                ar.info.applicationInfo.packageName)) {
1530                            return;
1531                        }
1532                        mCompatModeDialog.dismiss();
1533                        mCompatModeDialog = null;
1534                    }
1535                    if (ar != null && false) {
1536                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1537                                ar.packageName)) {
1538                            int mode = mCompatModePackages.computeCompatModeLocked(
1539                                    ar.info.applicationInfo);
1540                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1541                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1542                                mCompatModeDialog = new CompatModeDialog(
1543                                        ActivityManagerService.this, mContext,
1544                                        ar.info.applicationInfo);
1545                                mCompatModeDialog.show();
1546                            }
1547                        }
1548                    }
1549                }
1550                break;
1551            }
1552            case DISPATCH_PROCESSES_CHANGED: {
1553                dispatchProcessesChanged();
1554                break;
1555            }
1556            case DISPATCH_PROCESS_DIED: {
1557                final int pid = msg.arg1;
1558                final int uid = msg.arg2;
1559                dispatchProcessDied(pid, uid);
1560                break;
1561            }
1562            case REPORT_MEM_USAGE_MSG: {
1563                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1564                Thread thread = new Thread() {
1565                    @Override public void run() {
1566                        final SparseArray<ProcessMemInfo> infoMap
1567                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1568                        for (int i=0, N=memInfos.size(); i<N; i++) {
1569                            ProcessMemInfo mi = memInfos.get(i);
1570                            infoMap.put(mi.pid, mi);
1571                        }
1572                        updateCpuStatsNow();
1573                        synchronized (mProcessCpuThread) {
1574                            final int N = mProcessCpuTracker.countStats();
1575                            for (int i=0; i<N; i++) {
1576                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1577                                if (st.vsize > 0) {
1578                                    long pss = Debug.getPss(st.pid, null);
1579                                    if (pss > 0) {
1580                                        if (infoMap.indexOfKey(st.pid) < 0) {
1581                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1582                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1583                                            mi.pss = pss;
1584                                            memInfos.add(mi);
1585                                        }
1586                                    }
1587                                }
1588                            }
1589                        }
1590
1591                        long totalPss = 0;
1592                        for (int i=0, N=memInfos.size(); i<N; i++) {
1593                            ProcessMemInfo mi = memInfos.get(i);
1594                            if (mi.pss == 0) {
1595                                mi.pss = Debug.getPss(mi.pid, null);
1596                            }
1597                            totalPss += mi.pss;
1598                        }
1599                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1600                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1601                                if (lhs.oomAdj != rhs.oomAdj) {
1602                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1603                                }
1604                                if (lhs.pss != rhs.pss) {
1605                                    return lhs.pss < rhs.pss ? 1 : -1;
1606                                }
1607                                return 0;
1608                            }
1609                        });
1610
1611                        StringBuilder tag = new StringBuilder(128);
1612                        StringBuilder stack = new StringBuilder(128);
1613                        tag.append("Low on memory -- ");
1614                        appendMemBucket(tag, totalPss, "total", false);
1615                        appendMemBucket(stack, totalPss, "total", true);
1616
1617                        StringBuilder logBuilder = new StringBuilder(1024);
1618                        logBuilder.append("Low on memory:\n");
1619
1620                        boolean firstLine = true;
1621                        int lastOomAdj = Integer.MIN_VALUE;
1622                        for (int i=0, N=memInfos.size(); i<N; i++) {
1623                            ProcessMemInfo mi = memInfos.get(i);
1624
1625                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1626                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1627                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1628                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1629                                if (lastOomAdj != mi.oomAdj) {
1630                                    lastOomAdj = mi.oomAdj;
1631                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1632                                        tag.append(" / ");
1633                                    }
1634                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1635                                        if (firstLine) {
1636                                            stack.append(":");
1637                                            firstLine = false;
1638                                        }
1639                                        stack.append("\n\t at ");
1640                                    } else {
1641                                        stack.append("$");
1642                                    }
1643                                } else {
1644                                    tag.append(" ");
1645                                    stack.append("$");
1646                                }
1647                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1648                                    appendMemBucket(tag, mi.pss, mi.name, false);
1649                                }
1650                                appendMemBucket(stack, mi.pss, mi.name, true);
1651                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1652                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1653                                    stack.append("(");
1654                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1655                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1656                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1657                                            stack.append(":");
1658                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1659                                        }
1660                                    }
1661                                    stack.append(")");
1662                                }
1663                            }
1664
1665                            logBuilder.append("  ");
1666                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1667                            logBuilder.append(' ');
1668                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1669                            logBuilder.append(' ');
1670                            ProcessList.appendRamKb(logBuilder, mi.pss);
1671                            logBuilder.append(" kB: ");
1672                            logBuilder.append(mi.name);
1673                            logBuilder.append(" (");
1674                            logBuilder.append(mi.pid);
1675                            logBuilder.append(") ");
1676                            logBuilder.append(mi.adjType);
1677                            logBuilder.append('\n');
1678                            if (mi.adjReason != null) {
1679                                logBuilder.append("                      ");
1680                                logBuilder.append(mi.adjReason);
1681                                logBuilder.append('\n');
1682                            }
1683                        }
1684
1685                        logBuilder.append("           ");
1686                        ProcessList.appendRamKb(logBuilder, totalPss);
1687                        logBuilder.append(" kB: TOTAL\n");
1688
1689                        long[] infos = new long[Debug.MEMINFO_COUNT];
1690                        Debug.getMemInfo(infos);
1691                        logBuilder.append("  MemInfo: ");
1692                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1693                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1694                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1695                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1696                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1697                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1698                            logBuilder.append("  ZRAM: ");
1699                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1700                            logBuilder.append(" kB RAM, ");
1701                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1702                            logBuilder.append(" kB swap total, ");
1703                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1704                            logBuilder.append(" kB swap free\n");
1705                        }
1706                        Slog.i(TAG, logBuilder.toString());
1707
1708                        StringBuilder dropBuilder = new StringBuilder(1024);
1709                        /*
1710                        StringWriter oomSw = new StringWriter();
1711                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1712                        StringWriter catSw = new StringWriter();
1713                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1714                        String[] emptyArgs = new String[] { };
1715                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1716                        oomPw.flush();
1717                        String oomString = oomSw.toString();
1718                        */
1719                        dropBuilder.append(stack);
1720                        dropBuilder.append('\n');
1721                        dropBuilder.append('\n');
1722                        dropBuilder.append(logBuilder);
1723                        dropBuilder.append('\n');
1724                        /*
1725                        dropBuilder.append(oomString);
1726                        dropBuilder.append('\n');
1727                        */
1728                        StringWriter catSw = new StringWriter();
1729                        synchronized (ActivityManagerService.this) {
1730                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1731                            String[] emptyArgs = new String[] { };
1732                            catPw.println();
1733                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1734                            catPw.println();
1735                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1736                                    false, false, null);
1737                            catPw.println();
1738                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1739                            catPw.flush();
1740                        }
1741                        dropBuilder.append(catSw.toString());
1742                        addErrorToDropBox("lowmem", null, "system_server", null,
1743                                null, tag.toString(), dropBuilder.toString(), null, null);
1744                        //Slog.i(TAG, "Sent to dropbox:");
1745                        //Slog.i(TAG, dropBuilder.toString());
1746                        synchronized (ActivityManagerService.this) {
1747                            long now = SystemClock.uptimeMillis();
1748                            if (mLastMemUsageReportTime < now) {
1749                                mLastMemUsageReportTime = now;
1750                            }
1751                        }
1752                    }
1753                };
1754                thread.start();
1755                break;
1756            }
1757            case REPORT_USER_SWITCH_MSG: {
1758                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1759                break;
1760            }
1761            case CONTINUE_USER_SWITCH_MSG: {
1762                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1763                break;
1764            }
1765            case USER_SWITCH_TIMEOUT_MSG: {
1766                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1767                break;
1768            }
1769            case IMMERSIVE_MODE_LOCK_MSG: {
1770                final boolean nextState = (msg.arg1 != 0);
1771                if (mUpdateLock.isHeld() != nextState) {
1772                    if (DEBUG_IMMERSIVE) {
1773                        final ActivityRecord r = (ActivityRecord) msg.obj;
1774                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1775                    }
1776                    if (nextState) {
1777                        mUpdateLock.acquire();
1778                    } else {
1779                        mUpdateLock.release();
1780                    }
1781                }
1782                break;
1783            }
1784            case PERSIST_URI_GRANTS_MSG: {
1785                writeGrantedUriPermissions();
1786                break;
1787            }
1788            case REQUEST_ALL_PSS_MSG: {
1789                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1790                break;
1791            }
1792            case START_PROFILES_MSG: {
1793                synchronized (ActivityManagerService.this) {
1794                    startProfilesLocked();
1795                }
1796                break;
1797            }
1798            case UPDATE_TIME: {
1799                synchronized (ActivityManagerService.this) {
1800                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1801                        ProcessRecord r = mLruProcesses.get(i);
1802                        if (r.thread != null) {
1803                            try {
1804                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1805                            } catch (RemoteException ex) {
1806                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1807                            }
1808                        }
1809                    }
1810                }
1811                break;
1812            }
1813            case SYSTEM_USER_START_MSG: {
1814                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1815                        Integer.toString(msg.arg1), msg.arg1);
1816                mSystemServiceManager.startUser(msg.arg1);
1817                break;
1818            }
1819            case SYSTEM_USER_CURRENT_MSG: {
1820                mBatteryStatsService.noteEvent(
1821                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1822                        Integer.toString(msg.arg2), msg.arg2);
1823                mBatteryStatsService.noteEvent(
1824                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1825                        Integer.toString(msg.arg1), msg.arg1);
1826                mSystemServiceManager.switchUser(msg.arg1);
1827                break;
1828            }
1829            }
1830        }
1831    };
1832
1833    static final int COLLECT_PSS_BG_MSG = 1;
1834
1835    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1836        @Override
1837        public void handleMessage(Message msg) {
1838            switch (msg.what) {
1839            case COLLECT_PSS_BG_MSG: {
1840                long start = SystemClock.uptimeMillis();
1841                MemInfoReader memInfo = null;
1842                synchronized (ActivityManagerService.this) {
1843                    if (mFullPssPending) {
1844                        mFullPssPending = false;
1845                        memInfo = new MemInfoReader();
1846                    }
1847                }
1848                if (memInfo != null) {
1849                    updateCpuStatsNow();
1850                    long nativeTotalPss = 0;
1851                    synchronized (mProcessCpuThread) {
1852                        final int N = mProcessCpuTracker.countStats();
1853                        for (int j=0; j<N; j++) {
1854                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1855                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1856                                // This is definitely an application process; skip it.
1857                                continue;
1858                            }
1859                            synchronized (mPidsSelfLocked) {
1860                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1861                                    // This is one of our own processes; skip it.
1862                                    continue;
1863                                }
1864                            }
1865                            nativeTotalPss += Debug.getPss(st.pid, null);
1866                        }
1867                    }
1868                    memInfo.readMemInfo();
1869                    synchronized (this) {
1870                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1871                                + (SystemClock.uptimeMillis()-start) + "ms");
1872                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1873                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1874                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1875                                        +memInfo.getSlabSizeKb(),
1876                                nativeTotalPss);
1877                    }
1878                }
1879
1880                int i=0, num=0;
1881                long[] tmp = new long[1];
1882                do {
1883                    ProcessRecord proc;
1884                    int procState;
1885                    int pid;
1886                    synchronized (ActivityManagerService.this) {
1887                        if (i >= mPendingPssProcesses.size()) {
1888                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1889                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1890                            mPendingPssProcesses.clear();
1891                            return;
1892                        }
1893                        proc = mPendingPssProcesses.get(i);
1894                        procState = proc.pssProcState;
1895                        if (proc.thread != null && procState == proc.setProcState) {
1896                            pid = proc.pid;
1897                        } else {
1898                            proc = null;
1899                            pid = 0;
1900                        }
1901                        i++;
1902                    }
1903                    if (proc != null) {
1904                        long pss = Debug.getPss(pid, tmp);
1905                        synchronized (ActivityManagerService.this) {
1906                            if (proc.thread != null && proc.setProcState == procState
1907                                    && proc.pid == pid) {
1908                                num++;
1909                                proc.lastPssTime = SystemClock.uptimeMillis();
1910                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1911                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1912                                        + ": " + pss + " lastPss=" + proc.lastPss
1913                                        + " state=" + ProcessList.makeProcStateString(procState));
1914                                if (proc.initialIdlePss == 0) {
1915                                    proc.initialIdlePss = pss;
1916                                }
1917                                proc.lastPss = pss;
1918                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1919                                    proc.lastCachedPss = pss;
1920                                }
1921                            }
1922                        }
1923                    }
1924                } while (true);
1925            }
1926            }
1927        }
1928    };
1929
1930    /**
1931     * Monitor for package changes and update our internal state.
1932     */
1933    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1934        @Override
1935        public void onPackageRemoved(String packageName, int uid) {
1936            // Remove all tasks with activities in the specified package from the list of recent tasks
1937            synchronized (ActivityManagerService.this) {
1938                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1939                    TaskRecord tr = mRecentTasks.get(i);
1940                    ComponentName cn = tr.intent.getComponent();
1941                    if (cn != null && cn.getPackageName().equals(packageName)) {
1942                        // If the package name matches, remove the task and kill the process
1943                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1944                    }
1945                }
1946            }
1947        }
1948
1949        @Override
1950        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1951            onPackageModified(packageName);
1952            return true;
1953        }
1954
1955        @Override
1956        public void onPackageModified(String packageName) {
1957            final PackageManager pm = mContext.getPackageManager();
1958            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1959                    new ArrayList<Pair<Intent, Integer>>();
1960            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1961            // Copy the list of recent tasks so that we don't hold onto the lock on
1962            // ActivityManagerService for long periods while checking if components exist.
1963            synchronized (ActivityManagerService.this) {
1964                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1965                    TaskRecord tr = mRecentTasks.get(i);
1966                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1967                }
1968            }
1969            // Check the recent tasks and filter out all tasks with components that no longer exist.
1970            Intent tmpI = new Intent();
1971            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1972                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1973                ComponentName cn = p.first.getComponent();
1974                if (cn != null && cn.getPackageName().equals(packageName)) {
1975                    try {
1976                        // Add the task to the list to remove if the component no longer exists
1977                        tmpI.setComponent(cn);
1978                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1979                            tasksToRemove.add(p.second);
1980                        }
1981                    } catch (Exception e) {}
1982                }
1983            }
1984            // Prune all the tasks with removed components from the list of recent tasks
1985            synchronized (ActivityManagerService.this) {
1986                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1987                    // Remove the task but don't kill the process (since other components in that
1988                    // package may still be running and in the background)
1989                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1990                }
1991            }
1992        }
1993
1994        @Override
1995        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1996            // Force stop the specified packages
1997            if (packages != null) {
1998                for (String pkg : packages) {
1999                    synchronized (ActivityManagerService.this) {
2000                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2001                                "finished booting")) {
2002                            return true;
2003                        }
2004                    }
2005                }
2006            }
2007            return false;
2008        }
2009    };
2010
2011    public void setSystemProcess() {
2012        try {
2013            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2014            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2015            ServiceManager.addService("meminfo", new MemBinder(this));
2016            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2017            ServiceManager.addService("dbinfo", new DbBinder(this));
2018            if (MONITOR_CPU_USAGE) {
2019                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2020            }
2021            ServiceManager.addService("permission", new PermissionController(this));
2022
2023            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2024                    "android", STOCK_PM_FLAGS);
2025            mSystemThread.installSystemApplicationInfo(info);
2026
2027            synchronized (this) {
2028                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
2029                app.persistent = true;
2030                app.pid = MY_PID;
2031                app.maxAdj = ProcessList.SYSTEM_ADJ;
2032                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2033                mProcessNames.put(app.processName, app.uid, app);
2034                synchronized (mPidsSelfLocked) {
2035                    mPidsSelfLocked.put(app.pid, app);
2036                }
2037                updateLruProcessLocked(app, false, null);
2038                updateOomAdjLocked();
2039            }
2040        } catch (PackageManager.NameNotFoundException e) {
2041            throw new RuntimeException(
2042                    "Unable to find android system package", e);
2043        }
2044    }
2045
2046    public void setWindowManager(WindowManagerService wm) {
2047        mWindowManager = wm;
2048        mStackSupervisor.setWindowManager(wm);
2049    }
2050
2051    public void startObservingNativeCrashes() {
2052        final NativeCrashListener ncl = new NativeCrashListener(this);
2053        ncl.start();
2054    }
2055
2056    public IAppOpsService getAppOpsService() {
2057        return mAppOpsService;
2058    }
2059
2060    static class MemBinder extends Binder {
2061        ActivityManagerService mActivityManagerService;
2062        MemBinder(ActivityManagerService activityManagerService) {
2063            mActivityManagerService = activityManagerService;
2064        }
2065
2066        @Override
2067        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2068            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2069                    != PackageManager.PERMISSION_GRANTED) {
2070                pw.println("Permission Denial: can't dump meminfo from from pid="
2071                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2072                        + " without permission " + android.Manifest.permission.DUMP);
2073                return;
2074            }
2075
2076            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2077        }
2078    }
2079
2080    static class GraphicsBinder extends Binder {
2081        ActivityManagerService mActivityManagerService;
2082        GraphicsBinder(ActivityManagerService activityManagerService) {
2083            mActivityManagerService = activityManagerService;
2084        }
2085
2086        @Override
2087        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2088            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2089                    != PackageManager.PERMISSION_GRANTED) {
2090                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2091                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2092                        + " without permission " + android.Manifest.permission.DUMP);
2093                return;
2094            }
2095
2096            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2097        }
2098    }
2099
2100    static class DbBinder extends Binder {
2101        ActivityManagerService mActivityManagerService;
2102        DbBinder(ActivityManagerService activityManagerService) {
2103            mActivityManagerService = activityManagerService;
2104        }
2105
2106        @Override
2107        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2108            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2109                    != PackageManager.PERMISSION_GRANTED) {
2110                pw.println("Permission Denial: can't dump dbinfo from from pid="
2111                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2112                        + " without permission " + android.Manifest.permission.DUMP);
2113                return;
2114            }
2115
2116            mActivityManagerService.dumpDbInfo(fd, pw, args);
2117        }
2118    }
2119
2120    static class CpuBinder extends Binder {
2121        ActivityManagerService mActivityManagerService;
2122        CpuBinder(ActivityManagerService activityManagerService) {
2123            mActivityManagerService = activityManagerService;
2124        }
2125
2126        @Override
2127        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2128            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2129                    != PackageManager.PERMISSION_GRANTED) {
2130                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2131                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2132                        + " without permission " + android.Manifest.permission.DUMP);
2133                return;
2134            }
2135
2136            synchronized (mActivityManagerService.mProcessCpuThread) {
2137                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2138                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2139                        SystemClock.uptimeMillis()));
2140            }
2141        }
2142    }
2143
2144    public static final class Lifecycle extends SystemService {
2145        private final ActivityManagerService mService;
2146
2147        public Lifecycle(Context context) {
2148            super(context);
2149            mService = new ActivityManagerService(context);
2150        }
2151
2152        @Override
2153        public void onStart() {
2154            mService.start();
2155        }
2156
2157        public ActivityManagerService getService() {
2158            return mService;
2159        }
2160    }
2161
2162    // Note: This method is invoked on the main thread but may need to attach various
2163    // handlers to other threads.  So take care to be explicit about the looper.
2164    public ActivityManagerService(Context systemContext) {
2165        mContext = systemContext;
2166        mFactoryTest = FactoryTest.getMode();
2167        mSystemThread = ActivityThread.currentActivityThread();
2168
2169        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2170
2171        mHandlerThread = new ServiceThread(TAG,
2172                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2173        mHandlerThread.start();
2174        mHandler = new MainHandler(mHandlerThread.getLooper());
2175
2176        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2177                "foreground", BROADCAST_FG_TIMEOUT, false);
2178        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2179                "background", BROADCAST_BG_TIMEOUT, true);
2180        mBroadcastQueues[0] = mFgBroadcastQueue;
2181        mBroadcastQueues[1] = mBgBroadcastQueue;
2182
2183        mServices = new ActiveServices(this);
2184        mProviderMap = new ProviderMap(this);
2185
2186        // TODO: Move creation of battery stats service outside of activity manager service.
2187        File dataDir = Environment.getDataDirectory();
2188        File systemDir = new File(dataDir, "system");
2189        systemDir.mkdirs();
2190        mBatteryStatsService = new BatteryStatsService(new File(
2191                systemDir, "batterystats.bin").toString(), mHandler);
2192        mBatteryStatsService.getActiveStatistics().readLocked();
2193        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2194        mOnBattery = DEBUG_POWER ? true
2195                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2196        mBatteryStatsService.getActiveStatistics().setCallback(this);
2197
2198        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2199
2200        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
2201        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2202
2203        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2204
2205        // User 0 is the first and only user that runs at boot.
2206        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2207        mUserLru.add(Integer.valueOf(0));
2208        updateStartedUserArrayLocked();
2209
2210        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2211            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2212
2213        mConfiguration.setToDefaults();
2214        mConfiguration.setLocale(Locale.getDefault());
2215
2216        mConfigurationSeq = mConfiguration.seq = 1;
2217        mProcessCpuTracker.init();
2218
2219        mHasRecents = mContext.getResources().getBoolean(
2220                com.android.internal.R.bool.config_hasRecents);
2221
2222        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2223        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2224        mStackSupervisor = new ActivityStackSupervisor(this);
2225        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2226
2227        mProcessCpuThread = new Thread("CpuTracker") {
2228            @Override
2229            public void run() {
2230                while (true) {
2231                    try {
2232                        try {
2233                            synchronized(this) {
2234                                final long now = SystemClock.uptimeMillis();
2235                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2236                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2237                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2238                                //        + ", write delay=" + nextWriteDelay);
2239                                if (nextWriteDelay < nextCpuDelay) {
2240                                    nextCpuDelay = nextWriteDelay;
2241                                }
2242                                if (nextCpuDelay > 0) {
2243                                    mProcessCpuMutexFree.set(true);
2244                                    this.wait(nextCpuDelay);
2245                                }
2246                            }
2247                        } catch (InterruptedException e) {
2248                        }
2249                        updateCpuStatsNow();
2250                    } catch (Exception e) {
2251                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2252                    }
2253                }
2254            }
2255        };
2256
2257        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2258
2259        Watchdog.getInstance().addMonitor(this);
2260        Watchdog.getInstance().addThread(mHandler);
2261    }
2262
2263    public void setSystemServiceManager(SystemServiceManager mgr) {
2264        mSystemServiceManager = mgr;
2265    }
2266
2267    private void start() {
2268        Process.removeAllProcessGroups();
2269        mProcessCpuThread.start();
2270
2271        mBatteryStatsService.publish(mContext);
2272        mUsageStatsService.publish(mContext);
2273        mAppOpsService.publish(mContext);
2274        Slog.d("AppOps", "AppOpsService published");
2275        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2276    }
2277
2278    public void initPowerManagement() {
2279        mStackSupervisor.initPowerManagement();
2280        mBatteryStatsService.initPowerManagement();
2281    }
2282
2283    @Override
2284    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2285            throws RemoteException {
2286        if (code == SYSPROPS_TRANSACTION) {
2287            // We need to tell all apps about the system property change.
2288            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2289            synchronized(this) {
2290                final int NP = mProcessNames.getMap().size();
2291                for (int ip=0; ip<NP; ip++) {
2292                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2293                    final int NA = apps.size();
2294                    for (int ia=0; ia<NA; ia++) {
2295                        ProcessRecord app = apps.valueAt(ia);
2296                        if (app.thread != null) {
2297                            procs.add(app.thread.asBinder());
2298                        }
2299                    }
2300                }
2301            }
2302
2303            int N = procs.size();
2304            for (int i=0; i<N; i++) {
2305                Parcel data2 = Parcel.obtain();
2306                try {
2307                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2308                } catch (RemoteException e) {
2309                }
2310                data2.recycle();
2311            }
2312        }
2313        try {
2314            return super.onTransact(code, data, reply, flags);
2315        } catch (RuntimeException e) {
2316            // The activity manager only throws security exceptions, so let's
2317            // log all others.
2318            if (!(e instanceof SecurityException)) {
2319                Slog.wtf(TAG, "Activity Manager Crash", e);
2320            }
2321            throw e;
2322        }
2323    }
2324
2325    void updateCpuStats() {
2326        final long now = SystemClock.uptimeMillis();
2327        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2328            return;
2329        }
2330        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2331            synchronized (mProcessCpuThread) {
2332                mProcessCpuThread.notify();
2333            }
2334        }
2335    }
2336
2337    void updateCpuStatsNow() {
2338        synchronized (mProcessCpuThread) {
2339            mProcessCpuMutexFree.set(false);
2340            final long now = SystemClock.uptimeMillis();
2341            boolean haveNewCpuStats = false;
2342
2343            if (MONITOR_CPU_USAGE &&
2344                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2345                mLastCpuTime.set(now);
2346                haveNewCpuStats = true;
2347                mProcessCpuTracker.update();
2348                //Slog.i(TAG, mProcessCpu.printCurrentState());
2349                //Slog.i(TAG, "Total CPU usage: "
2350                //        + mProcessCpu.getTotalCpuPercent() + "%");
2351
2352                // Slog the cpu usage if the property is set.
2353                if ("true".equals(SystemProperties.get("events.cpu"))) {
2354                    int user = mProcessCpuTracker.getLastUserTime();
2355                    int system = mProcessCpuTracker.getLastSystemTime();
2356                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2357                    int irq = mProcessCpuTracker.getLastIrqTime();
2358                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2359                    int idle = mProcessCpuTracker.getLastIdleTime();
2360
2361                    int total = user + system + iowait + irq + softIrq + idle;
2362                    if (total == 0) total = 1;
2363
2364                    EventLog.writeEvent(EventLogTags.CPU,
2365                            ((user+system+iowait+irq+softIrq) * 100) / total,
2366                            (user * 100) / total,
2367                            (system * 100) / total,
2368                            (iowait * 100) / total,
2369                            (irq * 100) / total,
2370                            (softIrq * 100) / total);
2371                }
2372            }
2373
2374            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2375            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2376            synchronized(bstats) {
2377                synchronized(mPidsSelfLocked) {
2378                    if (haveNewCpuStats) {
2379                        if (mOnBattery) {
2380                            int perc = bstats.startAddingCpuLocked();
2381                            int totalUTime = 0;
2382                            int totalSTime = 0;
2383                            final int N = mProcessCpuTracker.countStats();
2384                            for (int i=0; i<N; i++) {
2385                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2386                                if (!st.working) {
2387                                    continue;
2388                                }
2389                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2390                                int otherUTime = (st.rel_utime*perc)/100;
2391                                int otherSTime = (st.rel_stime*perc)/100;
2392                                totalUTime += otherUTime;
2393                                totalSTime += otherSTime;
2394                                if (pr != null) {
2395                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2396                                    if (ps == null || !ps.isActive()) {
2397                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2398                                                pr.info.uid, pr.processName);
2399                                    }
2400                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2401                                            st.rel_stime-otherSTime);
2402                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2403                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2404                                } else {
2405                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2406                                    if (ps == null || !ps.isActive()) {
2407                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2408                                                bstats.mapUid(st.uid), st.name);
2409                                    }
2410                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2411                                            st.rel_stime-otherSTime);
2412                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2413                                }
2414                            }
2415                            bstats.finishAddingCpuLocked(perc, totalUTime,
2416                                    totalSTime, cpuSpeedTimes);
2417                        }
2418                    }
2419                }
2420
2421                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2422                    mLastWriteTime = now;
2423                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2424                }
2425            }
2426        }
2427    }
2428
2429    @Override
2430    public void batteryNeedsCpuUpdate() {
2431        updateCpuStatsNow();
2432    }
2433
2434    @Override
2435    public void batteryPowerChanged(boolean onBattery) {
2436        // When plugging in, update the CPU stats first before changing
2437        // the plug state.
2438        updateCpuStatsNow();
2439        synchronized (this) {
2440            synchronized(mPidsSelfLocked) {
2441                mOnBattery = DEBUG_POWER ? true : onBattery;
2442            }
2443        }
2444    }
2445
2446    /**
2447     * Initialize the application bind args. These are passed to each
2448     * process when the bindApplication() IPC is sent to the process. They're
2449     * lazily setup to make sure the services are running when they're asked for.
2450     */
2451    private HashMap<String, IBinder> getCommonServicesLocked() {
2452        if (mAppBindArgs == null) {
2453            mAppBindArgs = new HashMap<String, IBinder>();
2454
2455            // Setup the application init args
2456            mAppBindArgs.put("package", ServiceManager.getService("package"));
2457            mAppBindArgs.put("window", ServiceManager.getService("window"));
2458            mAppBindArgs.put(Context.ALARM_SERVICE,
2459                    ServiceManager.getService(Context.ALARM_SERVICE));
2460        }
2461        return mAppBindArgs;
2462    }
2463
2464    final void setFocusedActivityLocked(ActivityRecord r) {
2465        if (mFocusedActivity != r) {
2466            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2467            mFocusedActivity = r;
2468            if (r.task != null && r.task.voiceInteractor != null) {
2469                startRunningVoiceLocked();
2470            } else {
2471                finishRunningVoiceLocked();
2472            }
2473            mStackSupervisor.setFocusedStack(r);
2474            if (r != null) {
2475                mWindowManager.setFocusedApp(r.appToken, true);
2476            }
2477            applyUpdateLockStateLocked(r);
2478        }
2479    }
2480
2481    final void clearFocusedActivity(ActivityRecord r) {
2482        if (mFocusedActivity == r) {
2483            mFocusedActivity = null;
2484        }
2485    }
2486
2487    @Override
2488    public void setFocusedStack(int stackId) {
2489        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2490        synchronized (ActivityManagerService.this) {
2491            ActivityStack stack = mStackSupervisor.getStack(stackId);
2492            if (stack != null) {
2493                ActivityRecord r = stack.topRunningActivityLocked(null);
2494                if (r != null) {
2495                    setFocusedActivityLocked(r);
2496                }
2497            }
2498        }
2499    }
2500
2501    @Override
2502    public void notifyActivityDrawn(IBinder token) {
2503        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2504        synchronized (this) {
2505            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2506            if (r != null) {
2507                r.task.stack.notifyActivityDrawnLocked(r);
2508            }
2509        }
2510    }
2511
2512    final void applyUpdateLockStateLocked(ActivityRecord r) {
2513        // Modifications to the UpdateLock state are done on our handler, outside
2514        // the activity manager's locks.  The new state is determined based on the
2515        // state *now* of the relevant activity record.  The object is passed to
2516        // the handler solely for logging detail, not to be consulted/modified.
2517        final boolean nextState = r != null && r.immersive;
2518        mHandler.sendMessage(
2519                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2520    }
2521
2522    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2523        Message msg = Message.obtain();
2524        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2525        msg.obj = r.task.askedCompatMode ? null : r;
2526        mHandler.sendMessage(msg);
2527    }
2528
2529    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2530            String what, Object obj, ProcessRecord srcApp) {
2531        app.lastActivityTime = now;
2532
2533        if (app.activities.size() > 0) {
2534            // Don't want to touch dependent processes that are hosting activities.
2535            return index;
2536        }
2537
2538        int lrui = mLruProcesses.lastIndexOf(app);
2539        if (lrui < 0) {
2540            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2541                    + what + " " + obj + " from " + srcApp);
2542            return index;
2543        }
2544
2545        if (lrui >= index) {
2546            // Don't want to cause this to move dependent processes *back* in the
2547            // list as if they were less frequently used.
2548            return index;
2549        }
2550
2551        if (lrui >= mLruProcessActivityStart) {
2552            // Don't want to touch dependent processes that are hosting activities.
2553            return index;
2554        }
2555
2556        mLruProcesses.remove(lrui);
2557        if (index > 0) {
2558            index--;
2559        }
2560        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2561                + " in LRU list: " + app);
2562        mLruProcesses.add(index, app);
2563        return index;
2564    }
2565
2566    final void removeLruProcessLocked(ProcessRecord app) {
2567        int lrui = mLruProcesses.lastIndexOf(app);
2568        if (lrui >= 0) {
2569            if (lrui <= mLruProcessActivityStart) {
2570                mLruProcessActivityStart--;
2571            }
2572            if (lrui <= mLruProcessServiceStart) {
2573                mLruProcessServiceStart--;
2574            }
2575            mLruProcesses.remove(lrui);
2576        }
2577    }
2578
2579    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2580            ProcessRecord client) {
2581        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2582                || app.treatLikeActivity;
2583        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2584        if (!activityChange && hasActivity) {
2585            // The process has activities, so we are only allowing activity-based adjustments
2586            // to move it.  It should be kept in the front of the list with other
2587            // processes that have activities, and we don't want those to change their
2588            // order except due to activity operations.
2589            return;
2590        }
2591
2592        mLruSeq++;
2593        final long now = SystemClock.uptimeMillis();
2594        app.lastActivityTime = now;
2595
2596        // First a quick reject: if the app is already at the position we will
2597        // put it, then there is nothing to do.
2598        if (hasActivity) {
2599            final int N = mLruProcesses.size();
2600            if (N > 0 && mLruProcesses.get(N-1) == app) {
2601                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2602                return;
2603            }
2604        } else {
2605            if (mLruProcessServiceStart > 0
2606                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2607                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2608                return;
2609            }
2610        }
2611
2612        int lrui = mLruProcesses.lastIndexOf(app);
2613
2614        if (app.persistent && lrui >= 0) {
2615            // We don't care about the position of persistent processes, as long as
2616            // they are in the list.
2617            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2618            return;
2619        }
2620
2621        /* In progress: compute new position first, so we can avoid doing work
2622           if the process is not actually going to move.  Not yet working.
2623        int addIndex;
2624        int nextIndex;
2625        boolean inActivity = false, inService = false;
2626        if (hasActivity) {
2627            // Process has activities, put it at the very tipsy-top.
2628            addIndex = mLruProcesses.size();
2629            nextIndex = mLruProcessServiceStart;
2630            inActivity = true;
2631        } else if (hasService) {
2632            // Process has services, put it at the top of the service list.
2633            addIndex = mLruProcessActivityStart;
2634            nextIndex = mLruProcessServiceStart;
2635            inActivity = true;
2636            inService = true;
2637        } else  {
2638            // Process not otherwise of interest, it goes to the top of the non-service area.
2639            addIndex = mLruProcessServiceStart;
2640            if (client != null) {
2641                int clientIndex = mLruProcesses.lastIndexOf(client);
2642                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2643                        + app);
2644                if (clientIndex >= 0 && addIndex > clientIndex) {
2645                    addIndex = clientIndex;
2646                }
2647            }
2648            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2649        }
2650
2651        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2652                + mLruProcessActivityStart + "): " + app);
2653        */
2654
2655        if (lrui >= 0) {
2656            if (lrui < mLruProcessActivityStart) {
2657                mLruProcessActivityStart--;
2658            }
2659            if (lrui < mLruProcessServiceStart) {
2660                mLruProcessServiceStart--;
2661            }
2662            /*
2663            if (addIndex > lrui) {
2664                addIndex--;
2665            }
2666            if (nextIndex > lrui) {
2667                nextIndex--;
2668            }
2669            */
2670            mLruProcesses.remove(lrui);
2671        }
2672
2673        /*
2674        mLruProcesses.add(addIndex, app);
2675        if (inActivity) {
2676            mLruProcessActivityStart++;
2677        }
2678        if (inService) {
2679            mLruProcessActivityStart++;
2680        }
2681        */
2682
2683        int nextIndex;
2684        if (hasActivity) {
2685            final int N = mLruProcesses.size();
2686            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2687                // Process doesn't have activities, but has clients with
2688                // activities...  move it up, but one below the top (the top
2689                // should always have a real activity).
2690                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2691                mLruProcesses.add(N-1, app);
2692                // To keep it from spamming the LRU list (by making a bunch of clients),
2693                // we will push down any other entries owned by the app.
2694                final int uid = app.info.uid;
2695                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2696                    ProcessRecord subProc = mLruProcesses.get(i);
2697                    if (subProc.info.uid == uid) {
2698                        // We want to push this one down the list.  If the process after
2699                        // it is for the same uid, however, don't do so, because we don't
2700                        // want them internally to be re-ordered.
2701                        if (mLruProcesses.get(i-1).info.uid != uid) {
2702                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2703                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2704                            ProcessRecord tmp = mLruProcesses.get(i);
2705                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2706                            mLruProcesses.set(i-1, tmp);
2707                            i--;
2708                        }
2709                    } else {
2710                        // A gap, we can stop here.
2711                        break;
2712                    }
2713                }
2714            } else {
2715                // Process has activities, put it at the very tipsy-top.
2716                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2717                mLruProcesses.add(app);
2718            }
2719            nextIndex = mLruProcessServiceStart;
2720        } else if (hasService) {
2721            // Process has services, put it at the top of the service list.
2722            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2723            mLruProcesses.add(mLruProcessActivityStart, app);
2724            nextIndex = mLruProcessServiceStart;
2725            mLruProcessActivityStart++;
2726        } else  {
2727            // Process not otherwise of interest, it goes to the top of the non-service area.
2728            int index = mLruProcessServiceStart;
2729            if (client != null) {
2730                // If there is a client, don't allow the process to be moved up higher
2731                // in the list than that client.
2732                int clientIndex = mLruProcesses.lastIndexOf(client);
2733                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2734                        + " when updating " + app);
2735                if (clientIndex <= lrui) {
2736                    // Don't allow the client index restriction to push it down farther in the
2737                    // list than it already is.
2738                    clientIndex = lrui;
2739                }
2740                if (clientIndex >= 0 && index > clientIndex) {
2741                    index = clientIndex;
2742                }
2743            }
2744            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2745            mLruProcesses.add(index, app);
2746            nextIndex = index-1;
2747            mLruProcessActivityStart++;
2748            mLruProcessServiceStart++;
2749        }
2750
2751        // If the app is currently using a content provider or service,
2752        // bump those processes as well.
2753        for (int j=app.connections.size()-1; j>=0; j--) {
2754            ConnectionRecord cr = app.connections.valueAt(j);
2755            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2756                    && cr.binding.service.app != null
2757                    && cr.binding.service.app.lruSeq != mLruSeq
2758                    && !cr.binding.service.app.persistent) {
2759                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2760                        "service connection", cr, app);
2761            }
2762        }
2763        for (int j=app.conProviders.size()-1; j>=0; j--) {
2764            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2765            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2766                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2767                        "provider reference", cpr, app);
2768            }
2769        }
2770    }
2771
2772    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2773        if (uid == Process.SYSTEM_UID) {
2774            // The system gets to run in any process.  If there are multiple
2775            // processes with the same uid, just pick the first (this
2776            // should never happen).
2777            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2778            if (procs == null) return null;
2779            final int N = procs.size();
2780            for (int i = 0; i < N; i++) {
2781                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2782            }
2783        }
2784        ProcessRecord proc = mProcessNames.get(processName, uid);
2785        if (false && proc != null && !keepIfLarge
2786                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2787                && proc.lastCachedPss >= 4000) {
2788            // Turn this condition on to cause killing to happen regularly, for testing.
2789            if (proc.baseProcessTracker != null) {
2790                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2791            }
2792            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2793                    + "k from cached");
2794        } else if (proc != null && !keepIfLarge
2795                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2796                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2797            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2798            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2799                if (proc.baseProcessTracker != null) {
2800                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2801                }
2802                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2803                        + "k from cached");
2804            }
2805        }
2806        return proc;
2807    }
2808
2809    void ensurePackageDexOpt(String packageName) {
2810        IPackageManager pm = AppGlobals.getPackageManager();
2811        try {
2812            if (pm.performDexOpt(packageName)) {
2813                mDidDexOpt = true;
2814            }
2815        } catch (RemoteException e) {
2816        }
2817    }
2818
2819    boolean isNextTransitionForward() {
2820        int transit = mWindowManager.getPendingAppTransition();
2821        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2822                || transit == AppTransition.TRANSIT_TASK_OPEN
2823                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2824    }
2825
2826    final ProcessRecord startProcessLocked(String processName,
2827            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2828            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2829            boolean isolated, boolean keepIfLarge) {
2830        ProcessRecord app;
2831        if (!isolated) {
2832            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2833        } else {
2834            // If this is an isolated process, it can't re-use an existing process.
2835            app = null;
2836        }
2837        // We don't have to do anything more if:
2838        // (1) There is an existing application record; and
2839        // (2) The caller doesn't think it is dead, OR there is no thread
2840        //     object attached to it so we know it couldn't have crashed; and
2841        // (3) There is a pid assigned to it, so it is either starting or
2842        //     already running.
2843        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2844                + " app=" + app + " knownToBeDead=" + knownToBeDead
2845                + " thread=" + (app != null ? app.thread : null)
2846                + " pid=" + (app != null ? app.pid : -1));
2847        if (app != null && app.pid > 0) {
2848            if (!knownToBeDead || app.thread == null) {
2849                // We already have the app running, or are waiting for it to
2850                // come up (we have a pid but not yet its thread), so keep it.
2851                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2852                // If this is a new package in the process, add the package to the list
2853                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2854                return app;
2855            }
2856
2857            // An application record is attached to a previous process,
2858            // clean it up now.
2859            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2860            Process.killProcessGroup(app.info.uid, app.pid);
2861            handleAppDiedLocked(app, true, true);
2862        }
2863
2864        String hostingNameStr = hostingName != null
2865                ? hostingName.flattenToShortString() : null;
2866
2867        if (!isolated) {
2868            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2869                // If we are in the background, then check to see if this process
2870                // is bad.  If so, we will just silently fail.
2871                if (mBadProcesses.get(info.processName, info.uid) != null) {
2872                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2873                            + "/" + info.processName);
2874                    return null;
2875                }
2876            } else {
2877                // When the user is explicitly starting a process, then clear its
2878                // crash count so that we won't make it bad until they see at
2879                // least one crash dialog again, and make the process good again
2880                // if it had been bad.
2881                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2882                        + "/" + info.processName);
2883                mProcessCrashTimes.remove(info.processName, info.uid);
2884                if (mBadProcesses.get(info.processName, info.uid) != null) {
2885                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2886                            UserHandle.getUserId(info.uid), info.uid,
2887                            info.processName);
2888                    mBadProcesses.remove(info.processName, info.uid);
2889                    if (app != null) {
2890                        app.bad = false;
2891                    }
2892                }
2893            }
2894        }
2895
2896        if (app == null) {
2897            app = newProcessRecordLocked(info, processName, isolated);
2898            if (app == null) {
2899                Slog.w(TAG, "Failed making new process record for "
2900                        + processName + "/" + info.uid + " isolated=" + isolated);
2901                return null;
2902            }
2903            mProcessNames.put(processName, app.uid, app);
2904            if (isolated) {
2905                mIsolatedProcesses.put(app.uid, app);
2906            }
2907        } else {
2908            // If this is a new package in the process, add the package to the list
2909            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2910        }
2911
2912        // If the system is not ready yet, then hold off on starting this
2913        // process until it is.
2914        if (!mProcessesReady
2915                && !isAllowedWhileBooting(info)
2916                && !allowWhileBooting) {
2917            if (!mProcessesOnHold.contains(app)) {
2918                mProcessesOnHold.add(app);
2919            }
2920            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2921            return app;
2922        }
2923
2924        startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */);
2925        return (app.pid != 0) ? app : null;
2926    }
2927
2928    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2929        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2930    }
2931
2932    private final void startProcessLocked(ProcessRecord app,
2933            String hostingType, String hostingNameStr, String abiOverride) {
2934        if (app.pid > 0 && app.pid != MY_PID) {
2935            synchronized (mPidsSelfLocked) {
2936                mPidsSelfLocked.remove(app.pid);
2937                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2938            }
2939            app.setPid(0);
2940        }
2941
2942        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2943                "startProcessLocked removing on hold: " + app);
2944        mProcessesOnHold.remove(app);
2945
2946        updateCpuStats();
2947
2948        try {
2949            int uid = app.uid;
2950
2951            int[] gids = null;
2952            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2953            if (!app.isolated) {
2954                int[] permGids = null;
2955                try {
2956                    final PackageManager pm = mContext.getPackageManager();
2957                    permGids = pm.getPackageGids(app.info.packageName);
2958
2959                    if (Environment.isExternalStorageEmulated()) {
2960                        if (pm.checkPermission(
2961                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2962                                app.info.packageName) == PERMISSION_GRANTED) {
2963                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2964                        } else {
2965                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2966                        }
2967                    }
2968                } catch (PackageManager.NameNotFoundException e) {
2969                    Slog.w(TAG, "Unable to retrieve gids", e);
2970                }
2971
2972                /*
2973                 * Add shared application and profile GIDs so applications can share some
2974                 * resources like shared libraries and access user-wide resources
2975                 */
2976                if (permGids == null) {
2977                    gids = new int[2];
2978                } else {
2979                    gids = new int[permGids.length + 2];
2980                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2981                }
2982                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2983                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2984            }
2985            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2986                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2987                        && mTopComponent != null
2988                        && app.processName.equals(mTopComponent.getPackageName())) {
2989                    uid = 0;
2990                }
2991                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2992                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2993                    uid = 0;
2994                }
2995            }
2996            int debugFlags = 0;
2997            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2998                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2999                // Also turn on CheckJNI for debuggable apps. It's quite
3000                // awkward to turn on otherwise.
3001                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3002            }
3003            // Run the app in safe mode if its manifest requests so or the
3004            // system is booted in safe mode.
3005            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3006                mSafeMode == true) {
3007                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3008            }
3009            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3010                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3011            }
3012            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3013                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3014            }
3015            if ("1".equals(SystemProperties.get("debug.assert"))) {
3016                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3017            }
3018
3019            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3020            if (requiredAbi == null) {
3021                requiredAbi = Build.SUPPORTED_ABIS[0];
3022            }
3023
3024            // Start the process.  It will either succeed and return a result containing
3025            // the PID of the new process, or else throw a RuntimeException.
3026            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
3027                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3028                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
3029
3030            if (app.isolated) {
3031                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3032            }
3033            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3034
3035            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3036                    UserHandle.getUserId(uid), startResult.pid, uid,
3037                    app.processName, hostingType,
3038                    hostingNameStr != null ? hostingNameStr : "");
3039
3040            if (app.persistent) {
3041                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3042            }
3043
3044            StringBuilder buf = mStringBuilder;
3045            buf.setLength(0);
3046            buf.append("Start proc ");
3047            buf.append(app.processName);
3048            buf.append(" for ");
3049            buf.append(hostingType);
3050            if (hostingNameStr != null) {
3051                buf.append(" ");
3052                buf.append(hostingNameStr);
3053            }
3054            buf.append(": pid=");
3055            buf.append(startResult.pid);
3056            buf.append(" uid=");
3057            buf.append(uid);
3058            buf.append(" gids={");
3059            if (gids != null) {
3060                for (int gi=0; gi<gids.length; gi++) {
3061                    if (gi != 0) buf.append(", ");
3062                    buf.append(gids[gi]);
3063
3064                }
3065            }
3066            buf.append("}");
3067            if (requiredAbi != null) {
3068                buf.append(" abi=");
3069                buf.append(requiredAbi);
3070            }
3071            Slog.i(TAG, buf.toString());
3072            app.setPid(startResult.pid);
3073            app.usingWrapper = startResult.usingWrapper;
3074            app.removed = false;
3075            app.killedByAm = false;
3076            synchronized (mPidsSelfLocked) {
3077                this.mPidsSelfLocked.put(startResult.pid, app);
3078                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3079                msg.obj = app;
3080                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3081                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3082            }
3083        } catch (RuntimeException e) {
3084            // XXX do better error recovery.
3085            app.setPid(0);
3086            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3087            if (app.isolated) {
3088                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3089            }
3090            Slog.e(TAG, "Failure starting process " + app.processName, e);
3091        }
3092    }
3093
3094    void updateUsageStats(ActivityRecord component, boolean resumed) {
3095        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3096        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3097        if (resumed) {
3098            mUsageStatsService.noteResumeComponent(component.realActivity);
3099            synchronized (stats) {
3100                stats.noteActivityResumedLocked(component.app.uid);
3101            }
3102        } else {
3103            mUsageStatsService.notePauseComponent(component.realActivity);
3104            synchronized (stats) {
3105                stats.noteActivityPausedLocked(component.app.uid);
3106            }
3107        }
3108    }
3109
3110    Intent getHomeIntent() {
3111        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3112        intent.setComponent(mTopComponent);
3113        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3114            intent.addCategory(Intent.CATEGORY_HOME);
3115        }
3116        return intent;
3117    }
3118
3119    boolean startHomeActivityLocked(int userId) {
3120        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3121                && mTopAction == null) {
3122            // We are running in factory test mode, but unable to find
3123            // the factory test app, so just sit around displaying the
3124            // error message and don't try to start anything.
3125            return false;
3126        }
3127        Intent intent = getHomeIntent();
3128        ActivityInfo aInfo =
3129            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3130        if (aInfo != null) {
3131            intent.setComponent(new ComponentName(
3132                    aInfo.applicationInfo.packageName, aInfo.name));
3133            // Don't do this if the home app is currently being
3134            // instrumented.
3135            aInfo = new ActivityInfo(aInfo);
3136            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3137            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3138                    aInfo.applicationInfo.uid, true);
3139            if (app == null || app.instrumentationClass == null) {
3140                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3141                mStackSupervisor.startHomeActivity(intent, aInfo);
3142            }
3143        }
3144
3145        return true;
3146    }
3147
3148    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3149        ActivityInfo ai = null;
3150        ComponentName comp = intent.getComponent();
3151        try {
3152            if (comp != null) {
3153                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3154            } else {
3155                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3156                        intent,
3157                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3158                            flags, userId);
3159
3160                if (info != null) {
3161                    ai = info.activityInfo;
3162                }
3163            }
3164        } catch (RemoteException e) {
3165            // ignore
3166        }
3167
3168        return ai;
3169    }
3170
3171    /**
3172     * Starts the "new version setup screen" if appropriate.
3173     */
3174    void startSetupActivityLocked() {
3175        // Only do this once per boot.
3176        if (mCheckedForSetup) {
3177            return;
3178        }
3179
3180        // We will show this screen if the current one is a different
3181        // version than the last one shown, and we are not running in
3182        // low-level factory test mode.
3183        final ContentResolver resolver = mContext.getContentResolver();
3184        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3185                Settings.Global.getInt(resolver,
3186                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3187            mCheckedForSetup = true;
3188
3189            // See if we should be showing the platform update setup UI.
3190            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3191            List<ResolveInfo> ris = mContext.getPackageManager()
3192                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3193
3194            // We don't allow third party apps to replace this.
3195            ResolveInfo ri = null;
3196            for (int i=0; ris != null && i<ris.size(); i++) {
3197                if ((ris.get(i).activityInfo.applicationInfo.flags
3198                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3199                    ri = ris.get(i);
3200                    break;
3201                }
3202            }
3203
3204            if (ri != null) {
3205                String vers = ri.activityInfo.metaData != null
3206                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3207                        : null;
3208                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3209                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3210                            Intent.METADATA_SETUP_VERSION);
3211                }
3212                String lastVers = Settings.Secure.getString(
3213                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3214                if (vers != null && !vers.equals(lastVers)) {
3215                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3216                    intent.setComponent(new ComponentName(
3217                            ri.activityInfo.packageName, ri.activityInfo.name));
3218                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3219                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3220                }
3221            }
3222        }
3223    }
3224
3225    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3226        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3227    }
3228
3229    void enforceNotIsolatedCaller(String caller) {
3230        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3231            throw new SecurityException("Isolated process not allowed to call " + caller);
3232        }
3233    }
3234
3235    @Override
3236    public int getFrontActivityScreenCompatMode() {
3237        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3238        synchronized (this) {
3239            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3240        }
3241    }
3242
3243    @Override
3244    public void setFrontActivityScreenCompatMode(int mode) {
3245        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3246                "setFrontActivityScreenCompatMode");
3247        synchronized (this) {
3248            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3249        }
3250    }
3251
3252    @Override
3253    public int getPackageScreenCompatMode(String packageName) {
3254        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3255        synchronized (this) {
3256            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3257        }
3258    }
3259
3260    @Override
3261    public void setPackageScreenCompatMode(String packageName, int mode) {
3262        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3263                "setPackageScreenCompatMode");
3264        synchronized (this) {
3265            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3266        }
3267    }
3268
3269    @Override
3270    public boolean getPackageAskScreenCompat(String packageName) {
3271        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3272        synchronized (this) {
3273            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3274        }
3275    }
3276
3277    @Override
3278    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3279        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3280                "setPackageAskScreenCompat");
3281        synchronized (this) {
3282            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3283        }
3284    }
3285
3286    private void dispatchProcessesChanged() {
3287        int N;
3288        synchronized (this) {
3289            N = mPendingProcessChanges.size();
3290            if (mActiveProcessChanges.length < N) {
3291                mActiveProcessChanges = new ProcessChangeItem[N];
3292            }
3293            mPendingProcessChanges.toArray(mActiveProcessChanges);
3294            mAvailProcessChanges.addAll(mPendingProcessChanges);
3295            mPendingProcessChanges.clear();
3296            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3297        }
3298
3299        int i = mProcessObservers.beginBroadcast();
3300        while (i > 0) {
3301            i--;
3302            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3303            if (observer != null) {
3304                try {
3305                    for (int j=0; j<N; j++) {
3306                        ProcessChangeItem item = mActiveProcessChanges[j];
3307                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3308                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3309                                    + item.pid + " uid=" + item.uid + ": "
3310                                    + item.foregroundActivities);
3311                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3312                                    item.foregroundActivities);
3313                        }
3314                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3315                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3316                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3317                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3318                        }
3319                    }
3320                } catch (RemoteException e) {
3321                }
3322            }
3323        }
3324        mProcessObservers.finishBroadcast();
3325    }
3326
3327    private void dispatchProcessDied(int pid, int uid) {
3328        int i = mProcessObservers.beginBroadcast();
3329        while (i > 0) {
3330            i--;
3331            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3332            if (observer != null) {
3333                try {
3334                    observer.onProcessDied(pid, uid);
3335                } catch (RemoteException e) {
3336                }
3337            }
3338        }
3339        mProcessObservers.finishBroadcast();
3340    }
3341
3342    final void doPendingActivityLaunchesLocked(boolean doResume) {
3343        final int N = mPendingActivityLaunches.size();
3344        if (N <= 0) {
3345            return;
3346        }
3347        for (int i=0; i<N; i++) {
3348            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3349            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3350                    doResume && i == (N-1), null);
3351        }
3352        mPendingActivityLaunches.clear();
3353    }
3354
3355    @Override
3356    public final int startActivity(IApplicationThread caller, String callingPackage,
3357            Intent intent, String resolvedType, IBinder resultTo,
3358            String resultWho, int requestCode, int startFlags,
3359            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3360        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3361                resultWho, requestCode,
3362                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3363    }
3364
3365    @Override
3366    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3367            Intent intent, String resolvedType, IBinder resultTo,
3368            String resultWho, int requestCode, int startFlags,
3369            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3370        enforceNotIsolatedCaller("startActivity");
3371        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3372                false, ALLOW_FULL_ONLY, "startActivity", null);
3373        // TODO: Switch to user app stacks here.
3374        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3375                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3376                null, null, options, userId, null);
3377    }
3378
3379    @Override
3380    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3381            Intent intent, String resolvedType, IBinder resultTo,
3382            String resultWho, int requestCode, int startFlags, String profileFile,
3383            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3384        enforceNotIsolatedCaller("startActivityAndWait");
3385        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3386                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3387        WaitResult res = new WaitResult();
3388        // TODO: Switch to user app stacks here.
3389        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3390                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3391                res, null, options, userId, null);
3392        return res;
3393    }
3394
3395    @Override
3396    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3397            Intent intent, String resolvedType, IBinder resultTo,
3398            String resultWho, int requestCode, int startFlags, Configuration config,
3399            Bundle options, int userId) {
3400        enforceNotIsolatedCaller("startActivityWithConfig");
3401        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3402                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3403        // TODO: Switch to user app stacks here.
3404        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3405                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3406                null, null, null, config, options, userId, null);
3407        return ret;
3408    }
3409
3410    @Override
3411    public int startActivityIntentSender(IApplicationThread caller,
3412            IntentSender intent, Intent fillInIntent, String resolvedType,
3413            IBinder resultTo, String resultWho, int requestCode,
3414            int flagsMask, int flagsValues, Bundle options) {
3415        enforceNotIsolatedCaller("startActivityIntentSender");
3416        // Refuse possible leaked file descriptors
3417        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3418            throw new IllegalArgumentException("File descriptors passed in Intent");
3419        }
3420
3421        IIntentSender sender = intent.getTarget();
3422        if (!(sender instanceof PendingIntentRecord)) {
3423            throw new IllegalArgumentException("Bad PendingIntent object");
3424        }
3425
3426        PendingIntentRecord pir = (PendingIntentRecord)sender;
3427
3428        synchronized (this) {
3429            // If this is coming from the currently resumed activity, it is
3430            // effectively saying that app switches are allowed at this point.
3431            final ActivityStack stack = getFocusedStack();
3432            if (stack.mResumedActivity != null &&
3433                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3434                mAppSwitchesAllowedTime = 0;
3435            }
3436        }
3437        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3438                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3439        return ret;
3440    }
3441
3442    @Override
3443    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3444            Intent intent, String resolvedType, IVoiceInteractionSession session,
3445            IVoiceInteractor interactor, int startFlags, String profileFile,
3446            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3447        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3448                != PackageManager.PERMISSION_GRANTED) {
3449            String msg = "Permission Denial: startVoiceActivity() from pid="
3450                    + Binder.getCallingPid()
3451                    + ", uid=" + Binder.getCallingUid()
3452                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3453            Slog.w(TAG, msg);
3454            throw new SecurityException(msg);
3455        }
3456        if (session == null || interactor == null) {
3457            throw new NullPointerException("null session or interactor");
3458        }
3459        userId = handleIncomingUser(callingPid, callingUid, userId,
3460                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3461        // TODO: Switch to user app stacks here.
3462        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3463                resolvedType, session, interactor, null, null, 0, startFlags,
3464                profileFile, profileFd, null, null, options, userId, null);
3465    }
3466
3467    @Override
3468    public boolean startNextMatchingActivity(IBinder callingActivity,
3469            Intent intent, Bundle options) {
3470        // Refuse possible leaked file descriptors
3471        if (intent != null && intent.hasFileDescriptors() == true) {
3472            throw new IllegalArgumentException("File descriptors passed in Intent");
3473        }
3474
3475        synchronized (this) {
3476            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3477            if (r == null) {
3478                ActivityOptions.abort(options);
3479                return false;
3480            }
3481            if (r.app == null || r.app.thread == null) {
3482                // The caller is not running...  d'oh!
3483                ActivityOptions.abort(options);
3484                return false;
3485            }
3486            intent = new Intent(intent);
3487            // The caller is not allowed to change the data.
3488            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3489            // And we are resetting to find the next component...
3490            intent.setComponent(null);
3491
3492            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3493
3494            ActivityInfo aInfo = null;
3495            try {
3496                List<ResolveInfo> resolves =
3497                    AppGlobals.getPackageManager().queryIntentActivities(
3498                            intent, r.resolvedType,
3499                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3500                            UserHandle.getCallingUserId());
3501
3502                // Look for the original activity in the list...
3503                final int N = resolves != null ? resolves.size() : 0;
3504                for (int i=0; i<N; i++) {
3505                    ResolveInfo rInfo = resolves.get(i);
3506                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3507                            && rInfo.activityInfo.name.equals(r.info.name)) {
3508                        // We found the current one...  the next matching is
3509                        // after it.
3510                        i++;
3511                        if (i<N) {
3512                            aInfo = resolves.get(i).activityInfo;
3513                        }
3514                        if (debug) {
3515                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3516                                    + "/" + r.info.name);
3517                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3518                                    + "/" + aInfo.name);
3519                        }
3520                        break;
3521                    }
3522                }
3523            } catch (RemoteException e) {
3524            }
3525
3526            if (aInfo == null) {
3527                // Nobody who is next!
3528                ActivityOptions.abort(options);
3529                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3530                return false;
3531            }
3532
3533            intent.setComponent(new ComponentName(
3534                    aInfo.applicationInfo.packageName, aInfo.name));
3535            intent.setFlags(intent.getFlags()&~(
3536                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3537                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3538                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3539                    Intent.FLAG_ACTIVITY_NEW_TASK));
3540
3541            // Okay now we need to start the new activity, replacing the
3542            // currently running activity.  This is a little tricky because
3543            // we want to start the new one as if the current one is finished,
3544            // but not finish the current one first so that there is no flicker.
3545            // And thus...
3546            final boolean wasFinishing = r.finishing;
3547            r.finishing = true;
3548
3549            // Propagate reply information over to the new activity.
3550            final ActivityRecord resultTo = r.resultTo;
3551            final String resultWho = r.resultWho;
3552            final int requestCode = r.requestCode;
3553            r.resultTo = null;
3554            if (resultTo != null) {
3555                resultTo.removeResultsLocked(r, resultWho, requestCode);
3556            }
3557
3558            final long origId = Binder.clearCallingIdentity();
3559            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3560                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3561                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3562                    options, false, null, null);
3563            Binder.restoreCallingIdentity(origId);
3564
3565            r.finishing = wasFinishing;
3566            if (res != ActivityManager.START_SUCCESS) {
3567                return false;
3568            }
3569            return true;
3570        }
3571    }
3572
3573    final int startActivityInPackage(int uid, String callingPackage,
3574            Intent intent, String resolvedType, IBinder resultTo,
3575            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3576                    IActivityContainer container) {
3577
3578        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3579                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3580
3581        // TODO: Switch to user app stacks here.
3582        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3583                null, null, resultTo, resultWho, requestCode, startFlags,
3584                null, null, null, null, options, userId, container);
3585        return ret;
3586    }
3587
3588    @Override
3589    public final int startActivities(IApplicationThread caller, String callingPackage,
3590            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3591            int userId) {
3592        enforceNotIsolatedCaller("startActivities");
3593        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3594                false, ALLOW_FULL_ONLY, "startActivity", null);
3595        // TODO: Switch to user app stacks here.
3596        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3597                resolvedTypes, resultTo, options, userId);
3598        return ret;
3599    }
3600
3601    final int startActivitiesInPackage(int uid, String callingPackage,
3602            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3603            Bundle options, int userId) {
3604
3605        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3606                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3607        // TODO: Switch to user app stacks here.
3608        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3609                resultTo, options, userId);
3610        return ret;
3611    }
3612
3613    final void addRecentTaskLocked(TaskRecord task) {
3614        int N = mRecentTasks.size();
3615        // Quick case: check if the top-most recent task is the same.
3616        if (N > 0 && mRecentTasks.get(0) == task) {
3617            return;
3618        }
3619        // Another quick case: never add voice sessions.
3620        if (task.voiceSession != null) {
3621            return;
3622        }
3623        // Remove any existing entries that are the same kind of task.
3624        final Intent intent = task.intent;
3625        final boolean document = intent != null && intent.isDocument();
3626        final ComponentName comp = intent.getComponent();
3627
3628        int maxRecents = task.maxRecents - 1;
3629        for (int i=0; i<N; i++) {
3630            final TaskRecord tr = mRecentTasks.get(i);
3631            if (task != tr) {
3632                if (task.userId != tr.userId) {
3633                    continue;
3634                }
3635                if (i > MAX_RECENT_BITMAPS) {
3636                    tr.freeLastThumbnail();
3637                }
3638                final Intent trIntent = tr.intent;
3639                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3640                    (intent == null || !intent.filterEquals(trIntent))) {
3641                    continue;
3642                }
3643                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3644                if (document && trIsDocument) {
3645                    // These are the same document activity (not necessarily the same doc).
3646                    if (maxRecents > 0) {
3647                        --maxRecents;
3648                        continue;
3649                    }
3650                    // Hit the maximum number of documents for this task. Fall through
3651                    // and remove this document from recents.
3652                } else if (document || trIsDocument) {
3653                    // Only one of these is a document. Not the droid we're looking for.
3654                    continue;
3655                }
3656            }
3657
3658            // Either task and tr are the same or, their affinities match or their intents match
3659            // and neither of them is a document, or they are documents using the same activity
3660            // and their maxRecents has been reached.
3661            tr.disposeThumbnail();
3662            mRecentTasks.remove(i);
3663            if (task != tr) {
3664                tr.closeRecentsChain();
3665            }
3666            i--;
3667            N--;
3668            if (task.intent == null) {
3669                // If the new recent task we are adding is not fully
3670                // specified, then replace it with the existing recent task.
3671                task = tr;
3672            }
3673            mTaskPersister.notify(tr, false);
3674        }
3675        if (N >= MAX_RECENT_TASKS) {
3676            final TaskRecord tr = mRecentTasks.remove(N - 1);
3677            tr.disposeThumbnail();
3678            tr.closeRecentsChain();
3679        }
3680        mRecentTasks.add(0, task);
3681    }
3682
3683    @Override
3684    public void reportActivityFullyDrawn(IBinder token) {
3685        synchronized (this) {
3686            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3687            if (r == null) {
3688                return;
3689            }
3690            r.reportFullyDrawnLocked();
3691        }
3692    }
3693
3694    @Override
3695    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3696        synchronized (this) {
3697            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3698            if (r == null) {
3699                return;
3700            }
3701            final long origId = Binder.clearCallingIdentity();
3702            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3703            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3704                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3705            if (config != null) {
3706                r.frozenBeforeDestroy = true;
3707                if (!updateConfigurationLocked(config, r, false, false)) {
3708                    mStackSupervisor.resumeTopActivitiesLocked();
3709                }
3710            }
3711            Binder.restoreCallingIdentity(origId);
3712        }
3713    }
3714
3715    @Override
3716    public int getRequestedOrientation(IBinder token) {
3717        synchronized (this) {
3718            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3719            if (r == null) {
3720                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3721            }
3722            return mWindowManager.getAppOrientation(r.appToken);
3723        }
3724    }
3725
3726    /**
3727     * This is the internal entry point for handling Activity.finish().
3728     *
3729     * @param token The Binder token referencing the Activity we want to finish.
3730     * @param resultCode Result code, if any, from this Activity.
3731     * @param resultData Result data (Intent), if any, from this Activity.
3732     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3733     *            the root Activity in the task.
3734     *
3735     * @return Returns true if the activity successfully finished, or false if it is still running.
3736     */
3737    @Override
3738    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3739            boolean finishTask) {
3740        // Refuse possible leaked file descriptors
3741        if (resultData != null && resultData.hasFileDescriptors() == true) {
3742            throw new IllegalArgumentException("File descriptors passed in Intent");
3743        }
3744
3745        synchronized(this) {
3746            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3747            if (r == null) {
3748                return true;
3749            }
3750            // Keep track of the root activity of the task before we finish it
3751            TaskRecord tr = r.task;
3752            ActivityRecord rootR = tr.getRootActivity();
3753            // Do not allow task to finish in Lock Task mode.
3754            if (tr == mStackSupervisor.mLockTaskModeTask) {
3755                if (rootR == r) {
3756                    mStackSupervisor.showLockTaskToast();
3757                    return false;
3758                }
3759            }
3760            if (mController != null) {
3761                // Find the first activity that is not finishing.
3762                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3763                if (next != null) {
3764                    // ask watcher if this is allowed
3765                    boolean resumeOK = true;
3766                    try {
3767                        resumeOK = mController.activityResuming(next.packageName);
3768                    } catch (RemoteException e) {
3769                        mController = null;
3770                        Watchdog.getInstance().setActivityController(null);
3771                    }
3772
3773                    if (!resumeOK) {
3774                        return false;
3775                    }
3776                }
3777            }
3778            final long origId = Binder.clearCallingIdentity();
3779            try {
3780                boolean res;
3781                if (finishTask && r == rootR) {
3782                    // If requested, remove the task that is associated to this activity only if it
3783                    // was the root activity in the task.  The result code and data is ignored because
3784                    // we don't support returning them across task boundaries.
3785                    res = removeTaskByIdLocked(tr.taskId, 0);
3786                } else {
3787                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3788                            resultData, "app-request", true);
3789                }
3790                return res;
3791            } finally {
3792                Binder.restoreCallingIdentity(origId);
3793            }
3794        }
3795    }
3796
3797    @Override
3798    public final void finishHeavyWeightApp() {
3799        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3800                != PackageManager.PERMISSION_GRANTED) {
3801            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3802                    + Binder.getCallingPid()
3803                    + ", uid=" + Binder.getCallingUid()
3804                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3805            Slog.w(TAG, msg);
3806            throw new SecurityException(msg);
3807        }
3808
3809        synchronized(this) {
3810            if (mHeavyWeightProcess == null) {
3811                return;
3812            }
3813
3814            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3815                    mHeavyWeightProcess.activities);
3816            for (int i=0; i<activities.size(); i++) {
3817                ActivityRecord r = activities.get(i);
3818                if (!r.finishing) {
3819                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3820                            null, "finish-heavy", true);
3821                }
3822            }
3823
3824            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3825                    mHeavyWeightProcess.userId, 0));
3826            mHeavyWeightProcess = null;
3827        }
3828    }
3829
3830    @Override
3831    public void crashApplication(int uid, int initialPid, String packageName,
3832            String message) {
3833        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3834                != PackageManager.PERMISSION_GRANTED) {
3835            String msg = "Permission Denial: crashApplication() from pid="
3836                    + Binder.getCallingPid()
3837                    + ", uid=" + Binder.getCallingUid()
3838                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3839            Slog.w(TAG, msg);
3840            throw new SecurityException(msg);
3841        }
3842
3843        synchronized(this) {
3844            ProcessRecord proc = null;
3845
3846            // Figure out which process to kill.  We don't trust that initialPid
3847            // still has any relation to current pids, so must scan through the
3848            // list.
3849            synchronized (mPidsSelfLocked) {
3850                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3851                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3852                    if (p.uid != uid) {
3853                        continue;
3854                    }
3855                    if (p.pid == initialPid) {
3856                        proc = p;
3857                        break;
3858                    }
3859                    if (p.pkgList.containsKey(packageName)) {
3860                        proc = p;
3861                    }
3862                }
3863            }
3864
3865            if (proc == null) {
3866                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3867                        + " initialPid=" + initialPid
3868                        + " packageName=" + packageName);
3869                return;
3870            }
3871
3872            if (proc.thread != null) {
3873                if (proc.pid == Process.myPid()) {
3874                    Log.w(TAG, "crashApplication: trying to crash self!");
3875                    return;
3876                }
3877                long ident = Binder.clearCallingIdentity();
3878                try {
3879                    proc.thread.scheduleCrash(message);
3880                } catch (RemoteException e) {
3881                }
3882                Binder.restoreCallingIdentity(ident);
3883            }
3884        }
3885    }
3886
3887    @Override
3888    public final void finishSubActivity(IBinder token, String resultWho,
3889            int requestCode) {
3890        synchronized(this) {
3891            final long origId = Binder.clearCallingIdentity();
3892            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3893            if (r != null) {
3894                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3895            }
3896            Binder.restoreCallingIdentity(origId);
3897        }
3898    }
3899
3900    @Override
3901    public boolean finishActivityAffinity(IBinder token) {
3902        synchronized(this) {
3903            final long origId = Binder.clearCallingIdentity();
3904            try {
3905                ActivityRecord r = ActivityRecord.isInStackLocked(token);
3906
3907                ActivityRecord rootR = r.task.getRootActivity();
3908                // Do not allow task to finish in Lock Task mode.
3909                if (r.task == mStackSupervisor.mLockTaskModeTask) {
3910                    if (rootR == r) {
3911                        mStackSupervisor.showLockTaskToast();
3912                        return false;
3913                    }
3914                }
3915                boolean res = false;
3916                if (r != null) {
3917                    res = r.task.stack.finishActivityAffinityLocked(r);
3918                }
3919                return res;
3920            } finally {
3921                Binder.restoreCallingIdentity(origId);
3922            }
3923        }
3924    }
3925
3926    @Override
3927    public void finishVoiceTask(IVoiceInteractionSession session) {
3928        synchronized(this) {
3929            final long origId = Binder.clearCallingIdentity();
3930            try {
3931                mStackSupervisor.finishVoiceTask(session);
3932            } finally {
3933                Binder.restoreCallingIdentity(origId);
3934            }
3935        }
3936
3937    }
3938
3939    @Override
3940    public boolean willActivityBeVisible(IBinder token) {
3941        synchronized(this) {
3942            ActivityStack stack = ActivityRecord.getStackLocked(token);
3943            if (stack != null) {
3944                return stack.willActivityBeVisibleLocked(token);
3945            }
3946            return false;
3947        }
3948    }
3949
3950    @Override
3951    public void overridePendingTransition(IBinder token, String packageName,
3952            int enterAnim, int exitAnim) {
3953        synchronized(this) {
3954            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3955            if (self == null) {
3956                return;
3957            }
3958
3959            final long origId = Binder.clearCallingIdentity();
3960
3961            if (self.state == ActivityState.RESUMED
3962                    || self.state == ActivityState.PAUSING) {
3963                mWindowManager.overridePendingAppTransition(packageName,
3964                        enterAnim, exitAnim, null);
3965            }
3966
3967            Binder.restoreCallingIdentity(origId);
3968        }
3969    }
3970
3971    /**
3972     * Main function for removing an existing process from the activity manager
3973     * as a result of that process going away.  Clears out all connections
3974     * to the process.
3975     */
3976    private final void handleAppDiedLocked(ProcessRecord app,
3977            boolean restarting, boolean allowRestart) {
3978        int pid = app.pid;
3979        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3980        if (!restarting) {
3981            removeLruProcessLocked(app);
3982            if (pid > 0) {
3983                ProcessList.remove(pid);
3984            }
3985        }
3986
3987        if (mProfileProc == app) {
3988            clearProfilerLocked();
3989        }
3990
3991        // Remove this application's activities from active lists.
3992        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3993
3994        app.activities.clear();
3995
3996        if (app.instrumentationClass != null) {
3997            Slog.w(TAG, "Crash of app " + app.processName
3998                  + " running instrumentation " + app.instrumentationClass);
3999            Bundle info = new Bundle();
4000            info.putString("shortMsg", "Process crashed.");
4001            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4002        }
4003
4004        if (!restarting) {
4005            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4006                // If there was nothing to resume, and we are not already
4007                // restarting this process, but there is a visible activity that
4008                // is hosted by the process...  then make sure all visible
4009                // activities are running, taking care of restarting this
4010                // process.
4011                if (hasVisibleActivities) {
4012                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4013                }
4014            }
4015        }
4016    }
4017
4018    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4019        IBinder threadBinder = thread.asBinder();
4020        // Find the application record.
4021        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4022            ProcessRecord rec = mLruProcesses.get(i);
4023            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4024                return i;
4025            }
4026        }
4027        return -1;
4028    }
4029
4030    final ProcessRecord getRecordForAppLocked(
4031            IApplicationThread thread) {
4032        if (thread == null) {
4033            return null;
4034        }
4035
4036        int appIndex = getLRURecordIndexForAppLocked(thread);
4037        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4038    }
4039
4040    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4041        // If there are no longer any background processes running,
4042        // and the app that died was not running instrumentation,
4043        // then tell everyone we are now low on memory.
4044        boolean haveBg = false;
4045        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4046            ProcessRecord rec = mLruProcesses.get(i);
4047            if (rec.thread != null
4048                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4049                haveBg = true;
4050                break;
4051            }
4052        }
4053
4054        if (!haveBg) {
4055            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4056            if (doReport) {
4057                long now = SystemClock.uptimeMillis();
4058                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4059                    doReport = false;
4060                } else {
4061                    mLastMemUsageReportTime = now;
4062                }
4063            }
4064            final ArrayList<ProcessMemInfo> memInfos
4065                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4066            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4067            long now = SystemClock.uptimeMillis();
4068            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4069                ProcessRecord rec = mLruProcesses.get(i);
4070                if (rec == dyingProc || rec.thread == null) {
4071                    continue;
4072                }
4073                if (doReport) {
4074                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4075                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4076                }
4077                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4078                    // The low memory report is overriding any current
4079                    // state for a GC request.  Make sure to do
4080                    // heavy/important/visible/foreground processes first.
4081                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4082                        rec.lastRequestedGc = 0;
4083                    } else {
4084                        rec.lastRequestedGc = rec.lastLowMemory;
4085                    }
4086                    rec.reportLowMemory = true;
4087                    rec.lastLowMemory = now;
4088                    mProcessesToGc.remove(rec);
4089                    addProcessToGcListLocked(rec);
4090                }
4091            }
4092            if (doReport) {
4093                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4094                mHandler.sendMessage(msg);
4095            }
4096            scheduleAppGcsLocked();
4097        }
4098    }
4099
4100    final void appDiedLocked(ProcessRecord app, int pid,
4101            IApplicationThread thread) {
4102
4103        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4104        synchronized (stats) {
4105            stats.noteProcessDiedLocked(app.info.uid, pid);
4106        }
4107
4108        Process.killProcessGroup(app.info.uid, pid);
4109
4110        // Clean up already done if the process has been re-started.
4111        if (app.pid == pid && app.thread != null &&
4112                app.thread.asBinder() == thread.asBinder()) {
4113            boolean doLowMem = app.instrumentationClass == null;
4114            boolean doOomAdj = doLowMem;
4115            if (!app.killedByAm) {
4116                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4117                        + ") has died.");
4118                mAllowLowerMemLevel = true;
4119            } else {
4120                // Note that we always want to do oom adj to update our state with the
4121                // new number of procs.
4122                mAllowLowerMemLevel = false;
4123                doLowMem = false;
4124            }
4125            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4126            if (DEBUG_CLEANUP) Slog.v(
4127                TAG, "Dying app: " + app + ", pid: " + pid
4128                + ", thread: " + thread.asBinder());
4129            handleAppDiedLocked(app, false, true);
4130
4131            if (doOomAdj) {
4132                updateOomAdjLocked();
4133            }
4134            if (doLowMem) {
4135                doLowMemReportIfNeededLocked(app);
4136            }
4137        } else if (app.pid != pid) {
4138            // A new process has already been started.
4139            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4140                    + ") has died and restarted (pid " + app.pid + ").");
4141            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4142        } else if (DEBUG_PROCESSES) {
4143            Slog.d(TAG, "Received spurious death notification for thread "
4144                    + thread.asBinder());
4145        }
4146    }
4147
4148    /**
4149     * If a stack trace dump file is configured, dump process stack traces.
4150     * @param clearTraces causes the dump file to be erased prior to the new
4151     *    traces being written, if true; when false, the new traces will be
4152     *    appended to any existing file content.
4153     * @param firstPids of dalvik VM processes to dump stack traces for first
4154     * @param lastPids of dalvik VM processes to dump stack traces for last
4155     * @param nativeProcs optional list of native process names to dump stack crawls
4156     * @return file containing stack traces, or null if no dump file is configured
4157     */
4158    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4159            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4160        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4161        if (tracesPath == null || tracesPath.length() == 0) {
4162            return null;
4163        }
4164
4165        File tracesFile = new File(tracesPath);
4166        try {
4167            File tracesDir = tracesFile.getParentFile();
4168            if (!tracesDir.exists()) {
4169                tracesFile.mkdirs();
4170                if (!SELinux.restorecon(tracesDir)) {
4171                    return null;
4172                }
4173            }
4174            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4175
4176            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4177            tracesFile.createNewFile();
4178            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4179        } catch (IOException e) {
4180            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4181            return null;
4182        }
4183
4184        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4185        return tracesFile;
4186    }
4187
4188    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4189            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4190        // Use a FileObserver to detect when traces finish writing.
4191        // The order of traces is considered important to maintain for legibility.
4192        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4193            @Override
4194            public synchronized void onEvent(int event, String path) { notify(); }
4195        };
4196
4197        try {
4198            observer.startWatching();
4199
4200            // First collect all of the stacks of the most important pids.
4201            if (firstPids != null) {
4202                try {
4203                    int num = firstPids.size();
4204                    for (int i = 0; i < num; i++) {
4205                        synchronized (observer) {
4206                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4207                            observer.wait(200);  // Wait for write-close, give up after 200msec
4208                        }
4209                    }
4210                } catch (InterruptedException e) {
4211                    Log.wtf(TAG, e);
4212                }
4213            }
4214
4215            // Next collect the stacks of the native pids
4216            if (nativeProcs != null) {
4217                int[] pids = Process.getPidsForCommands(nativeProcs);
4218                if (pids != null) {
4219                    for (int pid : pids) {
4220                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4221                    }
4222                }
4223            }
4224
4225            // Lastly, measure CPU usage.
4226            if (processCpuTracker != null) {
4227                processCpuTracker.init();
4228                System.gc();
4229                processCpuTracker.update();
4230                try {
4231                    synchronized (processCpuTracker) {
4232                        processCpuTracker.wait(500); // measure over 1/2 second.
4233                    }
4234                } catch (InterruptedException e) {
4235                }
4236                processCpuTracker.update();
4237
4238                // We'll take the stack crawls of just the top apps using CPU.
4239                final int N = processCpuTracker.countWorkingStats();
4240                int numProcs = 0;
4241                for (int i=0; i<N && numProcs<5; i++) {
4242                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4243                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4244                        numProcs++;
4245                        try {
4246                            synchronized (observer) {
4247                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4248                                observer.wait(200);  // Wait for write-close, give up after 200msec
4249                            }
4250                        } catch (InterruptedException e) {
4251                            Log.wtf(TAG, e);
4252                        }
4253
4254                    }
4255                }
4256            }
4257        } finally {
4258            observer.stopWatching();
4259        }
4260    }
4261
4262    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4263        if (true || IS_USER_BUILD) {
4264            return;
4265        }
4266        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4267        if (tracesPath == null || tracesPath.length() == 0) {
4268            return;
4269        }
4270
4271        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4272        StrictMode.allowThreadDiskWrites();
4273        try {
4274            final File tracesFile = new File(tracesPath);
4275            final File tracesDir = tracesFile.getParentFile();
4276            final File tracesTmp = new File(tracesDir, "__tmp__");
4277            try {
4278                if (!tracesDir.exists()) {
4279                    tracesFile.mkdirs();
4280                    if (!SELinux.restorecon(tracesDir.getPath())) {
4281                        return;
4282                    }
4283                }
4284                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4285
4286                if (tracesFile.exists()) {
4287                    tracesTmp.delete();
4288                    tracesFile.renameTo(tracesTmp);
4289                }
4290                StringBuilder sb = new StringBuilder();
4291                Time tobj = new Time();
4292                tobj.set(System.currentTimeMillis());
4293                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4294                sb.append(": ");
4295                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4296                sb.append(" since ");
4297                sb.append(msg);
4298                FileOutputStream fos = new FileOutputStream(tracesFile);
4299                fos.write(sb.toString().getBytes());
4300                if (app == null) {
4301                    fos.write("\n*** No application process!".getBytes());
4302                }
4303                fos.close();
4304                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4305            } catch (IOException e) {
4306                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4307                return;
4308            }
4309
4310            if (app != null) {
4311                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4312                firstPids.add(app.pid);
4313                dumpStackTraces(tracesPath, firstPids, null, null, null);
4314            }
4315
4316            File lastTracesFile = null;
4317            File curTracesFile = null;
4318            for (int i=9; i>=0; i--) {
4319                String name = String.format(Locale.US, "slow%02d.txt", i);
4320                curTracesFile = new File(tracesDir, name);
4321                if (curTracesFile.exists()) {
4322                    if (lastTracesFile != null) {
4323                        curTracesFile.renameTo(lastTracesFile);
4324                    } else {
4325                        curTracesFile.delete();
4326                    }
4327                }
4328                lastTracesFile = curTracesFile;
4329            }
4330            tracesFile.renameTo(curTracesFile);
4331            if (tracesTmp.exists()) {
4332                tracesTmp.renameTo(tracesFile);
4333            }
4334        } finally {
4335            StrictMode.setThreadPolicy(oldPolicy);
4336        }
4337    }
4338
4339    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4340            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4341        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4342        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4343
4344        if (mController != null) {
4345            try {
4346                // 0 == continue, -1 = kill process immediately
4347                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4348                if (res < 0 && app.pid != MY_PID) {
4349                    Process.killProcess(app.pid);
4350                    Process.killProcessGroup(app.info.uid, app.pid);
4351                }
4352            } catch (RemoteException e) {
4353                mController = null;
4354                Watchdog.getInstance().setActivityController(null);
4355            }
4356        }
4357
4358        long anrTime = SystemClock.uptimeMillis();
4359        if (MONITOR_CPU_USAGE) {
4360            updateCpuStatsNow();
4361        }
4362
4363        synchronized (this) {
4364            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4365            if (mShuttingDown) {
4366                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4367                return;
4368            } else if (app.notResponding) {
4369                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4370                return;
4371            } else if (app.crashing) {
4372                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4373                return;
4374            }
4375
4376            // In case we come through here for the same app before completing
4377            // this one, mark as anring now so we will bail out.
4378            app.notResponding = true;
4379
4380            // Log the ANR to the event log.
4381            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4382                    app.processName, app.info.flags, annotation);
4383
4384            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4385            firstPids.add(app.pid);
4386
4387            int parentPid = app.pid;
4388            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4389            if (parentPid != app.pid) firstPids.add(parentPid);
4390
4391            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4392
4393            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4394                ProcessRecord r = mLruProcesses.get(i);
4395                if (r != null && r.thread != null) {
4396                    int pid = r.pid;
4397                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4398                        if (r.persistent) {
4399                            firstPids.add(pid);
4400                        } else {
4401                            lastPids.put(pid, Boolean.TRUE);
4402                        }
4403                    }
4404                }
4405            }
4406        }
4407
4408        // Log the ANR to the main log.
4409        StringBuilder info = new StringBuilder();
4410        info.setLength(0);
4411        info.append("ANR in ").append(app.processName);
4412        if (activity != null && activity.shortComponentName != null) {
4413            info.append(" (").append(activity.shortComponentName).append(")");
4414        }
4415        info.append("\n");
4416        info.append("PID: ").append(app.pid).append("\n");
4417        if (annotation != null) {
4418            info.append("Reason: ").append(annotation).append("\n");
4419        }
4420        if (parent != null && parent != activity) {
4421            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4422        }
4423
4424        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4425
4426        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4427                NATIVE_STACKS_OF_INTEREST);
4428
4429        String cpuInfo = null;
4430        if (MONITOR_CPU_USAGE) {
4431            updateCpuStatsNow();
4432            synchronized (mProcessCpuThread) {
4433                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4434            }
4435            info.append(processCpuTracker.printCurrentLoad());
4436            info.append(cpuInfo);
4437        }
4438
4439        info.append(processCpuTracker.printCurrentState(anrTime));
4440
4441        Slog.e(TAG, info.toString());
4442        if (tracesFile == null) {
4443            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4444            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4445        }
4446
4447        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4448                cpuInfo, tracesFile, null);
4449
4450        if (mController != null) {
4451            try {
4452                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4453                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4454                if (res != 0) {
4455                    if (res < 0 && app.pid != MY_PID) {
4456                        Process.killProcess(app.pid);
4457                        Process.killProcessGroup(app.info.uid, app.pid);
4458                    } else {
4459                        synchronized (this) {
4460                            mServices.scheduleServiceTimeoutLocked(app);
4461                        }
4462                    }
4463                    return;
4464                }
4465            } catch (RemoteException e) {
4466                mController = null;
4467                Watchdog.getInstance().setActivityController(null);
4468            }
4469        }
4470
4471        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4472        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4473                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4474
4475        synchronized (this) {
4476            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4477                killUnneededProcessLocked(app, "background ANR");
4478                return;
4479            }
4480
4481            // Set the app's notResponding state, and look up the errorReportReceiver
4482            makeAppNotRespondingLocked(app,
4483                    activity != null ? activity.shortComponentName : null,
4484                    annotation != null ? "ANR " + annotation : "ANR",
4485                    info.toString());
4486
4487            // Bring up the infamous App Not Responding dialog
4488            Message msg = Message.obtain();
4489            HashMap<String, Object> map = new HashMap<String, Object>();
4490            msg.what = SHOW_NOT_RESPONDING_MSG;
4491            msg.obj = map;
4492            msg.arg1 = aboveSystem ? 1 : 0;
4493            map.put("app", app);
4494            if (activity != null) {
4495                map.put("activity", activity);
4496            }
4497
4498            mHandler.sendMessage(msg);
4499        }
4500    }
4501
4502    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4503        if (!mLaunchWarningShown) {
4504            mLaunchWarningShown = true;
4505            mHandler.post(new Runnable() {
4506                @Override
4507                public void run() {
4508                    synchronized (ActivityManagerService.this) {
4509                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4510                        d.show();
4511                        mHandler.postDelayed(new Runnable() {
4512                            @Override
4513                            public void run() {
4514                                synchronized (ActivityManagerService.this) {
4515                                    d.dismiss();
4516                                    mLaunchWarningShown = false;
4517                                }
4518                            }
4519                        }, 4000);
4520                    }
4521                }
4522            });
4523        }
4524    }
4525
4526    @Override
4527    public boolean clearApplicationUserData(final String packageName,
4528            final IPackageDataObserver observer, int userId) {
4529        enforceNotIsolatedCaller("clearApplicationUserData");
4530        int uid = Binder.getCallingUid();
4531        int pid = Binder.getCallingPid();
4532        userId = handleIncomingUser(pid, uid,
4533                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4534        long callingId = Binder.clearCallingIdentity();
4535        try {
4536            IPackageManager pm = AppGlobals.getPackageManager();
4537            int pkgUid = -1;
4538            synchronized(this) {
4539                try {
4540                    pkgUid = pm.getPackageUid(packageName, userId);
4541                } catch (RemoteException e) {
4542                }
4543                if (pkgUid == -1) {
4544                    Slog.w(TAG, "Invalid packageName: " + packageName);
4545                    if (observer != null) {
4546                        try {
4547                            observer.onRemoveCompleted(packageName, false);
4548                        } catch (RemoteException e) {
4549                            Slog.i(TAG, "Observer no longer exists.");
4550                        }
4551                    }
4552                    return false;
4553                }
4554                if (uid == pkgUid || checkComponentPermission(
4555                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4556                        pid, uid, -1, true)
4557                        == PackageManager.PERMISSION_GRANTED) {
4558                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4559                } else {
4560                    throw new SecurityException("PID " + pid + " does not have permission "
4561                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4562                                    + " of package " + packageName);
4563                }
4564            }
4565
4566            try {
4567                // Clear application user data
4568                pm.clearApplicationUserData(packageName, observer, userId);
4569
4570                // Remove all permissions granted from/to this package
4571                removeUriPermissionsForPackageLocked(packageName, userId, true);
4572
4573                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4574                        Uri.fromParts("package", packageName, null));
4575                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4576                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4577                        null, null, 0, null, null, null, false, false, userId);
4578            } catch (RemoteException e) {
4579            }
4580        } finally {
4581            Binder.restoreCallingIdentity(callingId);
4582        }
4583        return true;
4584    }
4585
4586    @Override
4587    public void killBackgroundProcesses(final String packageName, int userId) {
4588        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4589                != PackageManager.PERMISSION_GRANTED &&
4590                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4591                        != PackageManager.PERMISSION_GRANTED) {
4592            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4593                    + Binder.getCallingPid()
4594                    + ", uid=" + Binder.getCallingUid()
4595                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4596            Slog.w(TAG, msg);
4597            throw new SecurityException(msg);
4598        }
4599
4600        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4601                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4602        long callingId = Binder.clearCallingIdentity();
4603        try {
4604            IPackageManager pm = AppGlobals.getPackageManager();
4605            synchronized(this) {
4606                int appId = -1;
4607                try {
4608                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4609                } catch (RemoteException e) {
4610                }
4611                if (appId == -1) {
4612                    Slog.w(TAG, "Invalid packageName: " + packageName);
4613                    return;
4614                }
4615                killPackageProcessesLocked(packageName, appId, userId,
4616                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4617            }
4618        } finally {
4619            Binder.restoreCallingIdentity(callingId);
4620        }
4621    }
4622
4623    @Override
4624    public void killAllBackgroundProcesses() {
4625        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4626                != PackageManager.PERMISSION_GRANTED) {
4627            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4628                    + Binder.getCallingPid()
4629                    + ", uid=" + Binder.getCallingUid()
4630                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4631            Slog.w(TAG, msg);
4632            throw new SecurityException(msg);
4633        }
4634
4635        long callingId = Binder.clearCallingIdentity();
4636        try {
4637            synchronized(this) {
4638                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4639                final int NP = mProcessNames.getMap().size();
4640                for (int ip=0; ip<NP; ip++) {
4641                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4642                    final int NA = apps.size();
4643                    for (int ia=0; ia<NA; ia++) {
4644                        ProcessRecord app = apps.valueAt(ia);
4645                        if (app.persistent) {
4646                            // we don't kill persistent processes
4647                            continue;
4648                        }
4649                        if (app.removed) {
4650                            procs.add(app);
4651                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4652                            app.removed = true;
4653                            procs.add(app);
4654                        }
4655                    }
4656                }
4657
4658                int N = procs.size();
4659                for (int i=0; i<N; i++) {
4660                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4661                }
4662                mAllowLowerMemLevel = true;
4663                updateOomAdjLocked();
4664                doLowMemReportIfNeededLocked(null);
4665            }
4666        } finally {
4667            Binder.restoreCallingIdentity(callingId);
4668        }
4669    }
4670
4671    @Override
4672    public void forceStopPackage(final String packageName, int userId) {
4673        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4674                != PackageManager.PERMISSION_GRANTED) {
4675            String msg = "Permission Denial: forceStopPackage() from pid="
4676                    + Binder.getCallingPid()
4677                    + ", uid=" + Binder.getCallingUid()
4678                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4679            Slog.w(TAG, msg);
4680            throw new SecurityException(msg);
4681        }
4682        final int callingPid = Binder.getCallingPid();
4683        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4684                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4685        long callingId = Binder.clearCallingIdentity();
4686        try {
4687            IPackageManager pm = AppGlobals.getPackageManager();
4688            synchronized(this) {
4689                int[] users = userId == UserHandle.USER_ALL
4690                        ? getUsersLocked() : new int[] { userId };
4691                for (int user : users) {
4692                    int pkgUid = -1;
4693                    try {
4694                        pkgUid = pm.getPackageUid(packageName, user);
4695                    } catch (RemoteException e) {
4696                    }
4697                    if (pkgUid == -1) {
4698                        Slog.w(TAG, "Invalid packageName: " + packageName);
4699                        continue;
4700                    }
4701                    try {
4702                        pm.setPackageStoppedState(packageName, true, user);
4703                    } catch (RemoteException e) {
4704                    } catch (IllegalArgumentException e) {
4705                        Slog.w(TAG, "Failed trying to unstop package "
4706                                + packageName + ": " + e);
4707                    }
4708                    if (isUserRunningLocked(user, false)) {
4709                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4710                    }
4711                }
4712            }
4713        } finally {
4714            Binder.restoreCallingIdentity(callingId);
4715        }
4716    }
4717
4718    /*
4719     * The pkg name and app id have to be specified.
4720     */
4721    @Override
4722    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4723        if (pkg == null) {
4724            return;
4725        }
4726        // Make sure the uid is valid.
4727        if (appid < 0) {
4728            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4729            return;
4730        }
4731        int callerUid = Binder.getCallingUid();
4732        // Only the system server can kill an application
4733        if (callerUid == Process.SYSTEM_UID) {
4734            // Post an aysnc message to kill the application
4735            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4736            msg.arg1 = appid;
4737            msg.arg2 = 0;
4738            Bundle bundle = new Bundle();
4739            bundle.putString("pkg", pkg);
4740            bundle.putString("reason", reason);
4741            msg.obj = bundle;
4742            mHandler.sendMessage(msg);
4743        } else {
4744            throw new SecurityException(callerUid + " cannot kill pkg: " +
4745                    pkg);
4746        }
4747    }
4748
4749    @Override
4750    public void closeSystemDialogs(String reason) {
4751        enforceNotIsolatedCaller("closeSystemDialogs");
4752
4753        final int pid = Binder.getCallingPid();
4754        final int uid = Binder.getCallingUid();
4755        final long origId = Binder.clearCallingIdentity();
4756        try {
4757            synchronized (this) {
4758                // Only allow this from foreground processes, so that background
4759                // applications can't abuse it to prevent system UI from being shown.
4760                if (uid >= Process.FIRST_APPLICATION_UID) {
4761                    ProcessRecord proc;
4762                    synchronized (mPidsSelfLocked) {
4763                        proc = mPidsSelfLocked.get(pid);
4764                    }
4765                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4766                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4767                                + " from background process " + proc);
4768                        return;
4769                    }
4770                }
4771                closeSystemDialogsLocked(reason);
4772            }
4773        } finally {
4774            Binder.restoreCallingIdentity(origId);
4775        }
4776    }
4777
4778    void closeSystemDialogsLocked(String reason) {
4779        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4780        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4781                | Intent.FLAG_RECEIVER_FOREGROUND);
4782        if (reason != null) {
4783            intent.putExtra("reason", reason);
4784        }
4785        mWindowManager.closeSystemDialogs(reason);
4786
4787        mStackSupervisor.closeSystemDialogsLocked();
4788
4789        broadcastIntentLocked(null, null, intent, null,
4790                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4791                Process.SYSTEM_UID, UserHandle.USER_ALL);
4792    }
4793
4794    @Override
4795    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4796        enforceNotIsolatedCaller("getProcessMemoryInfo");
4797        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4798        for (int i=pids.length-1; i>=0; i--) {
4799            ProcessRecord proc;
4800            int oomAdj;
4801            synchronized (this) {
4802                synchronized (mPidsSelfLocked) {
4803                    proc = mPidsSelfLocked.get(pids[i]);
4804                    oomAdj = proc != null ? proc.setAdj : 0;
4805                }
4806            }
4807            infos[i] = new Debug.MemoryInfo();
4808            Debug.getMemoryInfo(pids[i], infos[i]);
4809            if (proc != null) {
4810                synchronized (this) {
4811                    if (proc.thread != null && proc.setAdj == oomAdj) {
4812                        // Record this for posterity if the process has been stable.
4813                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4814                                infos[i].getTotalUss(), false, proc.pkgList);
4815                    }
4816                }
4817            }
4818        }
4819        return infos;
4820    }
4821
4822    @Override
4823    public long[] getProcessPss(int[] pids) {
4824        enforceNotIsolatedCaller("getProcessPss");
4825        long[] pss = new long[pids.length];
4826        for (int i=pids.length-1; i>=0; i--) {
4827            ProcessRecord proc;
4828            int oomAdj;
4829            synchronized (this) {
4830                synchronized (mPidsSelfLocked) {
4831                    proc = mPidsSelfLocked.get(pids[i]);
4832                    oomAdj = proc != null ? proc.setAdj : 0;
4833                }
4834            }
4835            long[] tmpUss = new long[1];
4836            pss[i] = Debug.getPss(pids[i], tmpUss);
4837            if (proc != null) {
4838                synchronized (this) {
4839                    if (proc.thread != null && proc.setAdj == oomAdj) {
4840                        // Record this for posterity if the process has been stable.
4841                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4842                    }
4843                }
4844            }
4845        }
4846        return pss;
4847    }
4848
4849    @Override
4850    public void killApplicationProcess(String processName, int uid) {
4851        if (processName == null) {
4852            return;
4853        }
4854
4855        int callerUid = Binder.getCallingUid();
4856        // Only the system server can kill an application
4857        if (callerUid == Process.SYSTEM_UID) {
4858            synchronized (this) {
4859                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4860                if (app != null && app.thread != null) {
4861                    try {
4862                        app.thread.scheduleSuicide();
4863                    } catch (RemoteException e) {
4864                        // If the other end already died, then our work here is done.
4865                    }
4866                } else {
4867                    Slog.w(TAG, "Process/uid not found attempting kill of "
4868                            + processName + " / " + uid);
4869                }
4870            }
4871        } else {
4872            throw new SecurityException(callerUid + " cannot kill app process: " +
4873                    processName);
4874        }
4875    }
4876
4877    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4878        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4879                false, true, false, false, UserHandle.getUserId(uid), reason);
4880        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4881                Uri.fromParts("package", packageName, null));
4882        if (!mProcessesReady) {
4883            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4884                    | Intent.FLAG_RECEIVER_FOREGROUND);
4885        }
4886        intent.putExtra(Intent.EXTRA_UID, uid);
4887        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4888        broadcastIntentLocked(null, null, intent,
4889                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4890                false, false,
4891                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4892    }
4893
4894    private void forceStopUserLocked(int userId, String reason) {
4895        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4896        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4897        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4898                | Intent.FLAG_RECEIVER_FOREGROUND);
4899        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4900        broadcastIntentLocked(null, null, intent,
4901                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4902                false, false,
4903                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4904    }
4905
4906    private final boolean killPackageProcessesLocked(String packageName, int appId,
4907            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4908            boolean doit, boolean evenPersistent, String reason) {
4909        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4910
4911        // Remove all processes this package may have touched: all with the
4912        // same UID (except for the system or root user), and all whose name
4913        // matches the package name.
4914        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4915        final int NP = mProcessNames.getMap().size();
4916        for (int ip=0; ip<NP; ip++) {
4917            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4918            final int NA = apps.size();
4919            for (int ia=0; ia<NA; ia++) {
4920                ProcessRecord app = apps.valueAt(ia);
4921                if (app.persistent && !evenPersistent) {
4922                    // we don't kill persistent processes
4923                    continue;
4924                }
4925                if (app.removed) {
4926                    if (doit) {
4927                        procs.add(app);
4928                    }
4929                    continue;
4930                }
4931
4932                // Skip process if it doesn't meet our oom adj requirement.
4933                if (app.setAdj < minOomAdj) {
4934                    continue;
4935                }
4936
4937                // If no package is specified, we call all processes under the
4938                // give user id.
4939                if (packageName == null) {
4940                    if (app.userId != userId) {
4941                        continue;
4942                    }
4943                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4944                        continue;
4945                    }
4946                // Package has been specified, we want to hit all processes
4947                // that match it.  We need to qualify this by the processes
4948                // that are running under the specified app and user ID.
4949                } else {
4950                    if (UserHandle.getAppId(app.uid) != appId) {
4951                        continue;
4952                    }
4953                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4954                        continue;
4955                    }
4956                    if (!app.pkgList.containsKey(packageName)) {
4957                        continue;
4958                    }
4959                }
4960
4961                // Process has passed all conditions, kill it!
4962                if (!doit) {
4963                    return true;
4964                }
4965                app.removed = true;
4966                procs.add(app);
4967            }
4968        }
4969
4970        int N = procs.size();
4971        for (int i=0; i<N; i++) {
4972            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4973        }
4974        updateOomAdjLocked();
4975        return N > 0;
4976    }
4977
4978    private final boolean forceStopPackageLocked(String name, int appId,
4979            boolean callerWillRestart, boolean purgeCache, boolean doit,
4980            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4981        int i;
4982        int N;
4983
4984        if (userId == UserHandle.USER_ALL && name == null) {
4985            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4986        }
4987
4988        if (appId < 0 && name != null) {
4989            try {
4990                appId = UserHandle.getAppId(
4991                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4992            } catch (RemoteException e) {
4993            }
4994        }
4995
4996        if (doit) {
4997            if (name != null) {
4998                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4999                        + " user=" + userId + ": " + reason);
5000            } else {
5001                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5002            }
5003
5004            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5005            for (int ip=pmap.size()-1; ip>=0; ip--) {
5006                SparseArray<Long> ba = pmap.valueAt(ip);
5007                for (i=ba.size()-1; i>=0; i--) {
5008                    boolean remove = false;
5009                    final int entUid = ba.keyAt(i);
5010                    if (name != null) {
5011                        if (userId == UserHandle.USER_ALL) {
5012                            if (UserHandle.getAppId(entUid) == appId) {
5013                                remove = true;
5014                            }
5015                        } else {
5016                            if (entUid == UserHandle.getUid(userId, appId)) {
5017                                remove = true;
5018                            }
5019                        }
5020                    } else if (UserHandle.getUserId(entUid) == userId) {
5021                        remove = true;
5022                    }
5023                    if (remove) {
5024                        ba.removeAt(i);
5025                    }
5026                }
5027                if (ba.size() == 0) {
5028                    pmap.removeAt(ip);
5029                }
5030            }
5031        }
5032
5033        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5034                -100, callerWillRestart, true, doit, evenPersistent,
5035                name == null ? ("stop user " + userId) : ("stop " + name));
5036
5037        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5038            if (!doit) {
5039                return true;
5040            }
5041            didSomething = true;
5042        }
5043
5044        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5045            if (!doit) {
5046                return true;
5047            }
5048            didSomething = true;
5049        }
5050
5051        if (name == null) {
5052            // Remove all sticky broadcasts from this user.
5053            mStickyBroadcasts.remove(userId);
5054        }
5055
5056        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5057        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5058                userId, providers)) {
5059            if (!doit) {
5060                return true;
5061            }
5062            didSomething = true;
5063        }
5064        N = providers.size();
5065        for (i=0; i<N; i++) {
5066            removeDyingProviderLocked(null, providers.get(i), true);
5067        }
5068
5069        // Remove transient permissions granted from/to this package/user
5070        removeUriPermissionsForPackageLocked(name, userId, false);
5071
5072        if (name == null || uninstalling) {
5073            // Remove pending intents.  For now we only do this when force
5074            // stopping users, because we have some problems when doing this
5075            // for packages -- app widgets are not currently cleaned up for
5076            // such packages, so they can be left with bad pending intents.
5077            if (mIntentSenderRecords.size() > 0) {
5078                Iterator<WeakReference<PendingIntentRecord>> it
5079                        = mIntentSenderRecords.values().iterator();
5080                while (it.hasNext()) {
5081                    WeakReference<PendingIntentRecord> wpir = it.next();
5082                    if (wpir == null) {
5083                        it.remove();
5084                        continue;
5085                    }
5086                    PendingIntentRecord pir = wpir.get();
5087                    if (pir == null) {
5088                        it.remove();
5089                        continue;
5090                    }
5091                    if (name == null) {
5092                        // Stopping user, remove all objects for the user.
5093                        if (pir.key.userId != userId) {
5094                            // Not the same user, skip it.
5095                            continue;
5096                        }
5097                    } else {
5098                        if (UserHandle.getAppId(pir.uid) != appId) {
5099                            // Different app id, skip it.
5100                            continue;
5101                        }
5102                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5103                            // Different user, skip it.
5104                            continue;
5105                        }
5106                        if (!pir.key.packageName.equals(name)) {
5107                            // Different package, skip it.
5108                            continue;
5109                        }
5110                    }
5111                    if (!doit) {
5112                        return true;
5113                    }
5114                    didSomething = true;
5115                    it.remove();
5116                    pir.canceled = true;
5117                    if (pir.key.activity != null) {
5118                        pir.key.activity.pendingResults.remove(pir.ref);
5119                    }
5120                }
5121            }
5122        }
5123
5124        if (doit) {
5125            if (purgeCache && name != null) {
5126                AttributeCache ac = AttributeCache.instance();
5127                if (ac != null) {
5128                    ac.removePackage(name);
5129                }
5130            }
5131            if (mBooted) {
5132                mStackSupervisor.resumeTopActivitiesLocked();
5133                mStackSupervisor.scheduleIdleLocked();
5134            }
5135        }
5136
5137        return didSomething;
5138    }
5139
5140    private final boolean removeProcessLocked(ProcessRecord app,
5141            boolean callerWillRestart, boolean allowRestart, String reason) {
5142        final String name = app.processName;
5143        final int uid = app.uid;
5144        if (DEBUG_PROCESSES) Slog.d(
5145            TAG, "Force removing proc " + app.toShortString() + " (" + name
5146            + "/" + uid + ")");
5147
5148        mProcessNames.remove(name, uid);
5149        mIsolatedProcesses.remove(app.uid);
5150        if (mHeavyWeightProcess == app) {
5151            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5152                    mHeavyWeightProcess.userId, 0));
5153            mHeavyWeightProcess = null;
5154        }
5155        boolean needRestart = false;
5156        if (app.pid > 0 && app.pid != MY_PID) {
5157            int pid = app.pid;
5158            synchronized (mPidsSelfLocked) {
5159                mPidsSelfLocked.remove(pid);
5160                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5161            }
5162            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5163            if (app.isolated) {
5164                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5165            }
5166            killUnneededProcessLocked(app, reason);
5167            Process.killProcessGroup(app.info.uid, app.pid);
5168            handleAppDiedLocked(app, true, allowRestart);
5169            removeLruProcessLocked(app);
5170
5171            if (app.persistent && !app.isolated) {
5172                if (!callerWillRestart) {
5173                    addAppLocked(app.info, false, null /* ABI override */);
5174                } else {
5175                    needRestart = true;
5176                }
5177            }
5178        } else {
5179            mRemovedProcesses.add(app);
5180        }
5181
5182        return needRestart;
5183    }
5184
5185    private final void processStartTimedOutLocked(ProcessRecord app) {
5186        final int pid = app.pid;
5187        boolean gone = false;
5188        synchronized (mPidsSelfLocked) {
5189            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5190            if (knownApp != null && knownApp.thread == null) {
5191                mPidsSelfLocked.remove(pid);
5192                gone = true;
5193            }
5194        }
5195
5196        if (gone) {
5197            Slog.w(TAG, "Process " + app + " failed to attach");
5198            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5199                    pid, app.uid, app.processName);
5200            mProcessNames.remove(app.processName, app.uid);
5201            mIsolatedProcesses.remove(app.uid);
5202            if (mHeavyWeightProcess == app) {
5203                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5204                        mHeavyWeightProcess.userId, 0));
5205                mHeavyWeightProcess = null;
5206            }
5207            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5208            if (app.isolated) {
5209                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5210            }
5211            // Take care of any launching providers waiting for this process.
5212            checkAppInLaunchingProvidersLocked(app, true);
5213            // Take care of any services that are waiting for the process.
5214            mServices.processStartTimedOutLocked(app);
5215            killUnneededProcessLocked(app, "start timeout");
5216            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5217                Slog.w(TAG, "Unattached app died before backup, skipping");
5218                try {
5219                    IBackupManager bm = IBackupManager.Stub.asInterface(
5220                            ServiceManager.getService(Context.BACKUP_SERVICE));
5221                    bm.agentDisconnected(app.info.packageName);
5222                } catch (RemoteException e) {
5223                    // Can't happen; the backup manager is local
5224                }
5225            }
5226            if (isPendingBroadcastProcessLocked(pid)) {
5227                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5228                skipPendingBroadcastLocked(pid);
5229            }
5230        } else {
5231            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5232        }
5233    }
5234
5235    private final boolean attachApplicationLocked(IApplicationThread thread,
5236            int pid) {
5237
5238        // Find the application record that is being attached...  either via
5239        // the pid if we are running in multiple processes, or just pull the
5240        // next app record if we are emulating process with anonymous threads.
5241        ProcessRecord app;
5242        if (pid != MY_PID && pid >= 0) {
5243            synchronized (mPidsSelfLocked) {
5244                app = mPidsSelfLocked.get(pid);
5245            }
5246        } else {
5247            app = null;
5248        }
5249
5250        if (app == null) {
5251            Slog.w(TAG, "No pending application record for pid " + pid
5252                    + " (IApplicationThread " + thread + "); dropping process");
5253            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5254            if (pid > 0 && pid != MY_PID) {
5255                Process.killProcessQuiet(pid);
5256                //TODO: Process.killProcessGroup(app.info.uid, pid);
5257            } else {
5258                try {
5259                    thread.scheduleExit();
5260                } catch (Exception e) {
5261                    // Ignore exceptions.
5262                }
5263            }
5264            return false;
5265        }
5266
5267        // If this application record is still attached to a previous
5268        // process, clean it up now.
5269        if (app.thread != null) {
5270            handleAppDiedLocked(app, true, true);
5271        }
5272
5273        // Tell the process all about itself.
5274
5275        if (localLOGV) Slog.v(
5276                TAG, "Binding process pid " + pid + " to record " + app);
5277
5278        final String processName = app.processName;
5279        try {
5280            AppDeathRecipient adr = new AppDeathRecipient(
5281                    app, pid, thread);
5282            thread.asBinder().linkToDeath(adr, 0);
5283            app.deathRecipient = adr;
5284        } catch (RemoteException e) {
5285            app.resetPackageList(mProcessStats);
5286            startProcessLocked(app, "link fail", processName, null /* ABI override */);
5287            return false;
5288        }
5289
5290        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5291
5292        app.makeActive(thread, mProcessStats);
5293        app.curAdj = app.setAdj = -100;
5294        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5295        app.forcingToForeground = null;
5296        updateProcessForegroundLocked(app, false, false);
5297        app.hasShownUi = false;
5298        app.debugging = false;
5299        app.cached = false;
5300
5301        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5302
5303        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5304        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5305
5306        if (!normalMode) {
5307            Slog.i(TAG, "Launching preboot mode app: " + app);
5308        }
5309
5310        if (localLOGV) Slog.v(
5311            TAG, "New app record " + app
5312            + " thread=" + thread.asBinder() + " pid=" + pid);
5313        try {
5314            int testMode = IApplicationThread.DEBUG_OFF;
5315            if (mDebugApp != null && mDebugApp.equals(processName)) {
5316                testMode = mWaitForDebugger
5317                    ? IApplicationThread.DEBUG_WAIT
5318                    : IApplicationThread.DEBUG_ON;
5319                app.debugging = true;
5320                if (mDebugTransient) {
5321                    mDebugApp = mOrigDebugApp;
5322                    mWaitForDebugger = mOrigWaitForDebugger;
5323                }
5324            }
5325            String profileFile = app.instrumentationProfileFile;
5326            ParcelFileDescriptor profileFd = null;
5327            boolean profileAutoStop = false;
5328            if (mProfileApp != null && mProfileApp.equals(processName)) {
5329                mProfileProc = app;
5330                profileFile = mProfileFile;
5331                profileFd = mProfileFd;
5332                profileAutoStop = mAutoStopProfiler;
5333            }
5334            boolean enableOpenGlTrace = false;
5335            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5336                enableOpenGlTrace = true;
5337                mOpenGlTraceApp = null;
5338            }
5339
5340            // If the app is being launched for restore or full backup, set it up specially
5341            boolean isRestrictedBackupMode = false;
5342            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5343                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5344                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5345                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5346            }
5347
5348            ensurePackageDexOpt(app.instrumentationInfo != null
5349                    ? app.instrumentationInfo.packageName
5350                    : app.info.packageName);
5351            if (app.instrumentationClass != null) {
5352                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5353            }
5354            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5355                    + processName + " with config " + mConfiguration);
5356            ApplicationInfo appInfo = app.instrumentationInfo != null
5357                    ? app.instrumentationInfo : app.info;
5358            app.compat = compatibilityInfoForPackageLocked(appInfo);
5359            if (profileFd != null) {
5360                profileFd = profileFd.dup();
5361            }
5362            thread.bindApplication(processName, appInfo, providers,
5363                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5364                    app.instrumentationArguments, app.instrumentationWatcher,
5365                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5366                    isRestrictedBackupMode || !normalMode, app.persistent,
5367                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5368                    mCoreSettingsObserver.getCoreSettingsLocked());
5369            updateLruProcessLocked(app, false, null);
5370            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5371        } catch (Exception e) {
5372            // todo: Yikes!  What should we do?  For now we will try to
5373            // start another process, but that could easily get us in
5374            // an infinite loop of restarting processes...
5375            Slog.w(TAG, "Exception thrown during bind!", e);
5376
5377            app.resetPackageList(mProcessStats);
5378            app.unlinkDeathRecipient();
5379            startProcessLocked(app, "bind fail", processName, null /* ABI override */);
5380            return false;
5381        }
5382
5383        // Remove this record from the list of starting applications.
5384        mPersistentStartingProcesses.remove(app);
5385        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5386                "Attach application locked removing on hold: " + app);
5387        mProcessesOnHold.remove(app);
5388
5389        boolean badApp = false;
5390        boolean didSomething = false;
5391
5392        // See if the top visible activity is waiting to run in this process...
5393        if (normalMode) {
5394            try {
5395                if (mStackSupervisor.attachApplicationLocked(app)) {
5396                    didSomething = true;
5397                }
5398            } catch (Exception e) {
5399                badApp = true;
5400            }
5401        }
5402
5403        // Find any services that should be running in this process...
5404        if (!badApp) {
5405            try {
5406                didSomething |= mServices.attachApplicationLocked(app, processName);
5407            } catch (Exception e) {
5408                badApp = true;
5409            }
5410        }
5411
5412        // Check if a next-broadcast receiver is in this process...
5413        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5414            try {
5415                didSomething |= sendPendingBroadcastsLocked(app);
5416            } catch (Exception e) {
5417                // If the app died trying to launch the receiver we declare it 'bad'
5418                badApp = true;
5419            }
5420        }
5421
5422        // Check whether the next backup agent is in this process...
5423        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5424            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5425            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5426            try {
5427                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5428                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5429                        mBackupTarget.backupMode);
5430            } catch (Exception e) {
5431                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5432                e.printStackTrace();
5433            }
5434        }
5435
5436        if (badApp) {
5437            // todo: Also need to kill application to deal with all
5438            // kinds of exceptions.
5439            handleAppDiedLocked(app, false, true);
5440            return false;
5441        }
5442
5443        if (!didSomething) {
5444            updateOomAdjLocked();
5445        }
5446
5447        return true;
5448    }
5449
5450    @Override
5451    public final void attachApplication(IApplicationThread thread) {
5452        synchronized (this) {
5453            int callingPid = Binder.getCallingPid();
5454            final long origId = Binder.clearCallingIdentity();
5455            attachApplicationLocked(thread, callingPid);
5456            Binder.restoreCallingIdentity(origId);
5457        }
5458    }
5459
5460    @Override
5461    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5462        final long origId = Binder.clearCallingIdentity();
5463        synchronized (this) {
5464            ActivityStack stack = ActivityRecord.getStackLocked(token);
5465            if (stack != null) {
5466                ActivityRecord r =
5467                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5468                if (stopProfiling) {
5469                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5470                        try {
5471                            mProfileFd.close();
5472                        } catch (IOException e) {
5473                        }
5474                        clearProfilerLocked();
5475                    }
5476                }
5477            }
5478        }
5479        Binder.restoreCallingIdentity(origId);
5480    }
5481
5482    void enableScreenAfterBoot() {
5483        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5484                SystemClock.uptimeMillis());
5485        mWindowManager.enableScreenAfterBoot();
5486
5487        synchronized (this) {
5488            updateEventDispatchingLocked();
5489        }
5490    }
5491
5492    @Override
5493    public void showBootMessage(final CharSequence msg, final boolean always) {
5494        enforceNotIsolatedCaller("showBootMessage");
5495        mWindowManager.showBootMessage(msg, always);
5496    }
5497
5498    @Override
5499    public void dismissKeyguardOnNextActivity() {
5500        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5501        final long token = Binder.clearCallingIdentity();
5502        try {
5503            synchronized (this) {
5504                if (DEBUG_LOCKSCREEN) logLockScreen("");
5505                if (mLockScreenShown) {
5506                    mLockScreenShown = false;
5507                    comeOutOfSleepIfNeededLocked();
5508                }
5509                mStackSupervisor.setDismissKeyguard(true);
5510            }
5511        } finally {
5512            Binder.restoreCallingIdentity(token);
5513        }
5514    }
5515
5516    final void finishBooting() {
5517        // Register receivers to handle package update events
5518        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5519
5520        synchronized (this) {
5521            // Ensure that any processes we had put on hold are now started
5522            // up.
5523            final int NP = mProcessesOnHold.size();
5524            if (NP > 0) {
5525                ArrayList<ProcessRecord> procs =
5526                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5527                for (int ip=0; ip<NP; ip++) {
5528                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5529                            + procs.get(ip));
5530                    startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */);
5531                }
5532            }
5533
5534            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5535                // Start looking for apps that are abusing wake locks.
5536                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5537                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5538                // Tell anyone interested that we are done booting!
5539                SystemProperties.set("sys.boot_completed", "1");
5540                SystemProperties.set("dev.bootcomplete", "1");
5541                for (int i=0; i<mStartedUsers.size(); i++) {
5542                    UserStartedState uss = mStartedUsers.valueAt(i);
5543                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5544                        uss.mState = UserStartedState.STATE_RUNNING;
5545                        final int userId = mStartedUsers.keyAt(i);
5546                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5547                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5548                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5549                        broadcastIntentLocked(null, null, intent, null,
5550                                new IIntentReceiver.Stub() {
5551                                    @Override
5552                                    public void performReceive(Intent intent, int resultCode,
5553                                            String data, Bundle extras, boolean ordered,
5554                                            boolean sticky, int sendingUser) {
5555                                        synchronized (ActivityManagerService.this) {
5556                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5557                                                    true, false);
5558                                        }
5559                                    }
5560                                },
5561                                0, null, null,
5562                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5563                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5564                                userId);
5565                    }
5566                }
5567                scheduleStartProfilesLocked();
5568            }
5569        }
5570    }
5571
5572    final void ensureBootCompleted() {
5573        boolean booting;
5574        boolean enableScreen;
5575        synchronized (this) {
5576            booting = mBooting;
5577            mBooting = false;
5578            enableScreen = !mBooted;
5579            mBooted = true;
5580        }
5581
5582        if (booting) {
5583            finishBooting();
5584        }
5585
5586        if (enableScreen) {
5587            enableScreenAfterBoot();
5588        }
5589    }
5590
5591    @Override
5592    public final void activityResumed(IBinder token) {
5593        final long origId = Binder.clearCallingIdentity();
5594        synchronized(this) {
5595            ActivityStack stack = ActivityRecord.getStackLocked(token);
5596            if (stack != null) {
5597                ActivityRecord.activityResumedLocked(token);
5598            }
5599        }
5600        Binder.restoreCallingIdentity(origId);
5601    }
5602
5603    @Override
5604    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5605        final long origId = Binder.clearCallingIdentity();
5606        synchronized(this) {
5607            ActivityStack stack = ActivityRecord.getStackLocked(token);
5608            if (stack != null) {
5609                stack.activityPausedLocked(token, false, persistentState);
5610            }
5611        }
5612        Binder.restoreCallingIdentity(origId);
5613    }
5614
5615    @Override
5616    public final void activityStopped(IBinder token, Bundle icicle,
5617            PersistableBundle persistentState, CharSequence description) {
5618        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5619
5620        // Refuse possible leaked file descriptors
5621        if (icicle != null && icicle.hasFileDescriptors()) {
5622            throw new IllegalArgumentException("File descriptors passed in Bundle");
5623        }
5624
5625        final long origId = Binder.clearCallingIdentity();
5626
5627        synchronized (this) {
5628            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5629            if (r != null) {
5630                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5631            }
5632        }
5633
5634        trimApplications();
5635
5636        Binder.restoreCallingIdentity(origId);
5637    }
5638
5639    @Override
5640    public final void activityDestroyed(IBinder token) {
5641        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5642        synchronized (this) {
5643            ActivityStack stack = ActivityRecord.getStackLocked(token);
5644            if (stack != null) {
5645                stack.activityDestroyedLocked(token);
5646            }
5647        }
5648    }
5649
5650    @Override
5651    public final void mediaResourcesReleased(IBinder token) {
5652        final long origId = Binder.clearCallingIdentity();
5653        try {
5654            synchronized (this) {
5655                ActivityStack stack = ActivityRecord.getStackLocked(token);
5656                if (stack != null) {
5657                    stack.mediaResourcesReleased(token);
5658                }
5659            }
5660        } finally {
5661            Binder.restoreCallingIdentity(origId);
5662        }
5663    }
5664
5665    @Override
5666    public final void notifyLaunchTaskBehindComplete(IBinder token) {
5667        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
5668    }
5669
5670    @Override
5671    public String getCallingPackage(IBinder token) {
5672        synchronized (this) {
5673            ActivityRecord r = getCallingRecordLocked(token);
5674            return r != null ? r.info.packageName : null;
5675        }
5676    }
5677
5678    @Override
5679    public ComponentName getCallingActivity(IBinder token) {
5680        synchronized (this) {
5681            ActivityRecord r = getCallingRecordLocked(token);
5682            return r != null ? r.intent.getComponent() : null;
5683        }
5684    }
5685
5686    private ActivityRecord getCallingRecordLocked(IBinder token) {
5687        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5688        if (r == null) {
5689            return null;
5690        }
5691        return r.resultTo;
5692    }
5693
5694    @Override
5695    public ComponentName getActivityClassForToken(IBinder token) {
5696        synchronized(this) {
5697            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5698            if (r == null) {
5699                return null;
5700            }
5701            return r.intent.getComponent();
5702        }
5703    }
5704
5705    @Override
5706    public String getPackageForToken(IBinder token) {
5707        synchronized(this) {
5708            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5709            if (r == null) {
5710                return null;
5711            }
5712            return r.packageName;
5713        }
5714    }
5715
5716    @Override
5717    public IIntentSender getIntentSender(int type,
5718            String packageName, IBinder token, String resultWho,
5719            int requestCode, Intent[] intents, String[] resolvedTypes,
5720            int flags, Bundle options, int userId) {
5721        enforceNotIsolatedCaller("getIntentSender");
5722        // Refuse possible leaked file descriptors
5723        if (intents != null) {
5724            if (intents.length < 1) {
5725                throw new IllegalArgumentException("Intents array length must be >= 1");
5726            }
5727            for (int i=0; i<intents.length; i++) {
5728                Intent intent = intents[i];
5729                if (intent != null) {
5730                    if (intent.hasFileDescriptors()) {
5731                        throw new IllegalArgumentException("File descriptors passed in Intent");
5732                    }
5733                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5734                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5735                        throw new IllegalArgumentException(
5736                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5737                    }
5738                    intents[i] = new Intent(intent);
5739                }
5740            }
5741            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5742                throw new IllegalArgumentException(
5743                        "Intent array length does not match resolvedTypes length");
5744            }
5745        }
5746        if (options != null) {
5747            if (options.hasFileDescriptors()) {
5748                throw new IllegalArgumentException("File descriptors passed in options");
5749            }
5750        }
5751
5752        synchronized(this) {
5753            int callingUid = Binder.getCallingUid();
5754            int origUserId = userId;
5755            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5756                    type == ActivityManager.INTENT_SENDER_BROADCAST,
5757                    ALLOW_NON_FULL, "getIntentSender", null);
5758            if (origUserId == UserHandle.USER_CURRENT) {
5759                // We don't want to evaluate this until the pending intent is
5760                // actually executed.  However, we do want to always do the
5761                // security checking for it above.
5762                userId = UserHandle.USER_CURRENT;
5763            }
5764            try {
5765                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5766                    int uid = AppGlobals.getPackageManager()
5767                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5768                    if (!UserHandle.isSameApp(callingUid, uid)) {
5769                        String msg = "Permission Denial: getIntentSender() from pid="
5770                            + Binder.getCallingPid()
5771                            + ", uid=" + Binder.getCallingUid()
5772                            + ", (need uid=" + uid + ")"
5773                            + " is not allowed to send as package " + packageName;
5774                        Slog.w(TAG, msg);
5775                        throw new SecurityException(msg);
5776                    }
5777                }
5778
5779                return getIntentSenderLocked(type, packageName, callingUid, userId,
5780                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5781
5782            } catch (RemoteException e) {
5783                throw new SecurityException(e);
5784            }
5785        }
5786    }
5787
5788    IIntentSender getIntentSenderLocked(int type, String packageName,
5789            int callingUid, int userId, IBinder token, String resultWho,
5790            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5791            Bundle options) {
5792        if (DEBUG_MU)
5793            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5794        ActivityRecord activity = null;
5795        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5796            activity = ActivityRecord.isInStackLocked(token);
5797            if (activity == null) {
5798                return null;
5799            }
5800            if (activity.finishing) {
5801                return null;
5802            }
5803        }
5804
5805        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5806        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5807        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5808        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5809                |PendingIntent.FLAG_UPDATE_CURRENT);
5810
5811        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5812                type, packageName, activity, resultWho,
5813                requestCode, intents, resolvedTypes, flags, options, userId);
5814        WeakReference<PendingIntentRecord> ref;
5815        ref = mIntentSenderRecords.get(key);
5816        PendingIntentRecord rec = ref != null ? ref.get() : null;
5817        if (rec != null) {
5818            if (!cancelCurrent) {
5819                if (updateCurrent) {
5820                    if (rec.key.requestIntent != null) {
5821                        rec.key.requestIntent.replaceExtras(intents != null ?
5822                                intents[intents.length - 1] : null);
5823                    }
5824                    if (intents != null) {
5825                        intents[intents.length-1] = rec.key.requestIntent;
5826                        rec.key.allIntents = intents;
5827                        rec.key.allResolvedTypes = resolvedTypes;
5828                    } else {
5829                        rec.key.allIntents = null;
5830                        rec.key.allResolvedTypes = null;
5831                    }
5832                }
5833                return rec;
5834            }
5835            rec.canceled = true;
5836            mIntentSenderRecords.remove(key);
5837        }
5838        if (noCreate) {
5839            return rec;
5840        }
5841        rec = new PendingIntentRecord(this, key, callingUid);
5842        mIntentSenderRecords.put(key, rec.ref);
5843        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5844            if (activity.pendingResults == null) {
5845                activity.pendingResults
5846                        = new HashSet<WeakReference<PendingIntentRecord>>();
5847            }
5848            activity.pendingResults.add(rec.ref);
5849        }
5850        return rec;
5851    }
5852
5853    @Override
5854    public void cancelIntentSender(IIntentSender sender) {
5855        if (!(sender instanceof PendingIntentRecord)) {
5856            return;
5857        }
5858        synchronized(this) {
5859            PendingIntentRecord rec = (PendingIntentRecord)sender;
5860            try {
5861                int uid = AppGlobals.getPackageManager()
5862                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5863                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5864                    String msg = "Permission Denial: cancelIntentSender() from pid="
5865                        + Binder.getCallingPid()
5866                        + ", uid=" + Binder.getCallingUid()
5867                        + " is not allowed to cancel packges "
5868                        + rec.key.packageName;
5869                    Slog.w(TAG, msg);
5870                    throw new SecurityException(msg);
5871                }
5872            } catch (RemoteException e) {
5873                throw new SecurityException(e);
5874            }
5875            cancelIntentSenderLocked(rec, true);
5876        }
5877    }
5878
5879    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5880        rec.canceled = true;
5881        mIntentSenderRecords.remove(rec.key);
5882        if (cleanActivity && rec.key.activity != null) {
5883            rec.key.activity.pendingResults.remove(rec.ref);
5884        }
5885    }
5886
5887    @Override
5888    public String getPackageForIntentSender(IIntentSender pendingResult) {
5889        if (!(pendingResult instanceof PendingIntentRecord)) {
5890            return null;
5891        }
5892        try {
5893            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5894            return res.key.packageName;
5895        } catch (ClassCastException e) {
5896        }
5897        return null;
5898    }
5899
5900    @Override
5901    public int getUidForIntentSender(IIntentSender sender) {
5902        if (sender instanceof PendingIntentRecord) {
5903            try {
5904                PendingIntentRecord res = (PendingIntentRecord)sender;
5905                return res.uid;
5906            } catch (ClassCastException e) {
5907            }
5908        }
5909        return -1;
5910    }
5911
5912    @Override
5913    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5914        if (!(pendingResult instanceof PendingIntentRecord)) {
5915            return false;
5916        }
5917        try {
5918            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5919            if (res.key.allIntents == null) {
5920                return false;
5921            }
5922            for (int i=0; i<res.key.allIntents.length; i++) {
5923                Intent intent = res.key.allIntents[i];
5924                if (intent.getPackage() != null && intent.getComponent() != null) {
5925                    return false;
5926                }
5927            }
5928            return true;
5929        } catch (ClassCastException e) {
5930        }
5931        return false;
5932    }
5933
5934    @Override
5935    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5936        if (!(pendingResult instanceof PendingIntentRecord)) {
5937            return false;
5938        }
5939        try {
5940            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5941            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5942                return true;
5943            }
5944            return false;
5945        } catch (ClassCastException e) {
5946        }
5947        return false;
5948    }
5949
5950    @Override
5951    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5952        if (!(pendingResult instanceof PendingIntentRecord)) {
5953            return null;
5954        }
5955        try {
5956            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5957            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5958        } catch (ClassCastException e) {
5959        }
5960        return null;
5961    }
5962
5963    @Override
5964    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5965        if (!(pendingResult instanceof PendingIntentRecord)) {
5966            return null;
5967        }
5968        try {
5969            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5970            Intent intent = res.key.requestIntent;
5971            if (intent != null) {
5972                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5973                        || res.lastTagPrefix.equals(prefix))) {
5974                    return res.lastTag;
5975                }
5976                res.lastTagPrefix = prefix;
5977                StringBuilder sb = new StringBuilder(128);
5978                if (prefix != null) {
5979                    sb.append(prefix);
5980                }
5981                if (intent.getAction() != null) {
5982                    sb.append(intent.getAction());
5983                } else if (intent.getComponent() != null) {
5984                    intent.getComponent().appendShortString(sb);
5985                } else {
5986                    sb.append("?");
5987                }
5988                return res.lastTag = sb.toString();
5989            }
5990        } catch (ClassCastException e) {
5991        }
5992        return null;
5993    }
5994
5995    @Override
5996    public void setProcessLimit(int max) {
5997        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5998                "setProcessLimit()");
5999        synchronized (this) {
6000            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6001            mProcessLimitOverride = max;
6002        }
6003        trimApplications();
6004    }
6005
6006    @Override
6007    public int getProcessLimit() {
6008        synchronized (this) {
6009            return mProcessLimitOverride;
6010        }
6011    }
6012
6013    void foregroundTokenDied(ForegroundToken token) {
6014        synchronized (ActivityManagerService.this) {
6015            synchronized (mPidsSelfLocked) {
6016                ForegroundToken cur
6017                    = mForegroundProcesses.get(token.pid);
6018                if (cur != token) {
6019                    return;
6020                }
6021                mForegroundProcesses.remove(token.pid);
6022                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6023                if (pr == null) {
6024                    return;
6025                }
6026                pr.forcingToForeground = null;
6027                updateProcessForegroundLocked(pr, false, false);
6028            }
6029            updateOomAdjLocked();
6030        }
6031    }
6032
6033    @Override
6034    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6035        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6036                "setProcessForeground()");
6037        synchronized(this) {
6038            boolean changed = false;
6039
6040            synchronized (mPidsSelfLocked) {
6041                ProcessRecord pr = mPidsSelfLocked.get(pid);
6042                if (pr == null && isForeground) {
6043                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6044                    return;
6045                }
6046                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6047                if (oldToken != null) {
6048                    oldToken.token.unlinkToDeath(oldToken, 0);
6049                    mForegroundProcesses.remove(pid);
6050                    if (pr != null) {
6051                        pr.forcingToForeground = null;
6052                    }
6053                    changed = true;
6054                }
6055                if (isForeground && token != null) {
6056                    ForegroundToken newToken = new ForegroundToken() {
6057                        @Override
6058                        public void binderDied() {
6059                            foregroundTokenDied(this);
6060                        }
6061                    };
6062                    newToken.pid = pid;
6063                    newToken.token = token;
6064                    try {
6065                        token.linkToDeath(newToken, 0);
6066                        mForegroundProcesses.put(pid, newToken);
6067                        pr.forcingToForeground = token;
6068                        changed = true;
6069                    } catch (RemoteException e) {
6070                        // If the process died while doing this, we will later
6071                        // do the cleanup with the process death link.
6072                    }
6073                }
6074            }
6075
6076            if (changed) {
6077                updateOomAdjLocked();
6078            }
6079        }
6080    }
6081
6082    // =========================================================
6083    // PERMISSIONS
6084    // =========================================================
6085
6086    static class PermissionController extends IPermissionController.Stub {
6087        ActivityManagerService mActivityManagerService;
6088        PermissionController(ActivityManagerService activityManagerService) {
6089            mActivityManagerService = activityManagerService;
6090        }
6091
6092        @Override
6093        public boolean checkPermission(String permission, int pid, int uid) {
6094            return mActivityManagerService.checkPermission(permission, pid,
6095                    uid) == PackageManager.PERMISSION_GRANTED;
6096        }
6097    }
6098
6099    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6100        @Override
6101        public int checkComponentPermission(String permission, int pid, int uid,
6102                int owningUid, boolean exported) {
6103            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6104                    owningUid, exported);
6105        }
6106
6107        @Override
6108        public Object getAMSLock() {
6109            return ActivityManagerService.this;
6110        }
6111    }
6112
6113    /**
6114     * This can be called with or without the global lock held.
6115     */
6116    int checkComponentPermission(String permission, int pid, int uid,
6117            int owningUid, boolean exported) {
6118        // We might be performing an operation on behalf of an indirect binder
6119        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6120        // client identity accordingly before proceeding.
6121        Identity tlsIdentity = sCallerIdentity.get();
6122        if (tlsIdentity != null) {
6123            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6124                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6125            uid = tlsIdentity.uid;
6126            pid = tlsIdentity.pid;
6127        }
6128
6129        if (pid == MY_PID) {
6130            return PackageManager.PERMISSION_GRANTED;
6131        }
6132
6133        return ActivityManager.checkComponentPermission(permission, uid,
6134                owningUid, exported);
6135    }
6136
6137    /**
6138     * As the only public entry point for permissions checking, this method
6139     * can enforce the semantic that requesting a check on a null global
6140     * permission is automatically denied.  (Internally a null permission
6141     * string is used when calling {@link #checkComponentPermission} in cases
6142     * when only uid-based security is needed.)
6143     *
6144     * This can be called with or without the global lock held.
6145     */
6146    @Override
6147    public int checkPermission(String permission, int pid, int uid) {
6148        if (permission == null) {
6149            return PackageManager.PERMISSION_DENIED;
6150        }
6151        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6152    }
6153
6154    /**
6155     * Binder IPC calls go through the public entry point.
6156     * This can be called with or without the global lock held.
6157     */
6158    int checkCallingPermission(String permission) {
6159        return checkPermission(permission,
6160                Binder.getCallingPid(),
6161                UserHandle.getAppId(Binder.getCallingUid()));
6162    }
6163
6164    /**
6165     * This can be called with or without the global lock held.
6166     */
6167    void enforceCallingPermission(String permission, String func) {
6168        if (checkCallingPermission(permission)
6169                == PackageManager.PERMISSION_GRANTED) {
6170            return;
6171        }
6172
6173        String msg = "Permission Denial: " + func + " from pid="
6174                + Binder.getCallingPid()
6175                + ", uid=" + Binder.getCallingUid()
6176                + " requires " + permission;
6177        Slog.w(TAG, msg);
6178        throw new SecurityException(msg);
6179    }
6180
6181    /**
6182     * Determine if UID is holding permissions required to access {@link Uri} in
6183     * the given {@link ProviderInfo}. Final permission checking is always done
6184     * in {@link ContentProvider}.
6185     */
6186    private final boolean checkHoldingPermissionsLocked(
6187            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6188        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6189                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6190        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6191            return false;
6192        }
6193        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6194    }
6195
6196    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6197            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6198        if (pi.applicationInfo.uid == uid) {
6199            return true;
6200        } else if (!pi.exported) {
6201            return false;
6202        }
6203
6204        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6205        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6206        try {
6207            // check if target holds top-level <provider> permissions
6208            if (!readMet && pi.readPermission != null && considerUidPermissions
6209                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6210                readMet = true;
6211            }
6212            if (!writeMet && pi.writePermission != null && considerUidPermissions
6213                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6214                writeMet = true;
6215            }
6216
6217            // track if unprotected read/write is allowed; any denied
6218            // <path-permission> below removes this ability
6219            boolean allowDefaultRead = pi.readPermission == null;
6220            boolean allowDefaultWrite = pi.writePermission == null;
6221
6222            // check if target holds any <path-permission> that match uri
6223            final PathPermission[] pps = pi.pathPermissions;
6224            if (pps != null) {
6225                final String path = grantUri.uri.getPath();
6226                int i = pps.length;
6227                while (i > 0 && (!readMet || !writeMet)) {
6228                    i--;
6229                    PathPermission pp = pps[i];
6230                    if (pp.match(path)) {
6231                        if (!readMet) {
6232                            final String pprperm = pp.getReadPermission();
6233                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6234                                    + pprperm + " for " + pp.getPath()
6235                                    + ": match=" + pp.match(path)
6236                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6237                            if (pprperm != null) {
6238                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6239                                        == PERMISSION_GRANTED) {
6240                                    readMet = true;
6241                                } else {
6242                                    allowDefaultRead = false;
6243                                }
6244                            }
6245                        }
6246                        if (!writeMet) {
6247                            final String ppwperm = pp.getWritePermission();
6248                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6249                                    + ppwperm + " for " + pp.getPath()
6250                                    + ": match=" + pp.match(path)
6251                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6252                            if (ppwperm != null) {
6253                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6254                                        == PERMISSION_GRANTED) {
6255                                    writeMet = true;
6256                                } else {
6257                                    allowDefaultWrite = false;
6258                                }
6259                            }
6260                        }
6261                    }
6262                }
6263            }
6264
6265            // grant unprotected <provider> read/write, if not blocked by
6266            // <path-permission> above
6267            if (allowDefaultRead) readMet = true;
6268            if (allowDefaultWrite) writeMet = true;
6269
6270        } catch (RemoteException e) {
6271            return false;
6272        }
6273
6274        return readMet && writeMet;
6275    }
6276
6277    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6278        ProviderInfo pi = null;
6279        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6280        if (cpr != null) {
6281            pi = cpr.info;
6282        } else {
6283            try {
6284                pi = AppGlobals.getPackageManager().resolveContentProvider(
6285                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6286            } catch (RemoteException ex) {
6287            }
6288        }
6289        return pi;
6290    }
6291
6292    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6293        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6294        if (targetUris != null) {
6295            return targetUris.get(grantUri);
6296        }
6297        return null;
6298    }
6299
6300    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6301            String targetPkg, int targetUid, GrantUri grantUri) {
6302        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6303        if (targetUris == null) {
6304            targetUris = Maps.newArrayMap();
6305            mGrantedUriPermissions.put(targetUid, targetUris);
6306        }
6307
6308        UriPermission perm = targetUris.get(grantUri);
6309        if (perm == null) {
6310            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6311            targetUris.put(grantUri, perm);
6312        }
6313
6314        return perm;
6315    }
6316
6317    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6318            final int modeFlags) {
6319        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6320        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6321                : UriPermission.STRENGTH_OWNED;
6322
6323        // Root gets to do everything.
6324        if (uid == 0) {
6325            return true;
6326        }
6327
6328        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6329        if (perms == null) return false;
6330
6331        // First look for exact match
6332        final UriPermission exactPerm = perms.get(grantUri);
6333        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6334            return true;
6335        }
6336
6337        // No exact match, look for prefixes
6338        final int N = perms.size();
6339        for (int i = 0; i < N; i++) {
6340            final UriPermission perm = perms.valueAt(i);
6341            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6342                    && perm.getStrength(modeFlags) >= minStrength) {
6343                return true;
6344            }
6345        }
6346
6347        return false;
6348    }
6349
6350    @Override
6351    public int checkUriPermission(Uri uri, int pid, int uid,
6352            final int modeFlags, int userId) {
6353        enforceNotIsolatedCaller("checkUriPermission");
6354
6355        // Another redirected-binder-call permissions check as in
6356        // {@link checkComponentPermission}.
6357        Identity tlsIdentity = sCallerIdentity.get();
6358        if (tlsIdentity != null) {
6359            uid = tlsIdentity.uid;
6360            pid = tlsIdentity.pid;
6361        }
6362
6363        // Our own process gets to do everything.
6364        if (pid == MY_PID) {
6365            return PackageManager.PERMISSION_GRANTED;
6366        }
6367        synchronized (this) {
6368            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6369                    ? PackageManager.PERMISSION_GRANTED
6370                    : PackageManager.PERMISSION_DENIED;
6371        }
6372    }
6373
6374    /**
6375     * Check if the targetPkg can be granted permission to access uri by
6376     * the callingUid using the given modeFlags.  Throws a security exception
6377     * if callingUid is not allowed to do this.  Returns the uid of the target
6378     * if the URI permission grant should be performed; returns -1 if it is not
6379     * needed (for example targetPkg already has permission to access the URI).
6380     * If you already know the uid of the target, you can supply it in
6381     * lastTargetUid else set that to -1.
6382     */
6383    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6384            final int modeFlags, int lastTargetUid) {
6385        if (!Intent.isAccessUriMode(modeFlags)) {
6386            return -1;
6387        }
6388
6389        if (targetPkg != null) {
6390            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6391                    "Checking grant " + targetPkg + " permission to " + grantUri);
6392        }
6393
6394        final IPackageManager pm = AppGlobals.getPackageManager();
6395
6396        // If this is not a content: uri, we can't do anything with it.
6397        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6398            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6399                    "Can't grant URI permission for non-content URI: " + grantUri);
6400            return -1;
6401        }
6402
6403        final String authority = grantUri.uri.getAuthority();
6404        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6405        if (pi == null) {
6406            Slog.w(TAG, "No content provider found for permission check: " +
6407                    grantUri.uri.toSafeString());
6408            return -1;
6409        }
6410
6411        int targetUid = lastTargetUid;
6412        if (targetUid < 0 && targetPkg != null) {
6413            try {
6414                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6415                if (targetUid < 0) {
6416                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6417                            "Can't grant URI permission no uid for: " + targetPkg);
6418                    return -1;
6419                }
6420            } catch (RemoteException ex) {
6421                return -1;
6422            }
6423        }
6424
6425        if (targetUid >= 0) {
6426            // First...  does the target actually need this permission?
6427            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6428                // No need to grant the target this permission.
6429                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6430                        "Target " + targetPkg + " already has full permission to " + grantUri);
6431                return -1;
6432            }
6433        } else {
6434            // First...  there is no target package, so can anyone access it?
6435            boolean allowed = pi.exported;
6436            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6437                if (pi.readPermission != null) {
6438                    allowed = false;
6439                }
6440            }
6441            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6442                if (pi.writePermission != null) {
6443                    allowed = false;
6444                }
6445            }
6446            if (allowed) {
6447                return -1;
6448            }
6449        }
6450
6451        /* There is a special cross user grant if:
6452         * - The target is on another user.
6453         * - Apps on the current user can access the uri without any uid permissions.
6454         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6455         * grant uri permissions.
6456         */
6457        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6458                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6459                modeFlags, false /*without considering the uid permissions*/);
6460
6461        // Second...  is the provider allowing granting of URI permissions?
6462        if (!specialCrossUserGrant) {
6463            if (!pi.grantUriPermissions) {
6464                throw new SecurityException("Provider " + pi.packageName
6465                        + "/" + pi.name
6466                        + " does not allow granting of Uri permissions (uri "
6467                        + grantUri + ")");
6468            }
6469            if (pi.uriPermissionPatterns != null) {
6470                final int N = pi.uriPermissionPatterns.length;
6471                boolean allowed = false;
6472                for (int i=0; i<N; i++) {
6473                    if (pi.uriPermissionPatterns[i] != null
6474                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6475                        allowed = true;
6476                        break;
6477                    }
6478                }
6479                if (!allowed) {
6480                    throw new SecurityException("Provider " + pi.packageName
6481                            + "/" + pi.name
6482                            + " does not allow granting of permission to path of Uri "
6483                            + grantUri);
6484                }
6485            }
6486        }
6487
6488        // Third...  does the caller itself have permission to access
6489        // this uri?
6490        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6491            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6492                // Require they hold a strong enough Uri permission
6493                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6494                    throw new SecurityException("Uid " + callingUid
6495                            + " does not have permission to uri " + grantUri);
6496                }
6497            }
6498        }
6499        return targetUid;
6500    }
6501
6502    @Override
6503    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6504            final int modeFlags, int userId) {
6505        enforceNotIsolatedCaller("checkGrantUriPermission");
6506        synchronized(this) {
6507            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6508                    new GrantUri(userId, uri, false), modeFlags, -1);
6509        }
6510    }
6511
6512    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6513            final int modeFlags, UriPermissionOwner owner) {
6514        if (!Intent.isAccessUriMode(modeFlags)) {
6515            return;
6516        }
6517
6518        // So here we are: the caller has the assumed permission
6519        // to the uri, and the target doesn't.  Let's now give this to
6520        // the target.
6521
6522        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6523                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6524
6525        final String authority = grantUri.uri.getAuthority();
6526        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6527        if (pi == null) {
6528            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6529            return;
6530        }
6531
6532        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6533            grantUri.prefix = true;
6534        }
6535        final UriPermission perm = findOrCreateUriPermissionLocked(
6536                pi.packageName, targetPkg, targetUid, grantUri);
6537        perm.grantModes(modeFlags, owner);
6538    }
6539
6540    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6541            final int modeFlags, UriPermissionOwner owner) {
6542        if (targetPkg == null) {
6543            throw new NullPointerException("targetPkg");
6544        }
6545
6546        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6547                -1);
6548        if (targetUid < 0) {
6549            return;
6550        }
6551
6552        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6553                owner);
6554    }
6555
6556    static class NeededUriGrants extends ArrayList<GrantUri> {
6557        final String targetPkg;
6558        final int targetUid;
6559        final int flags;
6560
6561        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6562            this.targetPkg = targetPkg;
6563            this.targetUid = targetUid;
6564            this.flags = flags;
6565        }
6566    }
6567
6568    /**
6569     * Like checkGrantUriPermissionLocked, but takes an Intent.
6570     */
6571    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6572            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6573        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6574                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6575                + " clip=" + (intent != null ? intent.getClipData() : null)
6576                + " from " + intent + "; flags=0x"
6577                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6578
6579        if (targetPkg == null) {
6580            throw new NullPointerException("targetPkg");
6581        }
6582
6583        if (intent == null) {
6584            return null;
6585        }
6586        Uri data = intent.getData();
6587        ClipData clip = intent.getClipData();
6588        if (data == null && clip == null) {
6589            return null;
6590        }
6591        final IPackageManager pm = AppGlobals.getPackageManager();
6592        int targetUid;
6593        if (needed != null) {
6594            targetUid = needed.targetUid;
6595        } else {
6596            try {
6597                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6598            } catch (RemoteException ex) {
6599                return null;
6600            }
6601            if (targetUid < 0) {
6602                if (DEBUG_URI_PERMISSION) {
6603                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6604                            + " on user " + targetUserId);
6605                }
6606                return null;
6607            }
6608        }
6609        if (data != null) {
6610            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6611            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6612                    targetUid);
6613            if (targetUid > 0) {
6614                if (needed == null) {
6615                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6616                }
6617                needed.add(grantUri);
6618            }
6619        }
6620        if (clip != null) {
6621            for (int i=0; i<clip.getItemCount(); i++) {
6622                Uri uri = clip.getItemAt(i).getUri();
6623                if (uri != null) {
6624                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6625                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6626                            targetUid);
6627                    if (targetUid > 0) {
6628                        if (needed == null) {
6629                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6630                        }
6631                        needed.add(grantUri);
6632                    }
6633                } else {
6634                    Intent clipIntent = clip.getItemAt(i).getIntent();
6635                    if (clipIntent != null) {
6636                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6637                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6638                        if (newNeeded != null) {
6639                            needed = newNeeded;
6640                        }
6641                    }
6642                }
6643            }
6644        }
6645
6646        return needed;
6647    }
6648
6649    /**
6650     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6651     */
6652    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6653            UriPermissionOwner owner) {
6654        if (needed != null) {
6655            for (int i=0; i<needed.size(); i++) {
6656                GrantUri grantUri = needed.get(i);
6657                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6658                        grantUri, needed.flags, owner);
6659            }
6660        }
6661    }
6662
6663    void grantUriPermissionFromIntentLocked(int callingUid,
6664            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6665        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6666                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6667        if (needed == null) {
6668            return;
6669        }
6670
6671        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6672    }
6673
6674    @Override
6675    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6676            final int modeFlags, int userId) {
6677        enforceNotIsolatedCaller("grantUriPermission");
6678        GrantUri grantUri = new GrantUri(userId, uri, false);
6679        synchronized(this) {
6680            final ProcessRecord r = getRecordForAppLocked(caller);
6681            if (r == null) {
6682                throw new SecurityException("Unable to find app for caller "
6683                        + caller
6684                        + " when granting permission to uri " + grantUri);
6685            }
6686            if (targetPkg == null) {
6687                throw new IllegalArgumentException("null target");
6688            }
6689            if (grantUri == null) {
6690                throw new IllegalArgumentException("null uri");
6691            }
6692
6693            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6694                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6695                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6696                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6697
6698            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null);
6699        }
6700    }
6701
6702    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6703        if (perm.modeFlags == 0) {
6704            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6705                    perm.targetUid);
6706            if (perms != null) {
6707                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6708                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6709
6710                perms.remove(perm.uri);
6711                if (perms.isEmpty()) {
6712                    mGrantedUriPermissions.remove(perm.targetUid);
6713                }
6714            }
6715        }
6716    }
6717
6718    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6719        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6720
6721        final IPackageManager pm = AppGlobals.getPackageManager();
6722        final String authority = grantUri.uri.getAuthority();
6723        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6724        if (pi == null) {
6725            Slog.w(TAG, "No content provider found for permission revoke: "
6726                    + grantUri.toSafeString());
6727            return;
6728        }
6729
6730        // Does the caller have this permission on the URI?
6731        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6732            // Right now, if you are not the original owner of the permission,
6733            // you are not allowed to revoke it.
6734            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6735                throw new SecurityException("Uid " + callingUid
6736                        + " does not have permission to uri " + grantUri);
6737            //}
6738        }
6739
6740        boolean persistChanged = false;
6741
6742        // Go through all of the permissions and remove any that match.
6743        int N = mGrantedUriPermissions.size();
6744        for (int i = 0; i < N; i++) {
6745            final int targetUid = mGrantedUriPermissions.keyAt(i);
6746            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6747
6748            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6749                final UriPermission perm = it.next();
6750                if (perm.uri.sourceUserId == grantUri.sourceUserId
6751                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6752                    if (DEBUG_URI_PERMISSION)
6753                        Slog.v(TAG,
6754                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6755                    persistChanged |= perm.revokeModes(
6756                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6757                    if (perm.modeFlags == 0) {
6758                        it.remove();
6759                    }
6760                }
6761            }
6762
6763            if (perms.isEmpty()) {
6764                mGrantedUriPermissions.remove(targetUid);
6765                N--;
6766                i--;
6767            }
6768        }
6769
6770        if (persistChanged) {
6771            schedulePersistUriGrants();
6772        }
6773    }
6774
6775    @Override
6776    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6777            int userId) {
6778        enforceNotIsolatedCaller("revokeUriPermission");
6779        synchronized(this) {
6780            final ProcessRecord r = getRecordForAppLocked(caller);
6781            if (r == null) {
6782                throw new SecurityException("Unable to find app for caller "
6783                        + caller
6784                        + " when revoking permission to uri " + uri);
6785            }
6786            if (uri == null) {
6787                Slog.w(TAG, "revokeUriPermission: null uri");
6788                return;
6789            }
6790
6791            if (!Intent.isAccessUriMode(modeFlags)) {
6792                return;
6793            }
6794
6795            final IPackageManager pm = AppGlobals.getPackageManager();
6796            final String authority = uri.getAuthority();
6797            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6798            if (pi == null) {
6799                Slog.w(TAG, "No content provider found for permission revoke: "
6800                        + uri.toSafeString());
6801                return;
6802            }
6803
6804            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6805        }
6806    }
6807
6808    /**
6809     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6810     * given package.
6811     *
6812     * @param packageName Package name to match, or {@code null} to apply to all
6813     *            packages.
6814     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6815     *            to all users.
6816     * @param persistable If persistable grants should be removed.
6817     */
6818    private void removeUriPermissionsForPackageLocked(
6819            String packageName, int userHandle, boolean persistable) {
6820        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6821            throw new IllegalArgumentException("Must narrow by either package or user");
6822        }
6823
6824        boolean persistChanged = false;
6825
6826        int N = mGrantedUriPermissions.size();
6827        for (int i = 0; i < N; i++) {
6828            final int targetUid = mGrantedUriPermissions.keyAt(i);
6829            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6830
6831            // Only inspect grants matching user
6832            if (userHandle == UserHandle.USER_ALL
6833                    || userHandle == UserHandle.getUserId(targetUid)) {
6834                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6835                    final UriPermission perm = it.next();
6836
6837                    // Only inspect grants matching package
6838                    if (packageName == null || perm.sourcePkg.equals(packageName)
6839                            || perm.targetPkg.equals(packageName)) {
6840                        persistChanged |= perm.revokeModes(
6841                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6842
6843                        // Only remove when no modes remain; any persisted grants
6844                        // will keep this alive.
6845                        if (perm.modeFlags == 0) {
6846                            it.remove();
6847                        }
6848                    }
6849                }
6850
6851                if (perms.isEmpty()) {
6852                    mGrantedUriPermissions.remove(targetUid);
6853                    N--;
6854                    i--;
6855                }
6856            }
6857        }
6858
6859        if (persistChanged) {
6860            schedulePersistUriGrants();
6861        }
6862    }
6863
6864    @Override
6865    public IBinder newUriPermissionOwner(String name) {
6866        enforceNotIsolatedCaller("newUriPermissionOwner");
6867        synchronized(this) {
6868            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6869            return owner.getExternalTokenLocked();
6870        }
6871    }
6872
6873    @Override
6874    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6875            final int modeFlags, int userId) {
6876        synchronized(this) {
6877            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6878            if (owner == null) {
6879                throw new IllegalArgumentException("Unknown owner: " + token);
6880            }
6881            if (fromUid != Binder.getCallingUid()) {
6882                if (Binder.getCallingUid() != Process.myUid()) {
6883                    // Only system code can grant URI permissions on behalf
6884                    // of other users.
6885                    throw new SecurityException("nice try");
6886                }
6887            }
6888            if (targetPkg == null) {
6889                throw new IllegalArgumentException("null target");
6890            }
6891            if (uri == null) {
6892                throw new IllegalArgumentException("null uri");
6893            }
6894
6895            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false),
6896                    modeFlags, owner);
6897        }
6898    }
6899
6900    @Override
6901    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6902        synchronized(this) {
6903            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6904            if (owner == null) {
6905                throw new IllegalArgumentException("Unknown owner: " + token);
6906            }
6907
6908            if (uri == null) {
6909                owner.removeUriPermissionsLocked(mode);
6910            } else {
6911                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6912            }
6913        }
6914    }
6915
6916    private void schedulePersistUriGrants() {
6917        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6918            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6919                    10 * DateUtils.SECOND_IN_MILLIS);
6920        }
6921    }
6922
6923    private void writeGrantedUriPermissions() {
6924        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6925
6926        // Snapshot permissions so we can persist without lock
6927        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6928        synchronized (this) {
6929            final int size = mGrantedUriPermissions.size();
6930            for (int i = 0; i < size; i++) {
6931                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6932                for (UriPermission perm : perms.values()) {
6933                    if (perm.persistedModeFlags != 0) {
6934                        persist.add(perm.snapshot());
6935                    }
6936                }
6937            }
6938        }
6939
6940        FileOutputStream fos = null;
6941        try {
6942            fos = mGrantFile.startWrite();
6943
6944            XmlSerializer out = new FastXmlSerializer();
6945            out.setOutput(fos, "utf-8");
6946            out.startDocument(null, true);
6947            out.startTag(null, TAG_URI_GRANTS);
6948            for (UriPermission.Snapshot perm : persist) {
6949                out.startTag(null, TAG_URI_GRANT);
6950                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6951                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6952                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6953                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6954                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6955                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6956                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6957                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6958                out.endTag(null, TAG_URI_GRANT);
6959            }
6960            out.endTag(null, TAG_URI_GRANTS);
6961            out.endDocument();
6962
6963            mGrantFile.finishWrite(fos);
6964        } catch (IOException e) {
6965            if (fos != null) {
6966                mGrantFile.failWrite(fos);
6967            }
6968        }
6969    }
6970
6971    private void readGrantedUriPermissionsLocked() {
6972        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6973
6974        final long now = System.currentTimeMillis();
6975
6976        FileInputStream fis = null;
6977        try {
6978            fis = mGrantFile.openRead();
6979            final XmlPullParser in = Xml.newPullParser();
6980            in.setInput(fis, null);
6981
6982            int type;
6983            while ((type = in.next()) != END_DOCUMENT) {
6984                final String tag = in.getName();
6985                if (type == START_TAG) {
6986                    if (TAG_URI_GRANT.equals(tag)) {
6987                        final int sourceUserId;
6988                        final int targetUserId;
6989                        final int userHandle = readIntAttribute(in,
6990                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
6991                        if (userHandle != UserHandle.USER_NULL) {
6992                            // For backwards compatibility.
6993                            sourceUserId = userHandle;
6994                            targetUserId = userHandle;
6995                        } else {
6996                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
6997                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
6998                        }
6999                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7000                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7001                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7002                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7003                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7004                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7005
7006                        // Sanity check that provider still belongs to source package
7007                        final ProviderInfo pi = getProviderInfoLocked(
7008                                uri.getAuthority(), sourceUserId);
7009                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7010                            int targetUid = -1;
7011                            try {
7012                                targetUid = AppGlobals.getPackageManager()
7013                                        .getPackageUid(targetPkg, targetUserId);
7014                            } catch (RemoteException e) {
7015                            }
7016                            if (targetUid != -1) {
7017                                final UriPermission perm = findOrCreateUriPermissionLocked(
7018                                        sourcePkg, targetPkg, targetUid,
7019                                        new GrantUri(sourceUserId, uri, prefix));
7020                                perm.initPersistedModes(modeFlags, createdTime);
7021                            }
7022                        } else {
7023                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7024                                    + " but instead found " + pi);
7025                        }
7026                    }
7027                }
7028            }
7029        } catch (FileNotFoundException e) {
7030            // Missing grants is okay
7031        } catch (IOException e) {
7032            Log.wtf(TAG, "Failed reading Uri grants", e);
7033        } catch (XmlPullParserException e) {
7034            Log.wtf(TAG, "Failed reading Uri grants", e);
7035        } finally {
7036            IoUtils.closeQuietly(fis);
7037        }
7038    }
7039
7040    @Override
7041    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7042        enforceNotIsolatedCaller("takePersistableUriPermission");
7043
7044        Preconditions.checkFlagsArgument(modeFlags,
7045                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7046
7047        synchronized (this) {
7048            final int callingUid = Binder.getCallingUid();
7049            boolean persistChanged = false;
7050            GrantUri grantUri = new GrantUri(userId, uri, false);
7051
7052            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7053                    new GrantUri(userId, uri, false));
7054            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7055                    new GrantUri(userId, uri, true));
7056
7057            final boolean exactValid = (exactPerm != null)
7058                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7059            final boolean prefixValid = (prefixPerm != null)
7060                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7061
7062            if (!(exactValid || prefixValid)) {
7063                throw new SecurityException("No persistable permission grants found for UID "
7064                        + callingUid + " and Uri " + grantUri.toSafeString());
7065            }
7066
7067            if (exactValid) {
7068                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7069            }
7070            if (prefixValid) {
7071                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7072            }
7073
7074            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7075
7076            if (persistChanged) {
7077                schedulePersistUriGrants();
7078            }
7079        }
7080    }
7081
7082    @Override
7083    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7084        enforceNotIsolatedCaller("releasePersistableUriPermission");
7085
7086        Preconditions.checkFlagsArgument(modeFlags,
7087                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7088
7089        synchronized (this) {
7090            final int callingUid = Binder.getCallingUid();
7091            boolean persistChanged = false;
7092
7093            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7094                    new GrantUri(userId, uri, false));
7095            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7096                    new GrantUri(userId, uri, true));
7097            if (exactPerm == null && prefixPerm == null) {
7098                throw new SecurityException("No permission grants found for UID " + callingUid
7099                        + " and Uri " + uri.toSafeString());
7100            }
7101
7102            if (exactPerm != null) {
7103                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7104                removeUriPermissionIfNeededLocked(exactPerm);
7105            }
7106            if (prefixPerm != null) {
7107                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7108                removeUriPermissionIfNeededLocked(prefixPerm);
7109            }
7110
7111            if (persistChanged) {
7112                schedulePersistUriGrants();
7113            }
7114        }
7115    }
7116
7117    /**
7118     * Prune any older {@link UriPermission} for the given UID until outstanding
7119     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7120     *
7121     * @return if any mutations occured that require persisting.
7122     */
7123    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7124        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7125        if (perms == null) return false;
7126        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7127
7128        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7129        for (UriPermission perm : perms.values()) {
7130            if (perm.persistedModeFlags != 0) {
7131                persisted.add(perm);
7132            }
7133        }
7134
7135        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7136        if (trimCount <= 0) return false;
7137
7138        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7139        for (int i = 0; i < trimCount; i++) {
7140            final UriPermission perm = persisted.get(i);
7141
7142            if (DEBUG_URI_PERMISSION) {
7143                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7144            }
7145
7146            perm.releasePersistableModes(~0);
7147            removeUriPermissionIfNeededLocked(perm);
7148        }
7149
7150        return true;
7151    }
7152
7153    @Override
7154    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7155            String packageName, boolean incoming) {
7156        enforceNotIsolatedCaller("getPersistedUriPermissions");
7157        Preconditions.checkNotNull(packageName, "packageName");
7158
7159        final int callingUid = Binder.getCallingUid();
7160        final IPackageManager pm = AppGlobals.getPackageManager();
7161        try {
7162            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7163            if (packageUid != callingUid) {
7164                throw new SecurityException(
7165                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7166            }
7167        } catch (RemoteException e) {
7168            throw new SecurityException("Failed to verify package name ownership");
7169        }
7170
7171        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7172        synchronized (this) {
7173            if (incoming) {
7174                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7175                        callingUid);
7176                if (perms == null) {
7177                    Slog.w(TAG, "No permission grants found for " + packageName);
7178                } else {
7179                    for (UriPermission perm : perms.values()) {
7180                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7181                            result.add(perm.buildPersistedPublicApiObject());
7182                        }
7183                    }
7184                }
7185            } else {
7186                final int size = mGrantedUriPermissions.size();
7187                for (int i = 0; i < size; i++) {
7188                    final ArrayMap<GrantUri, UriPermission> perms =
7189                            mGrantedUriPermissions.valueAt(i);
7190                    for (UriPermission perm : perms.values()) {
7191                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7192                            result.add(perm.buildPersistedPublicApiObject());
7193                        }
7194                    }
7195                }
7196            }
7197        }
7198        return new ParceledListSlice<android.content.UriPermission>(result);
7199    }
7200
7201    @Override
7202    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7203        synchronized (this) {
7204            ProcessRecord app =
7205                who != null ? getRecordForAppLocked(who) : null;
7206            if (app == null) return;
7207
7208            Message msg = Message.obtain();
7209            msg.what = WAIT_FOR_DEBUGGER_MSG;
7210            msg.obj = app;
7211            msg.arg1 = waiting ? 1 : 0;
7212            mHandler.sendMessage(msg);
7213        }
7214    }
7215
7216    @Override
7217    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7218        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7219        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7220        outInfo.availMem = Process.getFreeMemory();
7221        outInfo.totalMem = Process.getTotalMemory();
7222        outInfo.threshold = homeAppMem;
7223        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7224        outInfo.hiddenAppThreshold = cachedAppMem;
7225        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7226                ProcessList.SERVICE_ADJ);
7227        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7228                ProcessList.VISIBLE_APP_ADJ);
7229        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7230                ProcessList.FOREGROUND_APP_ADJ);
7231    }
7232
7233    // =========================================================
7234    // TASK MANAGEMENT
7235    // =========================================================
7236
7237    @Override
7238    public List<IAppTask> getAppTasks() {
7239        final PackageManager pm = mContext.getPackageManager();
7240        int callingUid = Binder.getCallingUid();
7241        long ident = Binder.clearCallingIdentity();
7242
7243        // Compose the list of packages for this id to test against
7244        HashSet<String> packages = new HashSet<String>();
7245        String[] uidPackages = pm.getPackagesForUid(callingUid);
7246        for (int i = 0; i < uidPackages.length; i++) {
7247            packages.add(uidPackages[i]);
7248        }
7249
7250        synchronized(this) {
7251            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7252            try {
7253                if (localLOGV) Slog.v(TAG, "getAppTasks");
7254
7255                final int N = mRecentTasks.size();
7256                for (int i = 0; i < N; i++) {
7257                    TaskRecord tr = mRecentTasks.get(i);
7258                    // Skip tasks that are not created by the caller
7259                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
7260                        ActivityManager.RecentTaskInfo taskInfo =
7261                                createRecentTaskInfoFromTaskRecord(tr);
7262                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7263                        list.add(taskImpl);
7264                    }
7265                }
7266            } finally {
7267                Binder.restoreCallingIdentity(ident);
7268            }
7269            return list;
7270        }
7271    }
7272
7273    @Override
7274    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7275        final int callingUid = Binder.getCallingUid();
7276        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7277
7278        synchronized(this) {
7279            if (localLOGV) Slog.v(
7280                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7281
7282            final boolean allowed = checkCallingPermission(
7283                    android.Manifest.permission.GET_TASKS)
7284                    == PackageManager.PERMISSION_GRANTED;
7285            if (!allowed) {
7286                Slog.w(TAG, "getTasks: caller " + callingUid
7287                        + " does not hold GET_TASKS; limiting output");
7288            }
7289
7290            // TODO: Improve with MRU list from all ActivityStacks.
7291            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7292        }
7293
7294        return list;
7295    }
7296
7297    TaskRecord getMostRecentTask() {
7298        return mRecentTasks.get(0);
7299    }
7300
7301    /**
7302     * Creates a new RecentTaskInfo from a TaskRecord.
7303     */
7304    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7305        // Update the task description to reflect any changes in the task stack
7306        tr.updateTaskDescription();
7307
7308        // Compose the recent task info
7309        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7310        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7311        rti.persistentId = tr.taskId;
7312        rti.baseIntent = new Intent(tr.getBaseIntent());
7313        rti.origActivity = tr.origActivity;
7314        rti.description = tr.lastDescription;
7315        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7316        rti.userId = tr.userId;
7317        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7318        rti.firstActiveTime = tr.firstActiveTime;
7319        rti.lastActiveTime = tr.lastActiveTime;
7320        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7321        return rti;
7322    }
7323
7324    @Override
7325    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7326        final int callingUid = Binder.getCallingUid();
7327        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7328                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7329
7330        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7331        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7332        synchronized (this) {
7333            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
7334                    == PackageManager.PERMISSION_GRANTED;
7335            if (!allowed) {
7336                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7337                        + " does not hold GET_TASKS; limiting output");
7338            }
7339            final boolean detailed = checkCallingPermission(
7340                    android.Manifest.permission.GET_DETAILED_TASKS)
7341                    == PackageManager.PERMISSION_GRANTED;
7342
7343            IPackageManager pm = AppGlobals.getPackageManager();
7344
7345            final int N = mRecentTasks.size();
7346            ArrayList<ActivityManager.RecentTaskInfo> res
7347                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7348                            maxNum < N ? maxNum : N);
7349
7350            final Set<Integer> includedUsers;
7351            if (includeProfiles) {
7352                includedUsers = getProfileIdsLocked(userId);
7353            } else {
7354                includedUsers = new HashSet<Integer>();
7355            }
7356            includedUsers.add(Integer.valueOf(userId));
7357
7358            // Regroup affiliated tasks together.
7359            for (int i = 0; i < N; ) {
7360                TaskRecord task = mRecentTasks.remove(i);
7361                if (mTmpRecents.contains(task)) {
7362                    continue;
7363                }
7364                int affiliatedTaskId = task.mAffiliatedTaskId;
7365                while (true) {
7366                    TaskRecord next = task.mNextAffiliate;
7367                    if (next == null) {
7368                        break;
7369                    }
7370                    if (next.mAffiliatedTaskId != affiliatedTaskId) {
7371                        Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
7372                                next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
7373                        task.setNextAffiliate(null);
7374                        if (next.mPrevAffiliate == task) {
7375                            next.setPrevAffiliate(null);
7376                        }
7377                        break;
7378                    }
7379                    if (next.mPrevAffiliate != task) {
7380                        Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
7381                                next.mPrevAffiliate + " task=" + task);
7382                        next.setPrevAffiliate(null);
7383                        break;
7384                    }
7385                    if (!mRecentTasks.contains(next)) {
7386                        Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
7387                        task.setNextAffiliate(null);
7388                        if (next.mPrevAffiliate == task) {
7389                            next.setPrevAffiliate(null);
7390                        }
7391                        break;
7392                    }
7393                    task = next;
7394                }
7395                // task is now the end of the list
7396                do {
7397                    mRecentTasks.remove(task);
7398                    mRecentTasks.add(i++, task);
7399                    mTmpRecents.add(task);
7400                } while ((task = task.mPrevAffiliate) != null);
7401            }
7402            mTmpRecents.clear();
7403            // mRecentTasks is now in sorted, affiliated order.
7404
7405            for (int i=0; i<N && maxNum > 0; i++) {
7406                TaskRecord tr = mRecentTasks.get(i);
7407                // Only add calling user or related users recent tasks
7408                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7409
7410                // Return the entry if desired by the caller.  We always return
7411                // the first entry, because callers always expect this to be the
7412                // foreground app.  We may filter others if the caller has
7413                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7414                // we should exclude the entry.
7415
7416                if (i == 0
7417                        || withExcluded
7418                        || (tr.intent == null)
7419                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7420                                == 0)) {
7421                    if (!allowed) {
7422                        // If the caller doesn't have the GET_TASKS permission, then only
7423                        // allow them to see a small subset of tasks -- their own and home.
7424                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7425                            continue;
7426                        }
7427                    }
7428                    if (tr.intent != null &&
7429                            (tr.intent.getFlags() & Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS)
7430                            != 0 && tr.getTopActivity() == null) {
7431                        // Don't include auto remove tasks that are finished or finishing.
7432                        continue;
7433                    }
7434
7435                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7436                    if (!detailed) {
7437                        rti.baseIntent.replaceExtras((Bundle)null);
7438                    }
7439
7440                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7441                        // Check whether this activity is currently available.
7442                        try {
7443                            if (rti.origActivity != null) {
7444                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7445                                        == null) {
7446                                    continue;
7447                                }
7448                            } else if (rti.baseIntent != null) {
7449                                if (pm.queryIntentActivities(rti.baseIntent,
7450                                        null, 0, userId) == null) {
7451                                    continue;
7452                                }
7453                            }
7454                        } catch (RemoteException e) {
7455                            // Will never happen.
7456                        }
7457                    }
7458
7459                    res.add(rti);
7460                    maxNum--;
7461                }
7462            }
7463            return res;
7464        }
7465    }
7466
7467    private TaskRecord recentTaskForIdLocked(int id) {
7468        final int N = mRecentTasks.size();
7469            for (int i=0; i<N; i++) {
7470                TaskRecord tr = mRecentTasks.get(i);
7471                if (tr.taskId == id) {
7472                    return tr;
7473                }
7474            }
7475            return null;
7476    }
7477
7478    @Override
7479    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7480        synchronized (this) {
7481            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7482                    "getTaskThumbnail()");
7483            TaskRecord tr = recentTaskForIdLocked(id);
7484            if (tr != null) {
7485                return tr.getTaskThumbnailLocked();
7486            }
7487        }
7488        return null;
7489    }
7490
7491    @Override
7492    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7493        synchronized (this) {
7494            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7495            if (r != null) {
7496                r.taskDescription = td;
7497                r.task.updateTaskDescription();
7498            }
7499        }
7500    }
7501
7502    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7503        if (!pr.killedByAm) {
7504            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7505            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7506                    pr.processName, pr.setAdj, reason);
7507            pr.killedByAm = true;
7508            Process.killProcessQuiet(pr.pid);
7509            Process.killProcessGroup(pr.info.uid, pr.pid);
7510        }
7511    }
7512
7513    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7514        tr.disposeThumbnail();
7515        mRecentTasks.remove(tr);
7516        tr.closeRecentsChain();
7517        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7518        Intent baseIntent = new Intent(
7519                tr.intent != null ? tr.intent : tr.affinityIntent);
7520        ComponentName component = baseIntent.getComponent();
7521        if (component == null) {
7522            Slog.w(TAG, "Now component for base intent of task: " + tr);
7523            return;
7524        }
7525
7526        // Find any running services associated with this app.
7527        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7528
7529        if (killProcesses) {
7530            // Find any running processes associated with this app.
7531            final String pkg = component.getPackageName();
7532            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7533            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7534            for (int i=0; i<pmap.size(); i++) {
7535                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7536                for (int j=0; j<uids.size(); j++) {
7537                    ProcessRecord proc = uids.valueAt(j);
7538                    if (proc.userId != tr.userId) {
7539                        continue;
7540                    }
7541                    if (!proc.pkgList.containsKey(pkg)) {
7542                        continue;
7543                    }
7544                    procs.add(proc);
7545                }
7546            }
7547
7548            // Kill the running processes.
7549            for (int i=0; i<procs.size(); i++) {
7550                ProcessRecord pr = procs.get(i);
7551                if (pr == mHomeProcess) {
7552                    // Don't kill the home process along with tasks from the same package.
7553                    continue;
7554                }
7555                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7556                    killUnneededProcessLocked(pr, "remove task");
7557                } else {
7558                    pr.waitingToKill = "remove task";
7559                }
7560            }
7561        }
7562    }
7563
7564    /**
7565     * Removes the task with the specified task id.
7566     *
7567     * @param taskId Identifier of the task to be removed.
7568     * @param flags Additional operational flags.  May be 0 or
7569     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7570     * @return Returns true if the given task was found and removed.
7571     */
7572    private boolean removeTaskByIdLocked(int taskId, int flags) {
7573        TaskRecord tr = recentTaskForIdLocked(taskId);
7574        if (tr != null) {
7575            tr.removeTaskActivitiesLocked();
7576            cleanUpRemovedTaskLocked(tr, flags);
7577            if (tr.isPersistable) {
7578                notifyTaskPersisterLocked(tr, true);
7579            }
7580            return true;
7581        }
7582        return false;
7583    }
7584
7585    @Override
7586    public boolean removeTask(int taskId, int flags) {
7587        synchronized (this) {
7588            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7589                    "removeTask()");
7590            long ident = Binder.clearCallingIdentity();
7591            try {
7592                return removeTaskByIdLocked(taskId, flags);
7593            } finally {
7594                Binder.restoreCallingIdentity(ident);
7595            }
7596        }
7597    }
7598
7599    /**
7600     * TODO: Add mController hook
7601     */
7602    @Override
7603    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7604        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7605                "moveTaskToFront()");
7606
7607        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7608        synchronized(this) {
7609            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7610                    Binder.getCallingUid(), "Task to front")) {
7611                ActivityOptions.abort(options);
7612                return;
7613            }
7614            final long origId = Binder.clearCallingIdentity();
7615            try {
7616                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7617                if (task == null) {
7618                    return;
7619                }
7620                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7621                    mStackSupervisor.showLockTaskToast();
7622                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7623                    return;
7624                }
7625                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7626                if (prev != null && prev.isRecentsActivity()) {
7627                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7628                }
7629                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7630            } finally {
7631                Binder.restoreCallingIdentity(origId);
7632            }
7633            ActivityOptions.abort(options);
7634        }
7635    }
7636
7637    @Override
7638    public void moveTaskToBack(int taskId) {
7639        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7640                "moveTaskToBack()");
7641
7642        synchronized(this) {
7643            TaskRecord tr = recentTaskForIdLocked(taskId);
7644            if (tr != null) {
7645                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7646                ActivityStack stack = tr.stack;
7647                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7648                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7649                            Binder.getCallingUid(), "Task to back")) {
7650                        return;
7651                    }
7652                }
7653                final long origId = Binder.clearCallingIdentity();
7654                try {
7655                    stack.moveTaskToBackLocked(taskId, null);
7656                } finally {
7657                    Binder.restoreCallingIdentity(origId);
7658                }
7659            }
7660        }
7661    }
7662
7663    /**
7664     * Moves an activity, and all of the other activities within the same task, to the bottom
7665     * of the history stack.  The activity's order within the task is unchanged.
7666     *
7667     * @param token A reference to the activity we wish to move
7668     * @param nonRoot If false then this only works if the activity is the root
7669     *                of a task; if true it will work for any activity in a task.
7670     * @return Returns true if the move completed, false if not.
7671     */
7672    @Override
7673    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7674        enforceNotIsolatedCaller("moveActivityTaskToBack");
7675        synchronized(this) {
7676            final long origId = Binder.clearCallingIdentity();
7677            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7678            if (taskId >= 0) {
7679                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7680            }
7681            Binder.restoreCallingIdentity(origId);
7682        }
7683        return false;
7684    }
7685
7686    @Override
7687    public void moveTaskBackwards(int task) {
7688        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7689                "moveTaskBackwards()");
7690
7691        synchronized(this) {
7692            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7693                    Binder.getCallingUid(), "Task backwards")) {
7694                return;
7695            }
7696            final long origId = Binder.clearCallingIdentity();
7697            moveTaskBackwardsLocked(task);
7698            Binder.restoreCallingIdentity(origId);
7699        }
7700    }
7701
7702    private final void moveTaskBackwardsLocked(int task) {
7703        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7704    }
7705
7706    @Override
7707    public IBinder getHomeActivityToken() throws RemoteException {
7708        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7709                "getHomeActivityToken()");
7710        synchronized (this) {
7711            return mStackSupervisor.getHomeActivityToken();
7712        }
7713    }
7714
7715    @Override
7716    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7717            IActivityContainerCallback callback) throws RemoteException {
7718        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7719                "createActivityContainer()");
7720        synchronized (this) {
7721            if (parentActivityToken == null) {
7722                throw new IllegalArgumentException("parent token must not be null");
7723            }
7724            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7725            if (r == null) {
7726                return null;
7727            }
7728            if (callback == null) {
7729                throw new IllegalArgumentException("callback must not be null");
7730            }
7731            return mStackSupervisor.createActivityContainer(r, callback);
7732        }
7733    }
7734
7735    @Override
7736    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7737        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7738                "deleteActivityContainer()");
7739        synchronized (this) {
7740            mStackSupervisor.deleteActivityContainer(container);
7741        }
7742    }
7743
7744    @Override
7745    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7746            throws RemoteException {
7747        synchronized (this) {
7748            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7749            if (stack != null) {
7750                return stack.mActivityContainer;
7751            }
7752            return null;
7753        }
7754    }
7755
7756    @Override
7757    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7758        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7759                "moveTaskToStack()");
7760        if (stackId == HOME_STACK_ID) {
7761            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7762                    new RuntimeException("here").fillInStackTrace());
7763        }
7764        synchronized (this) {
7765            long ident = Binder.clearCallingIdentity();
7766            try {
7767                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7768                        + stackId + " toTop=" + toTop);
7769                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7770            } finally {
7771                Binder.restoreCallingIdentity(ident);
7772            }
7773        }
7774    }
7775
7776    @Override
7777    public void resizeStack(int stackBoxId, Rect bounds) {
7778        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7779                "resizeStackBox()");
7780        long ident = Binder.clearCallingIdentity();
7781        try {
7782            mWindowManager.resizeStack(stackBoxId, bounds);
7783        } finally {
7784            Binder.restoreCallingIdentity(ident);
7785        }
7786    }
7787
7788    @Override
7789    public List<StackInfo> getAllStackInfos() {
7790        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7791                "getAllStackInfos()");
7792        long ident = Binder.clearCallingIdentity();
7793        try {
7794            synchronized (this) {
7795                return mStackSupervisor.getAllStackInfosLocked();
7796            }
7797        } finally {
7798            Binder.restoreCallingIdentity(ident);
7799        }
7800    }
7801
7802    @Override
7803    public StackInfo getStackInfo(int stackId) {
7804        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7805                "getStackInfo()");
7806        long ident = Binder.clearCallingIdentity();
7807        try {
7808            synchronized (this) {
7809                return mStackSupervisor.getStackInfoLocked(stackId);
7810            }
7811        } finally {
7812            Binder.restoreCallingIdentity(ident);
7813        }
7814    }
7815
7816    @Override
7817    public boolean isInHomeStack(int taskId) {
7818        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7819                "getStackInfo()");
7820        long ident = Binder.clearCallingIdentity();
7821        try {
7822            synchronized (this) {
7823                TaskRecord tr = recentTaskForIdLocked(taskId);
7824                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7825            }
7826        } finally {
7827            Binder.restoreCallingIdentity(ident);
7828        }
7829    }
7830
7831    @Override
7832    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7833        synchronized(this) {
7834            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7835        }
7836    }
7837
7838    private boolean isLockTaskAuthorized(String pkg) {
7839        final DevicePolicyManager dpm = (DevicePolicyManager)
7840                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7841        try {
7842            int uid = mContext.getPackageManager().getPackageUid(pkg,
7843                    Binder.getCallingUserHandle().getIdentifier());
7844            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7845        } catch (NameNotFoundException e) {
7846            return false;
7847        }
7848    }
7849
7850    void startLockTaskMode(TaskRecord task) {
7851        final String pkg;
7852        synchronized (this) {
7853            pkg = task.intent.getComponent().getPackageName();
7854        }
7855        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
7856        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
7857            final TaskRecord taskRecord = task;
7858            mHandler.post(new Runnable() {
7859                @Override
7860                public void run() {
7861                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
7862                }
7863            });
7864            return;
7865        }
7866        long ident = Binder.clearCallingIdentity();
7867        try {
7868            synchronized (this) {
7869                // Since we lost lock on task, make sure it is still there.
7870                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7871                if (task != null) {
7872                    if (!isSystemInitiated
7873                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
7874                        throw new IllegalArgumentException("Invalid task, not in foreground");
7875                    }
7876                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
7877                }
7878            }
7879        } finally {
7880            Binder.restoreCallingIdentity(ident);
7881        }
7882    }
7883
7884    @Override
7885    public void startLockTaskMode(int taskId) {
7886        final TaskRecord task;
7887        long ident = Binder.clearCallingIdentity();
7888        try {
7889            synchronized (this) {
7890                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7891            }
7892        } finally {
7893            Binder.restoreCallingIdentity(ident);
7894        }
7895        if (task != null) {
7896            startLockTaskMode(task);
7897        }
7898    }
7899
7900    @Override
7901    public void startLockTaskMode(IBinder token) {
7902        final TaskRecord task;
7903        long ident = Binder.clearCallingIdentity();
7904        try {
7905            synchronized (this) {
7906                final ActivityRecord r = ActivityRecord.forToken(token);
7907                if (r == null) {
7908                    return;
7909                }
7910                task = r.task;
7911            }
7912        } finally {
7913            Binder.restoreCallingIdentity(ident);
7914        }
7915        if (task != null) {
7916            startLockTaskMode(task);
7917        }
7918    }
7919
7920    @Override
7921    public void startLockTaskModeOnCurrent() throws RemoteException {
7922        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7923        ActivityRecord r = null;
7924        synchronized (this) {
7925            r = mStackSupervisor.topRunningActivityLocked();
7926        }
7927        startLockTaskMode(r.task);
7928    }
7929
7930    @Override
7931    public void stopLockTaskMode() {
7932        // Verify that the user matches the package of the intent for the TaskRecord
7933        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
7934        // and stopLockTaskMode.
7935        final int callingUid = Binder.getCallingUid();
7936        if (callingUid != Process.SYSTEM_UID) {
7937            try {
7938                String pkg =
7939                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
7940                int uid = mContext.getPackageManager().getPackageUid(pkg,
7941                        Binder.getCallingUserHandle().getIdentifier());
7942                if (uid != callingUid) {
7943                    throw new SecurityException("Invalid uid, expected " + uid);
7944                }
7945            } catch (NameNotFoundException e) {
7946                Log.d(TAG, "stopLockTaskMode " + e);
7947                return;
7948            }
7949        }
7950        long ident = Binder.clearCallingIdentity();
7951        try {
7952            Log.d(TAG, "stopLockTaskMode");
7953            // Stop lock task
7954            synchronized (this) {
7955                mStackSupervisor.setLockTaskModeLocked(null, false);
7956            }
7957        } finally {
7958            Binder.restoreCallingIdentity(ident);
7959        }
7960    }
7961
7962    @Override
7963    public void stopLockTaskModeOnCurrent() throws RemoteException {
7964        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7965        long ident = Binder.clearCallingIdentity();
7966        try {
7967            stopLockTaskMode();
7968        } finally {
7969            Binder.restoreCallingIdentity(ident);
7970        }
7971    }
7972
7973    @Override
7974    public boolean isInLockTaskMode() {
7975        synchronized (this) {
7976            return mStackSupervisor.isInLockTaskMode();
7977        }
7978    }
7979
7980    // =========================================================
7981    // CONTENT PROVIDERS
7982    // =========================================================
7983
7984    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7985        List<ProviderInfo> providers = null;
7986        try {
7987            providers = AppGlobals.getPackageManager().
7988                queryContentProviders(app.processName, app.uid,
7989                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7990        } catch (RemoteException ex) {
7991        }
7992        if (DEBUG_MU)
7993            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7994        int userId = app.userId;
7995        if (providers != null) {
7996            int N = providers.size();
7997            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7998            for (int i=0; i<N; i++) {
7999                ProviderInfo cpi =
8000                    (ProviderInfo)providers.get(i);
8001                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8002                        cpi.name, cpi.flags);
8003                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8004                    // This is a singleton provider, but a user besides the
8005                    // default user is asking to initialize a process it runs
8006                    // in...  well, no, it doesn't actually run in this process,
8007                    // it runs in the process of the default user.  Get rid of it.
8008                    providers.remove(i);
8009                    N--;
8010                    i--;
8011                    continue;
8012                }
8013
8014                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8015                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8016                if (cpr == null) {
8017                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8018                    mProviderMap.putProviderByClass(comp, cpr);
8019                }
8020                if (DEBUG_MU)
8021                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8022                app.pubProviders.put(cpi.name, cpr);
8023                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8024                    // Don't add this if it is a platform component that is marked
8025                    // to run in multiple processes, because this is actually
8026                    // part of the framework so doesn't make sense to track as a
8027                    // separate apk in the process.
8028                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8029                            mProcessStats);
8030                }
8031                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8032            }
8033        }
8034        return providers;
8035    }
8036
8037    /**
8038     * Check if {@link ProcessRecord} has a possible chance at accessing the
8039     * given {@link ProviderInfo}. Final permission checking is always done
8040     * in {@link ContentProvider}.
8041     */
8042    private final String checkContentProviderPermissionLocked(
8043            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8044        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8045        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8046        boolean checkedGrants = false;
8047        if (checkUser) {
8048            // Looking for cross-user grants before enforcing the typical cross-users permissions
8049            int tmpTargetUserId = unsafeConvertIncomingUser(UserHandle.getUserId(callingUid));
8050            if (tmpTargetUserId != userId) {
8051                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8052                    return null;
8053                }
8054                checkedGrants = true;
8055            }
8056            userId = handleIncomingUser(callingPid, callingUid, userId,
8057                    false, ALLOW_NON_FULL,
8058                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8059            if (userId != tmpTargetUserId) {
8060                // When we actually went to determine the final targer user ID, this ended
8061                // up different than our initial check for the authority.  This is because
8062                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8063                // SELF.  So we need to re-check the grants again.
8064                checkedGrants = false;
8065            }
8066        }
8067        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8068                cpi.applicationInfo.uid, cpi.exported)
8069                == PackageManager.PERMISSION_GRANTED) {
8070            return null;
8071        }
8072        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8073                cpi.applicationInfo.uid, cpi.exported)
8074                == PackageManager.PERMISSION_GRANTED) {
8075            return null;
8076        }
8077
8078        PathPermission[] pps = cpi.pathPermissions;
8079        if (pps != null) {
8080            int i = pps.length;
8081            while (i > 0) {
8082                i--;
8083                PathPermission pp = pps[i];
8084                String pprperm = pp.getReadPermission();
8085                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8086                        cpi.applicationInfo.uid, cpi.exported)
8087                        == PackageManager.PERMISSION_GRANTED) {
8088                    return null;
8089                }
8090                String ppwperm = pp.getWritePermission();
8091                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8092                        cpi.applicationInfo.uid, cpi.exported)
8093                        == PackageManager.PERMISSION_GRANTED) {
8094                    return null;
8095                }
8096            }
8097        }
8098        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8099            return null;
8100        }
8101
8102        String msg;
8103        if (!cpi.exported) {
8104            msg = "Permission Denial: opening provider " + cpi.name
8105                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8106                    + ", uid=" + callingUid + ") that is not exported from uid "
8107                    + cpi.applicationInfo.uid;
8108        } else {
8109            msg = "Permission Denial: opening provider " + cpi.name
8110                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8111                    + ", uid=" + callingUid + ") requires "
8112                    + cpi.readPermission + " or " + cpi.writePermission;
8113        }
8114        Slog.w(TAG, msg);
8115        return msg;
8116    }
8117
8118    /**
8119     * Returns if the ContentProvider has granted a uri to callingUid
8120     */
8121    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8122        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8123        if (perms != null) {
8124            for (int i=perms.size()-1; i>=0; i--) {
8125                GrantUri grantUri = perms.keyAt(i);
8126                if (grantUri.sourceUserId == userId || !checkUser) {
8127                    if (matchesProvider(grantUri.uri, cpi)) {
8128                        return true;
8129                    }
8130                }
8131            }
8132        }
8133        return false;
8134    }
8135
8136    /**
8137     * Returns true if the uri authority is one of the authorities specified in the provider.
8138     */
8139    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8140        String uriAuth = uri.getAuthority();
8141        String cpiAuth = cpi.authority;
8142        if (cpiAuth.indexOf(';') == -1) {
8143            return cpiAuth.equals(uriAuth);
8144        }
8145        String[] cpiAuths = cpiAuth.split(";");
8146        int length = cpiAuths.length;
8147        for (int i = 0; i < length; i++) {
8148            if (cpiAuths[i].equals(uriAuth)) return true;
8149        }
8150        return false;
8151    }
8152
8153    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8154            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8155        if (r != null) {
8156            for (int i=0; i<r.conProviders.size(); i++) {
8157                ContentProviderConnection conn = r.conProviders.get(i);
8158                if (conn.provider == cpr) {
8159                    if (DEBUG_PROVIDER) Slog.v(TAG,
8160                            "Adding provider requested by "
8161                            + r.processName + " from process "
8162                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8163                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8164                    if (stable) {
8165                        conn.stableCount++;
8166                        conn.numStableIncs++;
8167                    } else {
8168                        conn.unstableCount++;
8169                        conn.numUnstableIncs++;
8170                    }
8171                    return conn;
8172                }
8173            }
8174            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8175            if (stable) {
8176                conn.stableCount = 1;
8177                conn.numStableIncs = 1;
8178            } else {
8179                conn.unstableCount = 1;
8180                conn.numUnstableIncs = 1;
8181            }
8182            cpr.connections.add(conn);
8183            r.conProviders.add(conn);
8184            return conn;
8185        }
8186        cpr.addExternalProcessHandleLocked(externalProcessToken);
8187        return null;
8188    }
8189
8190    boolean decProviderCountLocked(ContentProviderConnection conn,
8191            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8192        if (conn != null) {
8193            cpr = conn.provider;
8194            if (DEBUG_PROVIDER) Slog.v(TAG,
8195                    "Removing provider requested by "
8196                    + conn.client.processName + " from process "
8197                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8198                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8199            if (stable) {
8200                conn.stableCount--;
8201            } else {
8202                conn.unstableCount--;
8203            }
8204            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8205                cpr.connections.remove(conn);
8206                conn.client.conProviders.remove(conn);
8207                return true;
8208            }
8209            return false;
8210        }
8211        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8212        return false;
8213    }
8214
8215    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8216            String name, IBinder token, boolean stable, int userId) {
8217        ContentProviderRecord cpr;
8218        ContentProviderConnection conn = null;
8219        ProviderInfo cpi = null;
8220
8221        synchronized(this) {
8222            ProcessRecord r = null;
8223            if (caller != null) {
8224                r = getRecordForAppLocked(caller);
8225                if (r == null) {
8226                    throw new SecurityException(
8227                            "Unable to find app for caller " + caller
8228                          + " (pid=" + Binder.getCallingPid()
8229                          + ") when getting content provider " + name);
8230                }
8231            }
8232
8233            boolean checkCrossUser = true;
8234
8235            // First check if this content provider has been published...
8236            cpr = mProviderMap.getProviderByName(name, userId);
8237            // If that didn't work, check if it exists for user 0 and then
8238            // verify that it's a singleton provider before using it.
8239            if (cpr == null && userId != UserHandle.USER_OWNER) {
8240                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8241                if (cpr != null) {
8242                    cpi = cpr.info;
8243                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8244                            cpi.name, cpi.flags)
8245                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8246                        userId = UserHandle.USER_OWNER;
8247                        checkCrossUser = false;
8248                    } else {
8249                        cpr = null;
8250                        cpi = null;
8251                    }
8252                }
8253            }
8254
8255            boolean providerRunning = cpr != null;
8256            if (providerRunning) {
8257                cpi = cpr.info;
8258                String msg;
8259                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8260                        != null) {
8261                    throw new SecurityException(msg);
8262                }
8263
8264                if (r != null && cpr.canRunHere(r)) {
8265                    // This provider has been published or is in the process
8266                    // of being published...  but it is also allowed to run
8267                    // in the caller's process, so don't make a connection
8268                    // and just let the caller instantiate its own instance.
8269                    ContentProviderHolder holder = cpr.newHolder(null);
8270                    // don't give caller the provider object, it needs
8271                    // to make its own.
8272                    holder.provider = null;
8273                    return holder;
8274                }
8275
8276                final long origId = Binder.clearCallingIdentity();
8277
8278                // In this case the provider instance already exists, so we can
8279                // return it right away.
8280                conn = incProviderCountLocked(r, cpr, token, stable);
8281                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8282                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8283                        // If this is a perceptible app accessing the provider,
8284                        // make sure to count it as being accessed and thus
8285                        // back up on the LRU list.  This is good because
8286                        // content providers are often expensive to start.
8287                        updateLruProcessLocked(cpr.proc, false, null);
8288                    }
8289                }
8290
8291                if (cpr.proc != null) {
8292                    if (false) {
8293                        if (cpr.name.flattenToShortString().equals(
8294                                "com.android.providers.calendar/.CalendarProvider2")) {
8295                            Slog.v(TAG, "****************** KILLING "
8296                                + cpr.name.flattenToShortString());
8297                            Process.killProcess(cpr.proc.pid);
8298                        }
8299                    }
8300                    boolean success = updateOomAdjLocked(cpr.proc);
8301                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8302                    // NOTE: there is still a race here where a signal could be
8303                    // pending on the process even though we managed to update its
8304                    // adj level.  Not sure what to do about this, but at least
8305                    // the race is now smaller.
8306                    if (!success) {
8307                        // Uh oh...  it looks like the provider's process
8308                        // has been killed on us.  We need to wait for a new
8309                        // process to be started, and make sure its death
8310                        // doesn't kill our process.
8311                        Slog.i(TAG,
8312                                "Existing provider " + cpr.name.flattenToShortString()
8313                                + " is crashing; detaching " + r);
8314                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8315                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8316                        if (!lastRef) {
8317                            // This wasn't the last ref our process had on
8318                            // the provider...  we have now been killed, bail.
8319                            return null;
8320                        }
8321                        providerRunning = false;
8322                        conn = null;
8323                    }
8324                }
8325
8326                Binder.restoreCallingIdentity(origId);
8327            }
8328
8329            boolean singleton;
8330            if (!providerRunning) {
8331                try {
8332                    cpi = AppGlobals.getPackageManager().
8333                        resolveContentProvider(name,
8334                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8335                } catch (RemoteException ex) {
8336                }
8337                if (cpi == null) {
8338                    return null;
8339                }
8340                // If the provider is a singleton AND
8341                // (it's a call within the same user || the provider is a
8342                // privileged app)
8343                // Then allow connecting to the singleton provider
8344                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8345                        cpi.name, cpi.flags)
8346                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8347                if (singleton) {
8348                    userId = UserHandle.USER_OWNER;
8349                }
8350                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8351
8352                String msg;
8353                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8354                        != null) {
8355                    throw new SecurityException(msg);
8356                }
8357
8358                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8359                        && !cpi.processName.equals("system")) {
8360                    // If this content provider does not run in the system
8361                    // process, and the system is not yet ready to run other
8362                    // processes, then fail fast instead of hanging.
8363                    throw new IllegalArgumentException(
8364                            "Attempt to launch content provider before system ready");
8365                }
8366
8367                // Make sure that the user who owns this provider is started.  If not,
8368                // we don't want to allow it to run.
8369                if (mStartedUsers.get(userId) == null) {
8370                    Slog.w(TAG, "Unable to launch app "
8371                            + cpi.applicationInfo.packageName + "/"
8372                            + cpi.applicationInfo.uid + " for provider "
8373                            + name + ": user " + userId + " is stopped");
8374                    return null;
8375                }
8376
8377                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8378                cpr = mProviderMap.getProviderByClass(comp, userId);
8379                final boolean firstClass = cpr == null;
8380                if (firstClass) {
8381                    try {
8382                        ApplicationInfo ai =
8383                            AppGlobals.getPackageManager().
8384                                getApplicationInfo(
8385                                        cpi.applicationInfo.packageName,
8386                                        STOCK_PM_FLAGS, userId);
8387                        if (ai == null) {
8388                            Slog.w(TAG, "No package info for content provider "
8389                                    + cpi.name);
8390                            return null;
8391                        }
8392                        ai = getAppInfoForUser(ai, userId);
8393                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8394                    } catch (RemoteException ex) {
8395                        // pm is in same process, this will never happen.
8396                    }
8397                }
8398
8399                if (r != null && cpr.canRunHere(r)) {
8400                    // If this is a multiprocess provider, then just return its
8401                    // info and allow the caller to instantiate it.  Only do
8402                    // this if the provider is the same user as the caller's
8403                    // process, or can run as root (so can be in any process).
8404                    return cpr.newHolder(null);
8405                }
8406
8407                if (DEBUG_PROVIDER) {
8408                    RuntimeException e = new RuntimeException("here");
8409                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8410                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8411                }
8412
8413                // This is single process, and our app is now connecting to it.
8414                // See if we are already in the process of launching this
8415                // provider.
8416                final int N = mLaunchingProviders.size();
8417                int i;
8418                for (i=0; i<N; i++) {
8419                    if (mLaunchingProviders.get(i) == cpr) {
8420                        break;
8421                    }
8422                }
8423
8424                // If the provider is not already being launched, then get it
8425                // started.
8426                if (i >= N) {
8427                    final long origId = Binder.clearCallingIdentity();
8428
8429                    try {
8430                        // Content provider is now in use, its package can't be stopped.
8431                        try {
8432                            AppGlobals.getPackageManager().setPackageStoppedState(
8433                                    cpr.appInfo.packageName, false, userId);
8434                        } catch (RemoteException e) {
8435                        } catch (IllegalArgumentException e) {
8436                            Slog.w(TAG, "Failed trying to unstop package "
8437                                    + cpr.appInfo.packageName + ": " + e);
8438                        }
8439
8440                        // Use existing process if already started
8441                        ProcessRecord proc = getProcessRecordLocked(
8442                                cpi.processName, cpr.appInfo.uid, false);
8443                        if (proc != null && proc.thread != null) {
8444                            if (DEBUG_PROVIDER) {
8445                                Slog.d(TAG, "Installing in existing process " + proc);
8446                            }
8447                            proc.pubProviders.put(cpi.name, cpr);
8448                            try {
8449                                proc.thread.scheduleInstallProvider(cpi);
8450                            } catch (RemoteException e) {
8451                            }
8452                        } else {
8453                            proc = startProcessLocked(cpi.processName,
8454                                    cpr.appInfo, false, 0, "content provider",
8455                                    new ComponentName(cpi.applicationInfo.packageName,
8456                                            cpi.name), false, false, false);
8457                            if (proc == null) {
8458                                Slog.w(TAG, "Unable to launch app "
8459                                        + cpi.applicationInfo.packageName + "/"
8460                                        + cpi.applicationInfo.uid + " for provider "
8461                                        + name + ": process is bad");
8462                                return null;
8463                            }
8464                        }
8465                        cpr.launchingApp = proc;
8466                        mLaunchingProviders.add(cpr);
8467                    } finally {
8468                        Binder.restoreCallingIdentity(origId);
8469                    }
8470                }
8471
8472                // Make sure the provider is published (the same provider class
8473                // may be published under multiple names).
8474                if (firstClass) {
8475                    mProviderMap.putProviderByClass(comp, cpr);
8476                }
8477
8478                mProviderMap.putProviderByName(name, cpr);
8479                conn = incProviderCountLocked(r, cpr, token, stable);
8480                if (conn != null) {
8481                    conn.waiting = true;
8482                }
8483            }
8484        }
8485
8486        // Wait for the provider to be published...
8487        synchronized (cpr) {
8488            while (cpr.provider == null) {
8489                if (cpr.launchingApp == null) {
8490                    Slog.w(TAG, "Unable to launch app "
8491                            + cpi.applicationInfo.packageName + "/"
8492                            + cpi.applicationInfo.uid + " for provider "
8493                            + name + ": launching app became null");
8494                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8495                            UserHandle.getUserId(cpi.applicationInfo.uid),
8496                            cpi.applicationInfo.packageName,
8497                            cpi.applicationInfo.uid, name);
8498                    return null;
8499                }
8500                try {
8501                    if (DEBUG_MU) {
8502                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8503                                + cpr.launchingApp);
8504                    }
8505                    if (conn != null) {
8506                        conn.waiting = true;
8507                    }
8508                    cpr.wait();
8509                } catch (InterruptedException ex) {
8510                } finally {
8511                    if (conn != null) {
8512                        conn.waiting = false;
8513                    }
8514                }
8515            }
8516        }
8517        return cpr != null ? cpr.newHolder(conn) : null;
8518    }
8519
8520    @Override
8521    public final ContentProviderHolder getContentProvider(
8522            IApplicationThread caller, String name, int userId, boolean stable) {
8523        enforceNotIsolatedCaller("getContentProvider");
8524        if (caller == null) {
8525            String msg = "null IApplicationThread when getting content provider "
8526                    + name;
8527            Slog.w(TAG, msg);
8528            throw new SecurityException(msg);
8529        }
8530        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8531        // with cross-user grant.
8532        return getContentProviderImpl(caller, name, null, stable, userId);
8533    }
8534
8535    public ContentProviderHolder getContentProviderExternal(
8536            String name, int userId, IBinder token) {
8537        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8538            "Do not have permission in call getContentProviderExternal()");
8539        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8540                false, ALLOW_FULL_ONLY, "getContentProvider", null);
8541        return getContentProviderExternalUnchecked(name, token, userId);
8542    }
8543
8544    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8545            IBinder token, int userId) {
8546        return getContentProviderImpl(null, name, token, true, userId);
8547    }
8548
8549    /**
8550     * Drop a content provider from a ProcessRecord's bookkeeping
8551     */
8552    public void removeContentProvider(IBinder connection, boolean stable) {
8553        enforceNotIsolatedCaller("removeContentProvider");
8554        long ident = Binder.clearCallingIdentity();
8555        try {
8556            synchronized (this) {
8557                ContentProviderConnection conn;
8558                try {
8559                    conn = (ContentProviderConnection)connection;
8560                } catch (ClassCastException e) {
8561                    String msg ="removeContentProvider: " + connection
8562                            + " not a ContentProviderConnection";
8563                    Slog.w(TAG, msg);
8564                    throw new IllegalArgumentException(msg);
8565                }
8566                if (conn == null) {
8567                    throw new NullPointerException("connection is null");
8568                }
8569                if (decProviderCountLocked(conn, null, null, stable)) {
8570                    updateOomAdjLocked();
8571                }
8572            }
8573        } finally {
8574            Binder.restoreCallingIdentity(ident);
8575        }
8576    }
8577
8578    public void removeContentProviderExternal(String name, IBinder token) {
8579        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8580            "Do not have permission in call removeContentProviderExternal()");
8581        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8582    }
8583
8584    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8585        synchronized (this) {
8586            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8587            if(cpr == null) {
8588                //remove from mProvidersByClass
8589                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8590                return;
8591            }
8592
8593            //update content provider record entry info
8594            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8595            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8596            if (localCpr.hasExternalProcessHandles()) {
8597                if (localCpr.removeExternalProcessHandleLocked(token)) {
8598                    updateOomAdjLocked();
8599                } else {
8600                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8601                            + " with no external reference for token: "
8602                            + token + ".");
8603                }
8604            } else {
8605                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8606                        + " with no external references.");
8607            }
8608        }
8609    }
8610
8611    public final void publishContentProviders(IApplicationThread caller,
8612            List<ContentProviderHolder> providers) {
8613        if (providers == null) {
8614            return;
8615        }
8616
8617        enforceNotIsolatedCaller("publishContentProviders");
8618        synchronized (this) {
8619            final ProcessRecord r = getRecordForAppLocked(caller);
8620            if (DEBUG_MU)
8621                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8622            if (r == null) {
8623                throw new SecurityException(
8624                        "Unable to find app for caller " + caller
8625                      + " (pid=" + Binder.getCallingPid()
8626                      + ") when publishing content providers");
8627            }
8628
8629            final long origId = Binder.clearCallingIdentity();
8630
8631            final int N = providers.size();
8632            for (int i=0; i<N; i++) {
8633                ContentProviderHolder src = providers.get(i);
8634                if (src == null || src.info == null || src.provider == null) {
8635                    continue;
8636                }
8637                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8638                if (DEBUG_MU)
8639                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8640                if (dst != null) {
8641                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8642                    mProviderMap.putProviderByClass(comp, dst);
8643                    String names[] = dst.info.authority.split(";");
8644                    for (int j = 0; j < names.length; j++) {
8645                        mProviderMap.putProviderByName(names[j], dst);
8646                    }
8647
8648                    int NL = mLaunchingProviders.size();
8649                    int j;
8650                    for (j=0; j<NL; j++) {
8651                        if (mLaunchingProviders.get(j) == dst) {
8652                            mLaunchingProviders.remove(j);
8653                            j--;
8654                            NL--;
8655                        }
8656                    }
8657                    synchronized (dst) {
8658                        dst.provider = src.provider;
8659                        dst.proc = r;
8660                        dst.notifyAll();
8661                    }
8662                    updateOomAdjLocked(r);
8663                }
8664            }
8665
8666            Binder.restoreCallingIdentity(origId);
8667        }
8668    }
8669
8670    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8671        ContentProviderConnection conn;
8672        try {
8673            conn = (ContentProviderConnection)connection;
8674        } catch (ClassCastException e) {
8675            String msg ="refContentProvider: " + connection
8676                    + " not a ContentProviderConnection";
8677            Slog.w(TAG, msg);
8678            throw new IllegalArgumentException(msg);
8679        }
8680        if (conn == null) {
8681            throw new NullPointerException("connection is null");
8682        }
8683
8684        synchronized (this) {
8685            if (stable > 0) {
8686                conn.numStableIncs += stable;
8687            }
8688            stable = conn.stableCount + stable;
8689            if (stable < 0) {
8690                throw new IllegalStateException("stableCount < 0: " + stable);
8691            }
8692
8693            if (unstable > 0) {
8694                conn.numUnstableIncs += unstable;
8695            }
8696            unstable = conn.unstableCount + unstable;
8697            if (unstable < 0) {
8698                throw new IllegalStateException("unstableCount < 0: " + unstable);
8699            }
8700
8701            if ((stable+unstable) <= 0) {
8702                throw new IllegalStateException("ref counts can't go to zero here: stable="
8703                        + stable + " unstable=" + unstable);
8704            }
8705            conn.stableCount = stable;
8706            conn.unstableCount = unstable;
8707            return !conn.dead;
8708        }
8709    }
8710
8711    public void unstableProviderDied(IBinder connection) {
8712        ContentProviderConnection conn;
8713        try {
8714            conn = (ContentProviderConnection)connection;
8715        } catch (ClassCastException e) {
8716            String msg ="refContentProvider: " + connection
8717                    + " not a ContentProviderConnection";
8718            Slog.w(TAG, msg);
8719            throw new IllegalArgumentException(msg);
8720        }
8721        if (conn == null) {
8722            throw new NullPointerException("connection is null");
8723        }
8724
8725        // Safely retrieve the content provider associated with the connection.
8726        IContentProvider provider;
8727        synchronized (this) {
8728            provider = conn.provider.provider;
8729        }
8730
8731        if (provider == null) {
8732            // Um, yeah, we're way ahead of you.
8733            return;
8734        }
8735
8736        // Make sure the caller is being honest with us.
8737        if (provider.asBinder().pingBinder()) {
8738            // Er, no, still looks good to us.
8739            synchronized (this) {
8740                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8741                        + " says " + conn + " died, but we don't agree");
8742                return;
8743            }
8744        }
8745
8746        // Well look at that!  It's dead!
8747        synchronized (this) {
8748            if (conn.provider.provider != provider) {
8749                // But something changed...  good enough.
8750                return;
8751            }
8752
8753            ProcessRecord proc = conn.provider.proc;
8754            if (proc == null || proc.thread == null) {
8755                // Seems like the process is already cleaned up.
8756                return;
8757            }
8758
8759            // As far as we're concerned, this is just like receiving a
8760            // death notification...  just a bit prematurely.
8761            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8762                    + ") early provider death");
8763            final long ident = Binder.clearCallingIdentity();
8764            try {
8765                appDiedLocked(proc, proc.pid, proc.thread);
8766            } finally {
8767                Binder.restoreCallingIdentity(ident);
8768            }
8769        }
8770    }
8771
8772    @Override
8773    public void appNotRespondingViaProvider(IBinder connection) {
8774        enforceCallingPermission(
8775                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8776
8777        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8778        if (conn == null) {
8779            Slog.w(TAG, "ContentProviderConnection is null");
8780            return;
8781        }
8782
8783        final ProcessRecord host = conn.provider.proc;
8784        if (host == null) {
8785            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8786            return;
8787        }
8788
8789        final long token = Binder.clearCallingIdentity();
8790        try {
8791            appNotResponding(host, null, null, false, "ContentProvider not responding");
8792        } finally {
8793            Binder.restoreCallingIdentity(token);
8794        }
8795    }
8796
8797    public final void installSystemProviders() {
8798        List<ProviderInfo> providers;
8799        synchronized (this) {
8800            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8801            providers = generateApplicationProvidersLocked(app);
8802            if (providers != null) {
8803                for (int i=providers.size()-1; i>=0; i--) {
8804                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8805                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8806                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8807                                + ": not system .apk");
8808                        providers.remove(i);
8809                    }
8810                }
8811            }
8812        }
8813        if (providers != null) {
8814            mSystemThread.installSystemProviders(providers);
8815        }
8816
8817        mCoreSettingsObserver = new CoreSettingsObserver(this);
8818
8819        mUsageStatsService.monitorPackages();
8820    }
8821
8822    /**
8823     * Allows app to retrieve the MIME type of a URI without having permission
8824     * to access its content provider.
8825     *
8826     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8827     *
8828     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8829     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8830     */
8831    public String getProviderMimeType(Uri uri, int userId) {
8832        enforceNotIsolatedCaller("getProviderMimeType");
8833        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8834                userId, false, ALLOW_NON_FULL_IN_PROFILE, "getProviderMimeType", null);
8835        final String name = uri.getAuthority();
8836        final long ident = Binder.clearCallingIdentity();
8837        ContentProviderHolder holder = null;
8838
8839        try {
8840            holder = getContentProviderExternalUnchecked(name, null, userId);
8841            if (holder != null) {
8842                return holder.provider.getType(uri);
8843            }
8844        } catch (RemoteException e) {
8845            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8846            return null;
8847        } finally {
8848            if (holder != null) {
8849                removeContentProviderExternalUnchecked(name, null, userId);
8850            }
8851            Binder.restoreCallingIdentity(ident);
8852        }
8853
8854        return null;
8855    }
8856
8857    // =========================================================
8858    // GLOBAL MANAGEMENT
8859    // =========================================================
8860
8861    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8862            boolean isolated) {
8863        String proc = customProcess != null ? customProcess : info.processName;
8864        BatteryStatsImpl.Uid.Proc ps = null;
8865        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8866        int uid = info.uid;
8867        if (isolated) {
8868            int userId = UserHandle.getUserId(uid);
8869            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8870            while (true) {
8871                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8872                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8873                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8874                }
8875                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8876                mNextIsolatedProcessUid++;
8877                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8878                    // No process for this uid, use it.
8879                    break;
8880                }
8881                stepsLeft--;
8882                if (stepsLeft <= 0) {
8883                    return null;
8884                }
8885            }
8886        }
8887        return new ProcessRecord(stats, info, proc, uid);
8888    }
8889
8890    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8891            String abiOverride) {
8892        ProcessRecord app;
8893        if (!isolated) {
8894            app = getProcessRecordLocked(info.processName, info.uid, true);
8895        } else {
8896            app = null;
8897        }
8898
8899        if (app == null) {
8900            app = newProcessRecordLocked(info, null, isolated);
8901            mProcessNames.put(info.processName, app.uid, app);
8902            if (isolated) {
8903                mIsolatedProcesses.put(app.uid, app);
8904            }
8905            updateLruProcessLocked(app, false, null);
8906            updateOomAdjLocked();
8907        }
8908
8909        // This package really, really can not be stopped.
8910        try {
8911            AppGlobals.getPackageManager().setPackageStoppedState(
8912                    info.packageName, false, UserHandle.getUserId(app.uid));
8913        } catch (RemoteException e) {
8914        } catch (IllegalArgumentException e) {
8915            Slog.w(TAG, "Failed trying to unstop package "
8916                    + info.packageName + ": " + e);
8917        }
8918
8919        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8920                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8921            app.persistent = true;
8922            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8923        }
8924        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8925            mPersistentStartingProcesses.add(app);
8926            startProcessLocked(app, "added application", app.processName,
8927                    abiOverride);
8928        }
8929
8930        return app;
8931    }
8932
8933    public void unhandledBack() {
8934        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8935                "unhandledBack()");
8936
8937        synchronized(this) {
8938            final long origId = Binder.clearCallingIdentity();
8939            try {
8940                getFocusedStack().unhandledBackLocked();
8941            } finally {
8942                Binder.restoreCallingIdentity(origId);
8943            }
8944        }
8945    }
8946
8947    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8948        enforceNotIsolatedCaller("openContentUri");
8949        final int userId = UserHandle.getCallingUserId();
8950        String name = uri.getAuthority();
8951        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8952        ParcelFileDescriptor pfd = null;
8953        if (cph != null) {
8954            // We record the binder invoker's uid in thread-local storage before
8955            // going to the content provider to open the file.  Later, in the code
8956            // that handles all permissions checks, we look for this uid and use
8957            // that rather than the Activity Manager's own uid.  The effect is that
8958            // we do the check against the caller's permissions even though it looks
8959            // to the content provider like the Activity Manager itself is making
8960            // the request.
8961            sCallerIdentity.set(new Identity(
8962                    Binder.getCallingPid(), Binder.getCallingUid()));
8963            try {
8964                pfd = cph.provider.openFile(null, uri, "r", null);
8965            } catch (FileNotFoundException e) {
8966                // do nothing; pfd will be returned null
8967            } finally {
8968                // Ensure that whatever happens, we clean up the identity state
8969                sCallerIdentity.remove();
8970            }
8971
8972            // We've got the fd now, so we're done with the provider.
8973            removeContentProviderExternalUnchecked(name, null, userId);
8974        } else {
8975            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8976        }
8977        return pfd;
8978    }
8979
8980    // Actually is sleeping or shutting down or whatever else in the future
8981    // is an inactive state.
8982    public boolean isSleepingOrShuttingDown() {
8983        return mSleeping || mShuttingDown;
8984    }
8985
8986    public boolean isSleeping() {
8987        return mSleeping;
8988    }
8989
8990    void goingToSleep() {
8991        synchronized(this) {
8992            mWentToSleep = true;
8993            updateEventDispatchingLocked();
8994            goToSleepIfNeededLocked();
8995        }
8996    }
8997
8998    void finishRunningVoiceLocked() {
8999        if (mRunningVoice) {
9000            mRunningVoice = false;
9001            goToSleepIfNeededLocked();
9002        }
9003    }
9004
9005    void goToSleepIfNeededLocked() {
9006        if (mWentToSleep && !mRunningVoice) {
9007            if (!mSleeping) {
9008                mSleeping = true;
9009                mStackSupervisor.goingToSleepLocked();
9010
9011                // Initialize the wake times of all processes.
9012                checkExcessivePowerUsageLocked(false);
9013                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9014                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9015                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9016            }
9017        }
9018    }
9019
9020    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9021        mTaskPersister.notify(task, flush);
9022    }
9023
9024    @Override
9025    public boolean shutdown(int timeout) {
9026        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9027                != PackageManager.PERMISSION_GRANTED) {
9028            throw new SecurityException("Requires permission "
9029                    + android.Manifest.permission.SHUTDOWN);
9030        }
9031
9032        boolean timedout = false;
9033
9034        synchronized(this) {
9035            mShuttingDown = true;
9036            updateEventDispatchingLocked();
9037            timedout = mStackSupervisor.shutdownLocked(timeout);
9038        }
9039
9040        mAppOpsService.shutdown();
9041        mUsageStatsService.shutdown();
9042        mBatteryStatsService.shutdown();
9043        synchronized (this) {
9044            mProcessStats.shutdownLocked();
9045        }
9046        notifyTaskPersisterLocked(null, true);
9047
9048        return timedout;
9049    }
9050
9051    public final void activitySlept(IBinder token) {
9052        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9053
9054        final long origId = Binder.clearCallingIdentity();
9055
9056        synchronized (this) {
9057            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9058            if (r != null) {
9059                mStackSupervisor.activitySleptLocked(r);
9060            }
9061        }
9062
9063        Binder.restoreCallingIdentity(origId);
9064    }
9065
9066    void logLockScreen(String msg) {
9067        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9068                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9069                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
9070                mStackSupervisor.mDismissKeyguardOnNextActivity);
9071    }
9072
9073    private void comeOutOfSleepIfNeededLocked() {
9074        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9075            if (mSleeping) {
9076                mSleeping = false;
9077                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9078            }
9079        }
9080    }
9081
9082    void wakingUp() {
9083        synchronized(this) {
9084            mWentToSleep = false;
9085            updateEventDispatchingLocked();
9086            comeOutOfSleepIfNeededLocked();
9087        }
9088    }
9089
9090    void startRunningVoiceLocked() {
9091        if (!mRunningVoice) {
9092            mRunningVoice = true;
9093            comeOutOfSleepIfNeededLocked();
9094        }
9095    }
9096
9097    private void updateEventDispatchingLocked() {
9098        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9099    }
9100
9101    public void setLockScreenShown(boolean shown) {
9102        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9103                != PackageManager.PERMISSION_GRANTED) {
9104            throw new SecurityException("Requires permission "
9105                    + android.Manifest.permission.DEVICE_POWER);
9106        }
9107
9108        synchronized(this) {
9109            long ident = Binder.clearCallingIdentity();
9110            try {
9111                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9112                mLockScreenShown = shown;
9113                comeOutOfSleepIfNeededLocked();
9114            } finally {
9115                Binder.restoreCallingIdentity(ident);
9116            }
9117        }
9118    }
9119
9120    public void stopAppSwitches() {
9121        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9122                != PackageManager.PERMISSION_GRANTED) {
9123            throw new SecurityException("Requires permission "
9124                    + android.Manifest.permission.STOP_APP_SWITCHES);
9125        }
9126
9127        synchronized(this) {
9128            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9129                    + APP_SWITCH_DELAY_TIME;
9130            mDidAppSwitch = false;
9131            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9132            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9133            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9134        }
9135    }
9136
9137    public void resumeAppSwitches() {
9138        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9139                != PackageManager.PERMISSION_GRANTED) {
9140            throw new SecurityException("Requires permission "
9141                    + android.Manifest.permission.STOP_APP_SWITCHES);
9142        }
9143
9144        synchronized(this) {
9145            // Note that we don't execute any pending app switches... we will
9146            // let those wait until either the timeout, or the next start
9147            // activity request.
9148            mAppSwitchesAllowedTime = 0;
9149        }
9150    }
9151
9152    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9153            String name) {
9154        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9155            return true;
9156        }
9157
9158        final int perm = checkComponentPermission(
9159                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9160                callingUid, -1, true);
9161        if (perm == PackageManager.PERMISSION_GRANTED) {
9162            return true;
9163        }
9164
9165        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9166        return false;
9167    }
9168
9169    public void setDebugApp(String packageName, boolean waitForDebugger,
9170            boolean persistent) {
9171        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9172                "setDebugApp()");
9173
9174        long ident = Binder.clearCallingIdentity();
9175        try {
9176            // Note that this is not really thread safe if there are multiple
9177            // callers into it at the same time, but that's not a situation we
9178            // care about.
9179            if (persistent) {
9180                final ContentResolver resolver = mContext.getContentResolver();
9181                Settings.Global.putString(
9182                    resolver, Settings.Global.DEBUG_APP,
9183                    packageName);
9184                Settings.Global.putInt(
9185                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9186                    waitForDebugger ? 1 : 0);
9187            }
9188
9189            synchronized (this) {
9190                if (!persistent) {
9191                    mOrigDebugApp = mDebugApp;
9192                    mOrigWaitForDebugger = mWaitForDebugger;
9193                }
9194                mDebugApp = packageName;
9195                mWaitForDebugger = waitForDebugger;
9196                mDebugTransient = !persistent;
9197                if (packageName != null) {
9198                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9199                            false, UserHandle.USER_ALL, "set debug app");
9200                }
9201            }
9202        } finally {
9203            Binder.restoreCallingIdentity(ident);
9204        }
9205    }
9206
9207    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9208        synchronized (this) {
9209            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9210            if (!isDebuggable) {
9211                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9212                    throw new SecurityException("Process not debuggable: " + app.packageName);
9213                }
9214            }
9215
9216            mOpenGlTraceApp = processName;
9217        }
9218    }
9219
9220    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9221            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9222        synchronized (this) {
9223            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9224            if (!isDebuggable) {
9225                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9226                    throw new SecurityException("Process not debuggable: " + app.packageName);
9227                }
9228            }
9229            mProfileApp = processName;
9230            mProfileFile = profileFile;
9231            if (mProfileFd != null) {
9232                try {
9233                    mProfileFd.close();
9234                } catch (IOException e) {
9235                }
9236                mProfileFd = null;
9237            }
9238            mProfileFd = profileFd;
9239            mProfileType = 0;
9240            mAutoStopProfiler = autoStopProfiler;
9241        }
9242    }
9243
9244    @Override
9245    public void setAlwaysFinish(boolean enabled) {
9246        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9247                "setAlwaysFinish()");
9248
9249        Settings.Global.putInt(
9250                mContext.getContentResolver(),
9251                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9252
9253        synchronized (this) {
9254            mAlwaysFinishActivities = enabled;
9255        }
9256    }
9257
9258    @Override
9259    public void setActivityController(IActivityController controller) {
9260        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9261                "setActivityController()");
9262        synchronized (this) {
9263            mController = controller;
9264            Watchdog.getInstance().setActivityController(controller);
9265        }
9266    }
9267
9268    @Override
9269    public void setUserIsMonkey(boolean userIsMonkey) {
9270        synchronized (this) {
9271            synchronized (mPidsSelfLocked) {
9272                final int callingPid = Binder.getCallingPid();
9273                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9274                if (precessRecord == null) {
9275                    throw new SecurityException("Unknown process: " + callingPid);
9276                }
9277                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9278                    throw new SecurityException("Only an instrumentation process "
9279                            + "with a UiAutomation can call setUserIsMonkey");
9280                }
9281            }
9282            mUserIsMonkey = userIsMonkey;
9283        }
9284    }
9285
9286    @Override
9287    public boolean isUserAMonkey() {
9288        synchronized (this) {
9289            // If there is a controller also implies the user is a monkey.
9290            return (mUserIsMonkey || mController != null);
9291        }
9292    }
9293
9294    public void requestBugReport() {
9295        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9296        SystemProperties.set("ctl.start", "bugreport");
9297    }
9298
9299    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9300        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9301    }
9302
9303    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9304        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9305            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9306        }
9307        return KEY_DISPATCHING_TIMEOUT;
9308    }
9309
9310    @Override
9311    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9312        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9313                != PackageManager.PERMISSION_GRANTED) {
9314            throw new SecurityException("Requires permission "
9315                    + android.Manifest.permission.FILTER_EVENTS);
9316        }
9317        ProcessRecord proc;
9318        long timeout;
9319        synchronized (this) {
9320            synchronized (mPidsSelfLocked) {
9321                proc = mPidsSelfLocked.get(pid);
9322            }
9323            timeout = getInputDispatchingTimeoutLocked(proc);
9324        }
9325
9326        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9327            return -1;
9328        }
9329
9330        return timeout;
9331    }
9332
9333    /**
9334     * Handle input dispatching timeouts.
9335     * Returns whether input dispatching should be aborted or not.
9336     */
9337    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9338            final ActivityRecord activity, final ActivityRecord parent,
9339            final boolean aboveSystem, String reason) {
9340        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9341                != PackageManager.PERMISSION_GRANTED) {
9342            throw new SecurityException("Requires permission "
9343                    + android.Manifest.permission.FILTER_EVENTS);
9344        }
9345
9346        final String annotation;
9347        if (reason == null) {
9348            annotation = "Input dispatching timed out";
9349        } else {
9350            annotation = "Input dispatching timed out (" + reason + ")";
9351        }
9352
9353        if (proc != null) {
9354            synchronized (this) {
9355                if (proc.debugging) {
9356                    return false;
9357                }
9358
9359                if (mDidDexOpt) {
9360                    // Give more time since we were dexopting.
9361                    mDidDexOpt = false;
9362                    return false;
9363                }
9364
9365                if (proc.instrumentationClass != null) {
9366                    Bundle info = new Bundle();
9367                    info.putString("shortMsg", "keyDispatchingTimedOut");
9368                    info.putString("longMsg", annotation);
9369                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9370                    return true;
9371                }
9372            }
9373            mHandler.post(new Runnable() {
9374                @Override
9375                public void run() {
9376                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9377                }
9378            });
9379        }
9380
9381        return true;
9382    }
9383
9384    public Bundle getAssistContextExtras(int requestType) {
9385        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9386                "getAssistContextExtras()");
9387        PendingAssistExtras pae;
9388        Bundle extras = new Bundle();
9389        synchronized (this) {
9390            ActivityRecord activity = getFocusedStack().mResumedActivity;
9391            if (activity == null) {
9392                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9393                return null;
9394            }
9395            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9396            if (activity.app == null || activity.app.thread == null) {
9397                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9398                return extras;
9399            }
9400            if (activity.app.pid == Binder.getCallingPid()) {
9401                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9402                return extras;
9403            }
9404            pae = new PendingAssistExtras(activity);
9405            try {
9406                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9407                        requestType);
9408                mPendingAssistExtras.add(pae);
9409                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9410            } catch (RemoteException e) {
9411                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9412                return extras;
9413            }
9414        }
9415        synchronized (pae) {
9416            while (!pae.haveResult) {
9417                try {
9418                    pae.wait();
9419                } catch (InterruptedException e) {
9420                }
9421            }
9422            if (pae.result != null) {
9423                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9424            }
9425        }
9426        synchronized (this) {
9427            mPendingAssistExtras.remove(pae);
9428            mHandler.removeCallbacks(pae);
9429        }
9430        return extras;
9431    }
9432
9433    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9434        PendingAssistExtras pae = (PendingAssistExtras)token;
9435        synchronized (pae) {
9436            pae.result = extras;
9437            pae.haveResult = true;
9438            pae.notifyAll();
9439        }
9440    }
9441
9442    public void registerProcessObserver(IProcessObserver observer) {
9443        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9444                "registerProcessObserver()");
9445        synchronized (this) {
9446            mProcessObservers.register(observer);
9447        }
9448    }
9449
9450    @Override
9451    public void unregisterProcessObserver(IProcessObserver observer) {
9452        synchronized (this) {
9453            mProcessObservers.unregister(observer);
9454        }
9455    }
9456
9457    @Override
9458    public boolean convertFromTranslucent(IBinder token) {
9459        final long origId = Binder.clearCallingIdentity();
9460        try {
9461            synchronized (this) {
9462                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9463                if (r == null) {
9464                    return false;
9465                }
9466                if (r.changeWindowTranslucency(true)) {
9467                    mWindowManager.setAppFullscreen(token, true);
9468                    r.task.stack.releaseMediaResources();
9469                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9470                    return true;
9471                }
9472                return false;
9473            }
9474        } finally {
9475            Binder.restoreCallingIdentity(origId);
9476        }
9477    }
9478
9479    @Override
9480    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9481        final long origId = Binder.clearCallingIdentity();
9482        try {
9483            synchronized (this) {
9484                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9485                if (r == null) {
9486                    return false;
9487                }
9488                if (r.changeWindowTranslucency(false)) {
9489                    r.task.stack.convertToTranslucent(r, options);
9490                    mWindowManager.setAppFullscreen(token, false);
9491                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9492                    return true;
9493                } else {
9494                    r.task.stack.mReturningActivityOptions = options;
9495                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9496                    return false;
9497                }
9498            }
9499        } finally {
9500            Binder.restoreCallingIdentity(origId);
9501        }
9502    }
9503
9504    @Override
9505    public boolean setMediaPlaying(IBinder token, boolean playing) {
9506        final long origId = Binder.clearCallingIdentity();
9507        try {
9508            synchronized (this) {
9509                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9510                if (r != null) {
9511                    return mStackSupervisor.setMediaPlayingLocked(r, playing);
9512                }
9513            }
9514            return false;
9515        } finally {
9516            Binder.restoreCallingIdentity(origId);
9517        }
9518    }
9519
9520    @Override
9521    public boolean isBackgroundMediaPlaying(IBinder token) {
9522        final long origId = Binder.clearCallingIdentity();
9523        try {
9524            synchronized (this) {
9525                final ActivityStack stack = ActivityRecord.getStackLocked(token);
9526                final boolean playing = stack == null ? false : stack.isMediaPlaying();
9527                if (ActivityStackSupervisor.DEBUG_MEDIA_VISIBILITY) Slog.d(TAG,
9528                        "isBackgroundMediaPlaying: stack=" + stack + " playing=" + playing);
9529                return playing;
9530            }
9531        } finally {
9532            Binder.restoreCallingIdentity(origId);
9533        }
9534    }
9535
9536    @Override
9537    public ActivityOptions getActivityOptions(IBinder token) {
9538        final long origId = Binder.clearCallingIdentity();
9539        try {
9540            synchronized (this) {
9541                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9542                if (r != null) {
9543                    final ActivityOptions activityOptions = r.pendingOptions;
9544                    r.pendingOptions = null;
9545                    return activityOptions;
9546                }
9547                return null;
9548            }
9549        } finally {
9550            Binder.restoreCallingIdentity(origId);
9551        }
9552    }
9553
9554    @Override
9555    public void setImmersive(IBinder token, boolean immersive) {
9556        synchronized(this) {
9557            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9558            if (r == null) {
9559                throw new IllegalArgumentException();
9560            }
9561            r.immersive = immersive;
9562
9563            // update associated state if we're frontmost
9564            if (r == mFocusedActivity) {
9565                if (DEBUG_IMMERSIVE) {
9566                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9567                }
9568                applyUpdateLockStateLocked(r);
9569            }
9570        }
9571    }
9572
9573    @Override
9574    public boolean isImmersive(IBinder token) {
9575        synchronized (this) {
9576            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9577            if (r == null) {
9578                throw new IllegalArgumentException();
9579            }
9580            return r.immersive;
9581        }
9582    }
9583
9584    public boolean isTopActivityImmersive() {
9585        enforceNotIsolatedCaller("startActivity");
9586        synchronized (this) {
9587            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9588            return (r != null) ? r.immersive : false;
9589        }
9590    }
9591
9592    @Override
9593    public boolean isTopOfTask(IBinder token) {
9594        synchronized (this) {
9595            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9596            if (r == null) {
9597                throw new IllegalArgumentException();
9598            }
9599            return r.task.getTopActivity() == r;
9600        }
9601    }
9602
9603    public final void enterSafeMode() {
9604        synchronized(this) {
9605            // It only makes sense to do this before the system is ready
9606            // and started launching other packages.
9607            if (!mSystemReady) {
9608                try {
9609                    AppGlobals.getPackageManager().enterSafeMode();
9610                } catch (RemoteException e) {
9611                }
9612            }
9613
9614            mSafeMode = true;
9615        }
9616    }
9617
9618    public final void showSafeModeOverlay() {
9619        View v = LayoutInflater.from(mContext).inflate(
9620                com.android.internal.R.layout.safe_mode, null);
9621        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9622        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9623        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9624        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9625        lp.gravity = Gravity.BOTTOM | Gravity.START;
9626        lp.format = v.getBackground().getOpacity();
9627        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9628                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9629        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9630        ((WindowManager)mContext.getSystemService(
9631                Context.WINDOW_SERVICE)).addView(v, lp);
9632    }
9633
9634    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9635        if (!(sender instanceof PendingIntentRecord)) {
9636            return;
9637        }
9638        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9639        synchronized (stats) {
9640            if (mBatteryStatsService.isOnBattery()) {
9641                mBatteryStatsService.enforceCallingPermission();
9642                PendingIntentRecord rec = (PendingIntentRecord)sender;
9643                int MY_UID = Binder.getCallingUid();
9644                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9645                BatteryStatsImpl.Uid.Pkg pkg =
9646                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9647                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9648                pkg.incWakeupsLocked();
9649            }
9650        }
9651    }
9652
9653    public boolean killPids(int[] pids, String pReason, boolean secure) {
9654        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9655            throw new SecurityException("killPids only available to the system");
9656        }
9657        String reason = (pReason == null) ? "Unknown" : pReason;
9658        // XXX Note: don't acquire main activity lock here, because the window
9659        // manager calls in with its locks held.
9660
9661        boolean killed = false;
9662        synchronized (mPidsSelfLocked) {
9663            int[] types = new int[pids.length];
9664            int worstType = 0;
9665            for (int i=0; i<pids.length; i++) {
9666                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9667                if (proc != null) {
9668                    int type = proc.setAdj;
9669                    types[i] = type;
9670                    if (type > worstType) {
9671                        worstType = type;
9672                    }
9673                }
9674            }
9675
9676            // If the worst oom_adj is somewhere in the cached proc LRU range,
9677            // then constrain it so we will kill all cached procs.
9678            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9679                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9680                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9681            }
9682
9683            // If this is not a secure call, don't let it kill processes that
9684            // are important.
9685            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9686                worstType = ProcessList.SERVICE_ADJ;
9687            }
9688
9689            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9690            for (int i=0; i<pids.length; i++) {
9691                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9692                if (proc == null) {
9693                    continue;
9694                }
9695                int adj = proc.setAdj;
9696                if (adj >= worstType && !proc.killedByAm) {
9697                    killUnneededProcessLocked(proc, reason);
9698                    killed = true;
9699                }
9700            }
9701        }
9702        return killed;
9703    }
9704
9705    @Override
9706    public void killUid(int uid, String reason) {
9707        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9708            throw new SecurityException("killUid only available to the system");
9709        }
9710        synchronized (this) {
9711            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9712                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9713                    reason != null ? reason : "kill uid");
9714        }
9715    }
9716
9717    @Override
9718    public boolean killProcessesBelowForeground(String reason) {
9719        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9720            throw new SecurityException("killProcessesBelowForeground() only available to system");
9721        }
9722
9723        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9724    }
9725
9726    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9727        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9728            throw new SecurityException("killProcessesBelowAdj() only available to system");
9729        }
9730
9731        boolean killed = false;
9732        synchronized (mPidsSelfLocked) {
9733            final int size = mPidsSelfLocked.size();
9734            for (int i = 0; i < size; i++) {
9735                final int pid = mPidsSelfLocked.keyAt(i);
9736                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9737                if (proc == null) continue;
9738
9739                final int adj = proc.setAdj;
9740                if (adj > belowAdj && !proc.killedByAm) {
9741                    killUnneededProcessLocked(proc, reason);
9742                    killed = true;
9743                }
9744            }
9745        }
9746        return killed;
9747    }
9748
9749    @Override
9750    public void hang(final IBinder who, boolean allowRestart) {
9751        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9752                != PackageManager.PERMISSION_GRANTED) {
9753            throw new SecurityException("Requires permission "
9754                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9755        }
9756
9757        final IBinder.DeathRecipient death = new DeathRecipient() {
9758            @Override
9759            public void binderDied() {
9760                synchronized (this) {
9761                    notifyAll();
9762                }
9763            }
9764        };
9765
9766        try {
9767            who.linkToDeath(death, 0);
9768        } catch (RemoteException e) {
9769            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9770            return;
9771        }
9772
9773        synchronized (this) {
9774            Watchdog.getInstance().setAllowRestart(allowRestart);
9775            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9776            synchronized (death) {
9777                while (who.isBinderAlive()) {
9778                    try {
9779                        death.wait();
9780                    } catch (InterruptedException e) {
9781                    }
9782                }
9783            }
9784            Watchdog.getInstance().setAllowRestart(true);
9785        }
9786    }
9787
9788    @Override
9789    public void restart() {
9790        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9791                != PackageManager.PERMISSION_GRANTED) {
9792            throw new SecurityException("Requires permission "
9793                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9794        }
9795
9796        Log.i(TAG, "Sending shutdown broadcast...");
9797
9798        BroadcastReceiver br = new BroadcastReceiver() {
9799            @Override public void onReceive(Context context, Intent intent) {
9800                // Now the broadcast is done, finish up the low-level shutdown.
9801                Log.i(TAG, "Shutting down activity manager...");
9802                shutdown(10000);
9803                Log.i(TAG, "Shutdown complete, restarting!");
9804                Process.killProcess(Process.myPid());
9805                System.exit(10);
9806            }
9807        };
9808
9809        // First send the high-level shut down broadcast.
9810        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9811        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9812        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9813        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9814        mContext.sendOrderedBroadcastAsUser(intent,
9815                UserHandle.ALL, null, br, mHandler, 0, null, null);
9816        */
9817        br.onReceive(mContext, intent);
9818    }
9819
9820    private long getLowRamTimeSinceIdle(long now) {
9821        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9822    }
9823
9824    @Override
9825    public void performIdleMaintenance() {
9826        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9827                != PackageManager.PERMISSION_GRANTED) {
9828            throw new SecurityException("Requires permission "
9829                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9830        }
9831
9832        synchronized (this) {
9833            final long now = SystemClock.uptimeMillis();
9834            final long timeSinceLastIdle = now - mLastIdleTime;
9835            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9836            mLastIdleTime = now;
9837            mLowRamTimeSinceLastIdle = 0;
9838            if (mLowRamStartTime != 0) {
9839                mLowRamStartTime = now;
9840            }
9841
9842            StringBuilder sb = new StringBuilder(128);
9843            sb.append("Idle maintenance over ");
9844            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9845            sb.append(" low RAM for ");
9846            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9847            Slog.i(TAG, sb.toString());
9848
9849            // If at least 1/3 of our time since the last idle period has been spent
9850            // with RAM low, then we want to kill processes.
9851            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9852
9853            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9854                ProcessRecord proc = mLruProcesses.get(i);
9855                if (proc.notCachedSinceIdle) {
9856                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9857                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9858                        if (doKilling && proc.initialIdlePss != 0
9859                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9860                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9861                                    + " from " + proc.initialIdlePss + ")");
9862                        }
9863                    }
9864                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9865                    proc.notCachedSinceIdle = true;
9866                    proc.initialIdlePss = 0;
9867                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9868                            isSleeping(), now);
9869                }
9870            }
9871
9872            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9873            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9874        }
9875    }
9876
9877    private void retrieveSettings() {
9878        final ContentResolver resolver = mContext.getContentResolver();
9879        String debugApp = Settings.Global.getString(
9880            resolver, Settings.Global.DEBUG_APP);
9881        boolean waitForDebugger = Settings.Global.getInt(
9882            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9883        boolean alwaysFinishActivities = Settings.Global.getInt(
9884            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9885        boolean forceRtl = Settings.Global.getInt(
9886                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9887        // Transfer any global setting for forcing RTL layout, into a System Property
9888        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9889
9890        Configuration configuration = new Configuration();
9891        Settings.System.getConfiguration(resolver, configuration);
9892        if (forceRtl) {
9893            // This will take care of setting the correct layout direction flags
9894            configuration.setLayoutDirection(configuration.locale);
9895        }
9896
9897        synchronized (this) {
9898            mDebugApp = mOrigDebugApp = debugApp;
9899            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9900            mAlwaysFinishActivities = alwaysFinishActivities;
9901            // This happens before any activities are started, so we can
9902            // change mConfiguration in-place.
9903            updateConfigurationLocked(configuration, null, false, true);
9904            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9905        }
9906    }
9907
9908    public boolean testIsSystemReady() {
9909        // no need to synchronize(this) just to read & return the value
9910        return mSystemReady;
9911    }
9912
9913    private static File getCalledPreBootReceiversFile() {
9914        File dataDir = Environment.getDataDirectory();
9915        File systemDir = new File(dataDir, "system");
9916        File fname = new File(systemDir, "called_pre_boots.dat");
9917        return fname;
9918    }
9919
9920    static final int LAST_DONE_VERSION = 10000;
9921
9922    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9923        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9924        File file = getCalledPreBootReceiversFile();
9925        FileInputStream fis = null;
9926        try {
9927            fis = new FileInputStream(file);
9928            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9929            int fvers = dis.readInt();
9930            if (fvers == LAST_DONE_VERSION) {
9931                String vers = dis.readUTF();
9932                String codename = dis.readUTF();
9933                String build = dis.readUTF();
9934                if (android.os.Build.VERSION.RELEASE.equals(vers)
9935                        && android.os.Build.VERSION.CODENAME.equals(codename)
9936                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9937                    int num = dis.readInt();
9938                    while (num > 0) {
9939                        num--;
9940                        String pkg = dis.readUTF();
9941                        String cls = dis.readUTF();
9942                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9943                    }
9944                }
9945            }
9946        } catch (FileNotFoundException e) {
9947        } catch (IOException e) {
9948            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9949        } finally {
9950            if (fis != null) {
9951                try {
9952                    fis.close();
9953                } catch (IOException e) {
9954                }
9955            }
9956        }
9957        return lastDoneReceivers;
9958    }
9959
9960    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9961        File file = getCalledPreBootReceiversFile();
9962        FileOutputStream fos = null;
9963        DataOutputStream dos = null;
9964        try {
9965            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9966            fos = new FileOutputStream(file);
9967            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9968            dos.writeInt(LAST_DONE_VERSION);
9969            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9970            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9971            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9972            dos.writeInt(list.size());
9973            for (int i=0; i<list.size(); i++) {
9974                dos.writeUTF(list.get(i).getPackageName());
9975                dos.writeUTF(list.get(i).getClassName());
9976            }
9977        } catch (IOException e) {
9978            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9979            file.delete();
9980        } finally {
9981            FileUtils.sync(fos);
9982            if (dos != null) {
9983                try {
9984                    dos.close();
9985                } catch (IOException e) {
9986                    // TODO Auto-generated catch block
9987                    e.printStackTrace();
9988                }
9989            }
9990        }
9991    }
9992
9993    public void systemReady(final Runnable goingCallback) {
9994        synchronized(this) {
9995            if (mSystemReady) {
9996                if (goingCallback != null) goingCallback.run();
9997                return;
9998            }
9999
10000            // Make sure we have the current profile info, since it is needed for
10001            // security checks.
10002            updateCurrentProfileIdsLocked();
10003
10004            if (mRecentTasks == null) {
10005                mRecentTasks = mTaskPersister.restoreTasksLocked();
10006                if (!mRecentTasks.isEmpty()) {
10007                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10008                }
10009                mTaskPersister.startPersisting();
10010            }
10011
10012            // Check to see if there are any update receivers to run.
10013            if (!mDidUpdate) {
10014                if (mWaitingUpdate) {
10015                    return;
10016                }
10017                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10018                List<ResolveInfo> ris = null;
10019                try {
10020                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
10021                            intent, null, 0, 0);
10022                } catch (RemoteException e) {
10023                }
10024                if (ris != null) {
10025                    for (int i=ris.size()-1; i>=0; i--) {
10026                        if ((ris.get(i).activityInfo.applicationInfo.flags
10027                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
10028                            ris.remove(i);
10029                        }
10030                    }
10031                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10032
10033                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10034
10035                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10036                    for (int i=0; i<ris.size(); i++) {
10037                        ActivityInfo ai = ris.get(i).activityInfo;
10038                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
10039                        if (lastDoneReceivers.contains(comp)) {
10040                            // We already did the pre boot receiver for this app with the current
10041                            // platform version, so don't do it again...
10042                            ris.remove(i);
10043                            i--;
10044                            // ...however, do keep it as one that has been done, so we don't
10045                            // forget about it when rewriting the file of last done receivers.
10046                            doneReceivers.add(comp);
10047                        }
10048                    }
10049
10050                    final int[] users = getUsersLocked();
10051                    for (int i=0; i<ris.size(); i++) {
10052                        ActivityInfo ai = ris.get(i).activityInfo;
10053                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
10054                        doneReceivers.add(comp);
10055                        intent.setComponent(comp);
10056                        for (int j=0; j<users.length; j++) {
10057                            IIntentReceiver finisher = null;
10058                            if (i == ris.size()-1 && j == users.length-1) {
10059                                finisher = new IIntentReceiver.Stub() {
10060                                    public void performReceive(Intent intent, int resultCode,
10061                                            String data, Bundle extras, boolean ordered,
10062                                            boolean sticky, int sendingUser) {
10063                                        // The raw IIntentReceiver interface is called
10064                                        // with the AM lock held, so redispatch to
10065                                        // execute our code without the lock.
10066                                        mHandler.post(new Runnable() {
10067                                            public void run() {
10068                                                synchronized (ActivityManagerService.this) {
10069                                                    mDidUpdate = true;
10070                                                }
10071                                                writeLastDonePreBootReceivers(doneReceivers);
10072                                                showBootMessage(mContext.getText(
10073                                                        R.string.android_upgrading_complete),
10074                                                        false);
10075                                                systemReady(goingCallback);
10076                                            }
10077                                        });
10078                                    }
10079                                };
10080                            }
10081                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
10082                                    + " for user " + users[j]);
10083                            broadcastIntentLocked(null, null, intent, null, finisher,
10084                                    0, null, null, null, AppOpsManager.OP_NONE,
10085                                    true, false, MY_PID, Process.SYSTEM_UID,
10086                                    users[j]);
10087                            if (finisher != null) {
10088                                mWaitingUpdate = true;
10089                            }
10090                        }
10091                    }
10092                }
10093                if (mWaitingUpdate) {
10094                    return;
10095                }
10096                mDidUpdate = true;
10097            }
10098
10099            mAppOpsService.systemReady();
10100            mUsageStatsService.systemReady();
10101            mSystemReady = true;
10102        }
10103
10104        ArrayList<ProcessRecord> procsToKill = null;
10105        synchronized(mPidsSelfLocked) {
10106            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10107                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10108                if (!isAllowedWhileBooting(proc.info)){
10109                    if (procsToKill == null) {
10110                        procsToKill = new ArrayList<ProcessRecord>();
10111                    }
10112                    procsToKill.add(proc);
10113                }
10114            }
10115        }
10116
10117        synchronized(this) {
10118            if (procsToKill != null) {
10119                for (int i=procsToKill.size()-1; i>=0; i--) {
10120                    ProcessRecord proc = procsToKill.get(i);
10121                    Slog.i(TAG, "Removing system update proc: " + proc);
10122                    removeProcessLocked(proc, true, false, "system update done");
10123                }
10124            }
10125
10126            // Now that we have cleaned up any update processes, we
10127            // are ready to start launching real processes and know that
10128            // we won't trample on them any more.
10129            mProcessesReady = true;
10130        }
10131
10132        Slog.i(TAG, "System now ready");
10133        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10134            SystemClock.uptimeMillis());
10135
10136        synchronized(this) {
10137            // Make sure we have no pre-ready processes sitting around.
10138
10139            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10140                ResolveInfo ri = mContext.getPackageManager()
10141                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10142                                STOCK_PM_FLAGS);
10143                CharSequence errorMsg = null;
10144                if (ri != null) {
10145                    ActivityInfo ai = ri.activityInfo;
10146                    ApplicationInfo app = ai.applicationInfo;
10147                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10148                        mTopAction = Intent.ACTION_FACTORY_TEST;
10149                        mTopData = null;
10150                        mTopComponent = new ComponentName(app.packageName,
10151                                ai.name);
10152                    } else {
10153                        errorMsg = mContext.getResources().getText(
10154                                com.android.internal.R.string.factorytest_not_system);
10155                    }
10156                } else {
10157                    errorMsg = mContext.getResources().getText(
10158                            com.android.internal.R.string.factorytest_no_action);
10159                }
10160                if (errorMsg != null) {
10161                    mTopAction = null;
10162                    mTopData = null;
10163                    mTopComponent = null;
10164                    Message msg = Message.obtain();
10165                    msg.what = SHOW_FACTORY_ERROR_MSG;
10166                    msg.getData().putCharSequence("msg", errorMsg);
10167                    mHandler.sendMessage(msg);
10168                }
10169            }
10170        }
10171
10172        retrieveSettings();
10173
10174        synchronized (this) {
10175            readGrantedUriPermissionsLocked();
10176        }
10177
10178        if (goingCallback != null) goingCallback.run();
10179
10180        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10181                Integer.toString(mCurrentUserId), mCurrentUserId);
10182        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10183                Integer.toString(mCurrentUserId), mCurrentUserId);
10184        mSystemServiceManager.startUser(mCurrentUserId);
10185
10186        synchronized (this) {
10187            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10188                try {
10189                    List apps = AppGlobals.getPackageManager().
10190                        getPersistentApplications(STOCK_PM_FLAGS);
10191                    if (apps != null) {
10192                        int N = apps.size();
10193                        int i;
10194                        for (i=0; i<N; i++) {
10195                            ApplicationInfo info
10196                                = (ApplicationInfo)apps.get(i);
10197                            if (info != null &&
10198                                    !info.packageName.equals("android")) {
10199                                addAppLocked(info, false, null /* ABI override */);
10200                            }
10201                        }
10202                    }
10203                } catch (RemoteException ex) {
10204                    // pm is in same process, this will never happen.
10205                }
10206            }
10207
10208            // Start up initial activity.
10209            mBooting = true;
10210
10211            try {
10212                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10213                    Message msg = Message.obtain();
10214                    msg.what = SHOW_UID_ERROR_MSG;
10215                    mHandler.sendMessage(msg);
10216                }
10217            } catch (RemoteException e) {
10218            }
10219
10220            long ident = Binder.clearCallingIdentity();
10221            try {
10222                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10223                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10224                        | Intent.FLAG_RECEIVER_FOREGROUND);
10225                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10226                broadcastIntentLocked(null, null, intent,
10227                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10228                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10229                intent = new Intent(Intent.ACTION_USER_STARTING);
10230                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10231                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10232                broadcastIntentLocked(null, null, intent,
10233                        null, new IIntentReceiver.Stub() {
10234                            @Override
10235                            public void performReceive(Intent intent, int resultCode, String data,
10236                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10237                                    throws RemoteException {
10238                            }
10239                        }, 0, null, null,
10240                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10241                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10242            } catch (Throwable t) {
10243                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10244            } finally {
10245                Binder.restoreCallingIdentity(ident);
10246            }
10247            mStackSupervisor.resumeTopActivitiesLocked();
10248            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10249        }
10250    }
10251
10252    private boolean makeAppCrashingLocked(ProcessRecord app,
10253            String shortMsg, String longMsg, String stackTrace) {
10254        app.crashing = true;
10255        app.crashingReport = generateProcessError(app,
10256                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10257        startAppProblemLocked(app);
10258        app.stopFreezingAllLocked();
10259        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10260    }
10261
10262    private void makeAppNotRespondingLocked(ProcessRecord app,
10263            String activity, String shortMsg, String longMsg) {
10264        app.notResponding = true;
10265        app.notRespondingReport = generateProcessError(app,
10266                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10267                activity, shortMsg, longMsg, null);
10268        startAppProblemLocked(app);
10269        app.stopFreezingAllLocked();
10270    }
10271
10272    /**
10273     * Generate a process error record, suitable for attachment to a ProcessRecord.
10274     *
10275     * @param app The ProcessRecord in which the error occurred.
10276     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10277     *                      ActivityManager.AppErrorStateInfo
10278     * @param activity The activity associated with the crash, if known.
10279     * @param shortMsg Short message describing the crash.
10280     * @param longMsg Long message describing the crash.
10281     * @param stackTrace Full crash stack trace, may be null.
10282     *
10283     * @return Returns a fully-formed AppErrorStateInfo record.
10284     */
10285    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10286            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10287        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10288
10289        report.condition = condition;
10290        report.processName = app.processName;
10291        report.pid = app.pid;
10292        report.uid = app.info.uid;
10293        report.tag = activity;
10294        report.shortMsg = shortMsg;
10295        report.longMsg = longMsg;
10296        report.stackTrace = stackTrace;
10297
10298        return report;
10299    }
10300
10301    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10302        synchronized (this) {
10303            app.crashing = false;
10304            app.crashingReport = null;
10305            app.notResponding = false;
10306            app.notRespondingReport = null;
10307            if (app.anrDialog == fromDialog) {
10308                app.anrDialog = null;
10309            }
10310            if (app.waitDialog == fromDialog) {
10311                app.waitDialog = null;
10312            }
10313            if (app.pid > 0 && app.pid != MY_PID) {
10314                handleAppCrashLocked(app, null, null, null);
10315                killUnneededProcessLocked(app, "user request after error");
10316            }
10317        }
10318    }
10319
10320    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10321            String stackTrace) {
10322        long now = SystemClock.uptimeMillis();
10323
10324        Long crashTime;
10325        if (!app.isolated) {
10326            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10327        } else {
10328            crashTime = null;
10329        }
10330        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10331            // This process loses!
10332            Slog.w(TAG, "Process " + app.info.processName
10333                    + " has crashed too many times: killing!");
10334            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10335                    app.userId, app.info.processName, app.uid);
10336            mStackSupervisor.handleAppCrashLocked(app);
10337            if (!app.persistent) {
10338                // We don't want to start this process again until the user
10339                // explicitly does so...  but for persistent process, we really
10340                // need to keep it running.  If a persistent process is actually
10341                // repeatedly crashing, then badness for everyone.
10342                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10343                        app.info.processName);
10344                if (!app.isolated) {
10345                    // XXX We don't have a way to mark isolated processes
10346                    // as bad, since they don't have a peristent identity.
10347                    mBadProcesses.put(app.info.processName, app.uid,
10348                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10349                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10350                }
10351                app.bad = true;
10352                app.removed = true;
10353                // Don't let services in this process be restarted and potentially
10354                // annoy the user repeatedly.  Unless it is persistent, since those
10355                // processes run critical code.
10356                removeProcessLocked(app, false, false, "crash");
10357                mStackSupervisor.resumeTopActivitiesLocked();
10358                return false;
10359            }
10360            mStackSupervisor.resumeTopActivitiesLocked();
10361        } else {
10362            mStackSupervisor.finishTopRunningActivityLocked(app);
10363        }
10364
10365        // Bump up the crash count of any services currently running in the proc.
10366        for (int i=app.services.size()-1; i>=0; i--) {
10367            // Any services running in the application need to be placed
10368            // back in the pending list.
10369            ServiceRecord sr = app.services.valueAt(i);
10370            sr.crashCount++;
10371        }
10372
10373        // If the crashing process is what we consider to be the "home process" and it has been
10374        // replaced by a third-party app, clear the package preferred activities from packages
10375        // with a home activity running in the process to prevent a repeatedly crashing app
10376        // from blocking the user to manually clear the list.
10377        final ArrayList<ActivityRecord> activities = app.activities;
10378        if (app == mHomeProcess && activities.size() > 0
10379                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10380            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10381                final ActivityRecord r = activities.get(activityNdx);
10382                if (r.isHomeActivity()) {
10383                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10384                    try {
10385                        ActivityThread.getPackageManager()
10386                                .clearPackagePreferredActivities(r.packageName);
10387                    } catch (RemoteException c) {
10388                        // pm is in same process, this will never happen.
10389                    }
10390                }
10391            }
10392        }
10393
10394        if (!app.isolated) {
10395            // XXX Can't keep track of crash times for isolated processes,
10396            // because they don't have a perisistent identity.
10397            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10398        }
10399
10400        return true;
10401    }
10402
10403    void startAppProblemLocked(ProcessRecord app) {
10404        if (app.userId == mCurrentUserId) {
10405            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10406                    mContext, app.info.packageName, app.info.flags);
10407        } else {
10408            // If this app is not running under the current user, then we
10409            // can't give it a report button because that would require
10410            // launching the report UI under a different user.
10411            app.errorReportReceiver = null;
10412        }
10413        skipCurrentReceiverLocked(app);
10414    }
10415
10416    void skipCurrentReceiverLocked(ProcessRecord app) {
10417        for (BroadcastQueue queue : mBroadcastQueues) {
10418            queue.skipCurrentReceiverLocked(app);
10419        }
10420    }
10421
10422    /**
10423     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10424     * The application process will exit immediately after this call returns.
10425     * @param app object of the crashing app, null for the system server
10426     * @param crashInfo describing the exception
10427     */
10428    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10429        ProcessRecord r = findAppProcess(app, "Crash");
10430        final String processName = app == null ? "system_server"
10431                : (r == null ? "unknown" : r.processName);
10432
10433        handleApplicationCrashInner("crash", r, processName, crashInfo);
10434    }
10435
10436    /* Native crash reporting uses this inner version because it needs to be somewhat
10437     * decoupled from the AM-managed cleanup lifecycle
10438     */
10439    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10440            ApplicationErrorReport.CrashInfo crashInfo) {
10441        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10442                UserHandle.getUserId(Binder.getCallingUid()), processName,
10443                r == null ? -1 : r.info.flags,
10444                crashInfo.exceptionClassName,
10445                crashInfo.exceptionMessage,
10446                crashInfo.throwFileName,
10447                crashInfo.throwLineNumber);
10448
10449        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10450
10451        crashApplication(r, crashInfo);
10452    }
10453
10454    public void handleApplicationStrictModeViolation(
10455            IBinder app,
10456            int violationMask,
10457            StrictMode.ViolationInfo info) {
10458        ProcessRecord r = findAppProcess(app, "StrictMode");
10459        if (r == null) {
10460            return;
10461        }
10462
10463        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10464            Integer stackFingerprint = info.hashCode();
10465            boolean logIt = true;
10466            synchronized (mAlreadyLoggedViolatedStacks) {
10467                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10468                    logIt = false;
10469                    // TODO: sub-sample into EventLog for these, with
10470                    // the info.durationMillis?  Then we'd get
10471                    // the relative pain numbers, without logging all
10472                    // the stack traces repeatedly.  We'd want to do
10473                    // likewise in the client code, which also does
10474                    // dup suppression, before the Binder call.
10475                } else {
10476                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10477                        mAlreadyLoggedViolatedStacks.clear();
10478                    }
10479                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10480                }
10481            }
10482            if (logIt) {
10483                logStrictModeViolationToDropBox(r, info);
10484            }
10485        }
10486
10487        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10488            AppErrorResult result = new AppErrorResult();
10489            synchronized (this) {
10490                final long origId = Binder.clearCallingIdentity();
10491
10492                Message msg = Message.obtain();
10493                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10494                HashMap<String, Object> data = new HashMap<String, Object>();
10495                data.put("result", result);
10496                data.put("app", r);
10497                data.put("violationMask", violationMask);
10498                data.put("info", info);
10499                msg.obj = data;
10500                mHandler.sendMessage(msg);
10501
10502                Binder.restoreCallingIdentity(origId);
10503            }
10504            int res = result.get();
10505            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10506        }
10507    }
10508
10509    // Depending on the policy in effect, there could be a bunch of
10510    // these in quick succession so we try to batch these together to
10511    // minimize disk writes, number of dropbox entries, and maximize
10512    // compression, by having more fewer, larger records.
10513    private void logStrictModeViolationToDropBox(
10514            ProcessRecord process,
10515            StrictMode.ViolationInfo info) {
10516        if (info == null) {
10517            return;
10518        }
10519        final boolean isSystemApp = process == null ||
10520                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10521                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10522        final String processName = process == null ? "unknown" : process.processName;
10523        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10524        final DropBoxManager dbox = (DropBoxManager)
10525                mContext.getSystemService(Context.DROPBOX_SERVICE);
10526
10527        // Exit early if the dropbox isn't configured to accept this report type.
10528        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10529
10530        boolean bufferWasEmpty;
10531        boolean needsFlush;
10532        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10533        synchronized (sb) {
10534            bufferWasEmpty = sb.length() == 0;
10535            appendDropBoxProcessHeaders(process, processName, sb);
10536            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10537            sb.append("System-App: ").append(isSystemApp).append("\n");
10538            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10539            if (info.violationNumThisLoop != 0) {
10540                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10541            }
10542            if (info.numAnimationsRunning != 0) {
10543                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10544            }
10545            if (info.broadcastIntentAction != null) {
10546                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10547            }
10548            if (info.durationMillis != -1) {
10549                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10550            }
10551            if (info.numInstances != -1) {
10552                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10553            }
10554            if (info.tags != null) {
10555                for (String tag : info.tags) {
10556                    sb.append("Span-Tag: ").append(tag).append("\n");
10557                }
10558            }
10559            sb.append("\n");
10560            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10561                sb.append(info.crashInfo.stackTrace);
10562            }
10563            sb.append("\n");
10564
10565            // Only buffer up to ~64k.  Various logging bits truncate
10566            // things at 128k.
10567            needsFlush = (sb.length() > 64 * 1024);
10568        }
10569
10570        // Flush immediately if the buffer's grown too large, or this
10571        // is a non-system app.  Non-system apps are isolated with a
10572        // different tag & policy and not batched.
10573        //
10574        // Batching is useful during internal testing with
10575        // StrictMode settings turned up high.  Without batching,
10576        // thousands of separate files could be created on boot.
10577        if (!isSystemApp || needsFlush) {
10578            new Thread("Error dump: " + dropboxTag) {
10579                @Override
10580                public void run() {
10581                    String report;
10582                    synchronized (sb) {
10583                        report = sb.toString();
10584                        sb.delete(0, sb.length());
10585                        sb.trimToSize();
10586                    }
10587                    if (report.length() != 0) {
10588                        dbox.addText(dropboxTag, report);
10589                    }
10590                }
10591            }.start();
10592            return;
10593        }
10594
10595        // System app batching:
10596        if (!bufferWasEmpty) {
10597            // An existing dropbox-writing thread is outstanding, so
10598            // we don't need to start it up.  The existing thread will
10599            // catch the buffer appends we just did.
10600            return;
10601        }
10602
10603        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10604        // (After this point, we shouldn't access AMS internal data structures.)
10605        new Thread("Error dump: " + dropboxTag) {
10606            @Override
10607            public void run() {
10608                // 5 second sleep to let stacks arrive and be batched together
10609                try {
10610                    Thread.sleep(5000);  // 5 seconds
10611                } catch (InterruptedException e) {}
10612
10613                String errorReport;
10614                synchronized (mStrictModeBuffer) {
10615                    errorReport = mStrictModeBuffer.toString();
10616                    if (errorReport.length() == 0) {
10617                        return;
10618                    }
10619                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10620                    mStrictModeBuffer.trimToSize();
10621                }
10622                dbox.addText(dropboxTag, errorReport);
10623            }
10624        }.start();
10625    }
10626
10627    /**
10628     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10629     * @param app object of the crashing app, null for the system server
10630     * @param tag reported by the caller
10631     * @param crashInfo describing the context of the error
10632     * @return true if the process should exit immediately (WTF is fatal)
10633     */
10634    public boolean handleApplicationWtf(IBinder app, String tag,
10635            ApplicationErrorReport.CrashInfo crashInfo) {
10636        ProcessRecord r = findAppProcess(app, "WTF");
10637        final String processName = app == null ? "system_server"
10638                : (r == null ? "unknown" : r.processName);
10639
10640        EventLog.writeEvent(EventLogTags.AM_WTF,
10641                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10642                processName,
10643                r == null ? -1 : r.info.flags,
10644                tag, crashInfo.exceptionMessage);
10645
10646        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10647
10648        if (r != null && r.pid != Process.myPid() &&
10649                Settings.Global.getInt(mContext.getContentResolver(),
10650                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10651            crashApplication(r, crashInfo);
10652            return true;
10653        } else {
10654            return false;
10655        }
10656    }
10657
10658    /**
10659     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10660     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10661     */
10662    private ProcessRecord findAppProcess(IBinder app, String reason) {
10663        if (app == null) {
10664            return null;
10665        }
10666
10667        synchronized (this) {
10668            final int NP = mProcessNames.getMap().size();
10669            for (int ip=0; ip<NP; ip++) {
10670                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10671                final int NA = apps.size();
10672                for (int ia=0; ia<NA; ia++) {
10673                    ProcessRecord p = apps.valueAt(ia);
10674                    if (p.thread != null && p.thread.asBinder() == app) {
10675                        return p;
10676                    }
10677                }
10678            }
10679
10680            Slog.w(TAG, "Can't find mystery application for " + reason
10681                    + " from pid=" + Binder.getCallingPid()
10682                    + " uid=" + Binder.getCallingUid() + ": " + app);
10683            return null;
10684        }
10685    }
10686
10687    /**
10688     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10689     * to append various headers to the dropbox log text.
10690     */
10691    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10692            StringBuilder sb) {
10693        // Watchdog thread ends up invoking this function (with
10694        // a null ProcessRecord) to add the stack file to dropbox.
10695        // Do not acquire a lock on this (am) in such cases, as it
10696        // could cause a potential deadlock, if and when watchdog
10697        // is invoked due to unavailability of lock on am and it
10698        // would prevent watchdog from killing system_server.
10699        if (process == null) {
10700            sb.append("Process: ").append(processName).append("\n");
10701            return;
10702        }
10703        // Note: ProcessRecord 'process' is guarded by the service
10704        // instance.  (notably process.pkgList, which could otherwise change
10705        // concurrently during execution of this method)
10706        synchronized (this) {
10707            sb.append("Process: ").append(processName).append("\n");
10708            int flags = process.info.flags;
10709            IPackageManager pm = AppGlobals.getPackageManager();
10710            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10711            for (int ip=0; ip<process.pkgList.size(); ip++) {
10712                String pkg = process.pkgList.keyAt(ip);
10713                sb.append("Package: ").append(pkg);
10714                try {
10715                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10716                    if (pi != null) {
10717                        sb.append(" v").append(pi.versionCode);
10718                        if (pi.versionName != null) {
10719                            sb.append(" (").append(pi.versionName).append(")");
10720                        }
10721                    }
10722                } catch (RemoteException e) {
10723                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10724                }
10725                sb.append("\n");
10726            }
10727        }
10728    }
10729
10730    private static String processClass(ProcessRecord process) {
10731        if (process == null || process.pid == MY_PID) {
10732            return "system_server";
10733        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10734            return "system_app";
10735        } else {
10736            return "data_app";
10737        }
10738    }
10739
10740    /**
10741     * Write a description of an error (crash, WTF, ANR) to the drop box.
10742     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10743     * @param process which caused the error, null means the system server
10744     * @param activity which triggered the error, null if unknown
10745     * @param parent activity related to the error, null if unknown
10746     * @param subject line related to the error, null if absent
10747     * @param report in long form describing the error, null if absent
10748     * @param logFile to include in the report, null if none
10749     * @param crashInfo giving an application stack trace, null if absent
10750     */
10751    public void addErrorToDropBox(String eventType,
10752            ProcessRecord process, String processName, ActivityRecord activity,
10753            ActivityRecord parent, String subject,
10754            final String report, final File logFile,
10755            final ApplicationErrorReport.CrashInfo crashInfo) {
10756        // NOTE -- this must never acquire the ActivityManagerService lock,
10757        // otherwise the watchdog may be prevented from resetting the system.
10758
10759        final String dropboxTag = processClass(process) + "_" + eventType;
10760        final DropBoxManager dbox = (DropBoxManager)
10761                mContext.getSystemService(Context.DROPBOX_SERVICE);
10762
10763        // Exit early if the dropbox isn't configured to accept this report type.
10764        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10765
10766        final StringBuilder sb = new StringBuilder(1024);
10767        appendDropBoxProcessHeaders(process, processName, sb);
10768        if (activity != null) {
10769            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10770        }
10771        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10772            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10773        }
10774        if (parent != null && parent != activity) {
10775            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10776        }
10777        if (subject != null) {
10778            sb.append("Subject: ").append(subject).append("\n");
10779        }
10780        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10781        if (Debug.isDebuggerConnected()) {
10782            sb.append("Debugger: Connected\n");
10783        }
10784        sb.append("\n");
10785
10786        // Do the rest in a worker thread to avoid blocking the caller on I/O
10787        // (After this point, we shouldn't access AMS internal data structures.)
10788        Thread worker = new Thread("Error dump: " + dropboxTag) {
10789            @Override
10790            public void run() {
10791                if (report != null) {
10792                    sb.append(report);
10793                }
10794                if (logFile != null) {
10795                    try {
10796                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10797                                    "\n\n[[TRUNCATED]]"));
10798                    } catch (IOException e) {
10799                        Slog.e(TAG, "Error reading " + logFile, e);
10800                    }
10801                }
10802                if (crashInfo != null && crashInfo.stackTrace != null) {
10803                    sb.append(crashInfo.stackTrace);
10804                }
10805
10806                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10807                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10808                if (lines > 0) {
10809                    sb.append("\n");
10810
10811                    // Merge several logcat streams, and take the last N lines
10812                    InputStreamReader input = null;
10813                    try {
10814                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10815                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10816                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10817
10818                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10819                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10820                        input = new InputStreamReader(logcat.getInputStream());
10821
10822                        int num;
10823                        char[] buf = new char[8192];
10824                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10825                    } catch (IOException e) {
10826                        Slog.e(TAG, "Error running logcat", e);
10827                    } finally {
10828                        if (input != null) try { input.close(); } catch (IOException e) {}
10829                    }
10830                }
10831
10832                dbox.addText(dropboxTag, sb.toString());
10833            }
10834        };
10835
10836        if (process == null) {
10837            // If process is null, we are being called from some internal code
10838            // and may be about to die -- run this synchronously.
10839            worker.run();
10840        } else {
10841            worker.start();
10842        }
10843    }
10844
10845    /**
10846     * Bring up the "unexpected error" dialog box for a crashing app.
10847     * Deal with edge cases (intercepts from instrumented applications,
10848     * ActivityController, error intent receivers, that sort of thing).
10849     * @param r the application crashing
10850     * @param crashInfo describing the failure
10851     */
10852    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10853        long timeMillis = System.currentTimeMillis();
10854        String shortMsg = crashInfo.exceptionClassName;
10855        String longMsg = crashInfo.exceptionMessage;
10856        String stackTrace = crashInfo.stackTrace;
10857        if (shortMsg != null && longMsg != null) {
10858            longMsg = shortMsg + ": " + longMsg;
10859        } else if (shortMsg != null) {
10860            longMsg = shortMsg;
10861        }
10862
10863        AppErrorResult result = new AppErrorResult();
10864        synchronized (this) {
10865            if (mController != null) {
10866                try {
10867                    String name = r != null ? r.processName : null;
10868                    int pid = r != null ? r.pid : Binder.getCallingPid();
10869                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
10870                    if (!mController.appCrashed(name, pid,
10871                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10872                        Slog.w(TAG, "Force-killing crashed app " + name
10873                                + " at watcher's request");
10874                        Process.killProcess(pid);
10875                        if (r != null) {
10876                            Process.killProcessGroup(uid, pid);
10877                        }
10878                        return;
10879                    }
10880                } catch (RemoteException e) {
10881                    mController = null;
10882                    Watchdog.getInstance().setActivityController(null);
10883                }
10884            }
10885
10886            final long origId = Binder.clearCallingIdentity();
10887
10888            // If this process is running instrumentation, finish it.
10889            if (r != null && r.instrumentationClass != null) {
10890                Slog.w(TAG, "Error in app " + r.processName
10891                      + " running instrumentation " + r.instrumentationClass + ":");
10892                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10893                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10894                Bundle info = new Bundle();
10895                info.putString("shortMsg", shortMsg);
10896                info.putString("longMsg", longMsg);
10897                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10898                Binder.restoreCallingIdentity(origId);
10899                return;
10900            }
10901
10902            // If we can't identify the process or it's already exceeded its crash quota,
10903            // quit right away without showing a crash dialog.
10904            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10905                Binder.restoreCallingIdentity(origId);
10906                return;
10907            }
10908
10909            Message msg = Message.obtain();
10910            msg.what = SHOW_ERROR_MSG;
10911            HashMap data = new HashMap();
10912            data.put("result", result);
10913            data.put("app", r);
10914            msg.obj = data;
10915            mHandler.sendMessage(msg);
10916
10917            Binder.restoreCallingIdentity(origId);
10918        }
10919
10920        int res = result.get();
10921
10922        Intent appErrorIntent = null;
10923        synchronized (this) {
10924            if (r != null && !r.isolated) {
10925                // XXX Can't keep track of crash time for isolated processes,
10926                // since they don't have a persistent identity.
10927                mProcessCrashTimes.put(r.info.processName, r.uid,
10928                        SystemClock.uptimeMillis());
10929            }
10930            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10931                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10932            }
10933        }
10934
10935        if (appErrorIntent != null) {
10936            try {
10937                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10938            } catch (ActivityNotFoundException e) {
10939                Slog.w(TAG, "bug report receiver dissappeared", e);
10940            }
10941        }
10942    }
10943
10944    Intent createAppErrorIntentLocked(ProcessRecord r,
10945            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10946        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10947        if (report == null) {
10948            return null;
10949        }
10950        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10951        result.setComponent(r.errorReportReceiver);
10952        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10953        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10954        return result;
10955    }
10956
10957    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10958            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10959        if (r.errorReportReceiver == null) {
10960            return null;
10961        }
10962
10963        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10964            return null;
10965        }
10966
10967        ApplicationErrorReport report = new ApplicationErrorReport();
10968        report.packageName = r.info.packageName;
10969        report.installerPackageName = r.errorReportReceiver.getPackageName();
10970        report.processName = r.processName;
10971        report.time = timeMillis;
10972        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10973
10974        if (r.crashing || r.forceCrashReport) {
10975            report.type = ApplicationErrorReport.TYPE_CRASH;
10976            report.crashInfo = crashInfo;
10977        } else if (r.notResponding) {
10978            report.type = ApplicationErrorReport.TYPE_ANR;
10979            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10980
10981            report.anrInfo.activity = r.notRespondingReport.tag;
10982            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10983            report.anrInfo.info = r.notRespondingReport.longMsg;
10984        }
10985
10986        return report;
10987    }
10988
10989    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10990        enforceNotIsolatedCaller("getProcessesInErrorState");
10991        // assume our apps are happy - lazy create the list
10992        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10993
10994        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10995                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10996        int userId = UserHandle.getUserId(Binder.getCallingUid());
10997
10998        synchronized (this) {
10999
11000            // iterate across all processes
11001            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11002                ProcessRecord app = mLruProcesses.get(i);
11003                if (!allUsers && app.userId != userId) {
11004                    continue;
11005                }
11006                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11007                    // This one's in trouble, so we'll generate a report for it
11008                    // crashes are higher priority (in case there's a crash *and* an anr)
11009                    ActivityManager.ProcessErrorStateInfo report = null;
11010                    if (app.crashing) {
11011                        report = app.crashingReport;
11012                    } else if (app.notResponding) {
11013                        report = app.notRespondingReport;
11014                    }
11015
11016                    if (report != null) {
11017                        if (errList == null) {
11018                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11019                        }
11020                        errList.add(report);
11021                    } else {
11022                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11023                                " crashing = " + app.crashing +
11024                                " notResponding = " + app.notResponding);
11025                    }
11026                }
11027            }
11028        }
11029
11030        return errList;
11031    }
11032
11033    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
11034        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
11035            if (currApp != null) {
11036                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
11037            }
11038            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
11039        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
11040            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
11041        } else if (adj >= ProcessList.HOME_APP_ADJ) {
11042            if (currApp != null) {
11043                currApp.lru = 0;
11044            }
11045            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
11046        } else if (adj >= ProcessList.SERVICE_ADJ) {
11047            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
11048        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
11049            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
11050        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
11051            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
11052        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
11053            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
11054        } else {
11055            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
11056        }
11057    }
11058
11059    private void fillInProcMemInfo(ProcessRecord app,
11060            ActivityManager.RunningAppProcessInfo outInfo) {
11061        outInfo.pid = app.pid;
11062        outInfo.uid = app.info.uid;
11063        if (mHeavyWeightProcess == app) {
11064            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11065        }
11066        if (app.persistent) {
11067            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11068        }
11069        if (app.activities.size() > 0) {
11070            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11071        }
11072        outInfo.lastTrimLevel = app.trimMemoryLevel;
11073        int adj = app.curAdj;
11074        outInfo.importance = oomAdjToImportance(adj, outInfo);
11075        outInfo.importanceReasonCode = app.adjTypeCode;
11076        outInfo.processState = app.curProcState;
11077    }
11078
11079    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11080        enforceNotIsolatedCaller("getRunningAppProcesses");
11081        // Lazy instantiation of list
11082        List<ActivityManager.RunningAppProcessInfo> runList = null;
11083        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11084                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11085        int userId = UserHandle.getUserId(Binder.getCallingUid());
11086        synchronized (this) {
11087            // Iterate across all processes
11088            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11089                ProcessRecord app = mLruProcesses.get(i);
11090                if (!allUsers && app.userId != userId) {
11091                    continue;
11092                }
11093                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11094                    // Generate process state info for running application
11095                    ActivityManager.RunningAppProcessInfo currApp =
11096                        new ActivityManager.RunningAppProcessInfo(app.processName,
11097                                app.pid, app.getPackageList());
11098                    fillInProcMemInfo(app, currApp);
11099                    if (app.adjSource instanceof ProcessRecord) {
11100                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11101                        currApp.importanceReasonImportance = oomAdjToImportance(
11102                                app.adjSourceOom, null);
11103                    } else if (app.adjSource instanceof ActivityRecord) {
11104                        ActivityRecord r = (ActivityRecord)app.adjSource;
11105                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11106                    }
11107                    if (app.adjTarget instanceof ComponentName) {
11108                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11109                    }
11110                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11111                    //        + " lru=" + currApp.lru);
11112                    if (runList == null) {
11113                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11114                    }
11115                    runList.add(currApp);
11116                }
11117            }
11118        }
11119        return runList;
11120    }
11121
11122    public List<ApplicationInfo> getRunningExternalApplications() {
11123        enforceNotIsolatedCaller("getRunningExternalApplications");
11124        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11125        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11126        if (runningApps != null && runningApps.size() > 0) {
11127            Set<String> extList = new HashSet<String>();
11128            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11129                if (app.pkgList != null) {
11130                    for (String pkg : app.pkgList) {
11131                        extList.add(pkg);
11132                    }
11133                }
11134            }
11135            IPackageManager pm = AppGlobals.getPackageManager();
11136            for (String pkg : extList) {
11137                try {
11138                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11139                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11140                        retList.add(info);
11141                    }
11142                } catch (RemoteException e) {
11143                }
11144            }
11145        }
11146        return retList;
11147    }
11148
11149    @Override
11150    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11151        enforceNotIsolatedCaller("getMyMemoryState");
11152        synchronized (this) {
11153            ProcessRecord proc;
11154            synchronized (mPidsSelfLocked) {
11155                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11156            }
11157            fillInProcMemInfo(proc, outInfo);
11158        }
11159    }
11160
11161    @Override
11162    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11163        if (checkCallingPermission(android.Manifest.permission.DUMP)
11164                != PackageManager.PERMISSION_GRANTED) {
11165            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11166                    + Binder.getCallingPid()
11167                    + ", uid=" + Binder.getCallingUid()
11168                    + " without permission "
11169                    + android.Manifest.permission.DUMP);
11170            return;
11171        }
11172
11173        boolean dumpAll = false;
11174        boolean dumpClient = false;
11175        String dumpPackage = null;
11176
11177        int opti = 0;
11178        while (opti < args.length) {
11179            String opt = args[opti];
11180            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11181                break;
11182            }
11183            opti++;
11184            if ("-a".equals(opt)) {
11185                dumpAll = true;
11186            } else if ("-c".equals(opt)) {
11187                dumpClient = true;
11188            } else if ("-h".equals(opt)) {
11189                pw.println("Activity manager dump options:");
11190                pw.println("  [-a] [-c] [-h] [cmd] ...");
11191                pw.println("  cmd may be one of:");
11192                pw.println("    a[ctivities]: activity stack state");
11193                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11194                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11195                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11196                pw.println("    o[om]: out of memory management");
11197                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11198                pw.println("    provider [COMP_SPEC]: provider client-side state");
11199                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11200                pw.println("    service [COMP_SPEC]: service client-side state");
11201                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11202                pw.println("    all: dump all activities");
11203                pw.println("    top: dump the top activity");
11204                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11205                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11206                pw.println("    a partial substring in a component name, a");
11207                pw.println("    hex object identifier.");
11208                pw.println("  -a: include all available server state.");
11209                pw.println("  -c: include client state.");
11210                return;
11211            } else {
11212                pw.println("Unknown argument: " + opt + "; use -h for help");
11213            }
11214        }
11215
11216        long origId = Binder.clearCallingIdentity();
11217        boolean more = false;
11218        // Is the caller requesting to dump a particular piece of data?
11219        if (opti < args.length) {
11220            String cmd = args[opti];
11221            opti++;
11222            if ("activities".equals(cmd) || "a".equals(cmd)) {
11223                synchronized (this) {
11224                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11225                }
11226            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11227                String[] newArgs;
11228                String name;
11229                if (opti >= args.length) {
11230                    name = null;
11231                    newArgs = EMPTY_STRING_ARRAY;
11232                } else {
11233                    name = args[opti];
11234                    opti++;
11235                    newArgs = new String[args.length - opti];
11236                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11237                            args.length - opti);
11238                }
11239                synchronized (this) {
11240                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11241                }
11242            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11243                String[] newArgs;
11244                String name;
11245                if (opti >= args.length) {
11246                    name = null;
11247                    newArgs = EMPTY_STRING_ARRAY;
11248                } else {
11249                    name = args[opti];
11250                    opti++;
11251                    newArgs = new String[args.length - opti];
11252                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11253                            args.length - opti);
11254                }
11255                synchronized (this) {
11256                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11257                }
11258            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11259                String[] newArgs;
11260                String name;
11261                if (opti >= args.length) {
11262                    name = null;
11263                    newArgs = EMPTY_STRING_ARRAY;
11264                } else {
11265                    name = args[opti];
11266                    opti++;
11267                    newArgs = new String[args.length - opti];
11268                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11269                            args.length - opti);
11270                }
11271                synchronized (this) {
11272                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11273                }
11274            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11275                synchronized (this) {
11276                    dumpOomLocked(fd, pw, args, opti, true);
11277                }
11278            } else if ("provider".equals(cmd)) {
11279                String[] newArgs;
11280                String name;
11281                if (opti >= args.length) {
11282                    name = null;
11283                    newArgs = EMPTY_STRING_ARRAY;
11284                } else {
11285                    name = args[opti];
11286                    opti++;
11287                    newArgs = new String[args.length - opti];
11288                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11289                }
11290                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11291                    pw.println("No providers match: " + name);
11292                    pw.println("Use -h for help.");
11293                }
11294            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11295                synchronized (this) {
11296                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11297                }
11298            } else if ("service".equals(cmd)) {
11299                String[] newArgs;
11300                String name;
11301                if (opti >= args.length) {
11302                    name = null;
11303                    newArgs = EMPTY_STRING_ARRAY;
11304                } else {
11305                    name = args[opti];
11306                    opti++;
11307                    newArgs = new String[args.length - opti];
11308                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11309                            args.length - opti);
11310                }
11311                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11312                    pw.println("No services match: " + name);
11313                    pw.println("Use -h for help.");
11314                }
11315            } else if ("package".equals(cmd)) {
11316                String[] newArgs;
11317                if (opti >= args.length) {
11318                    pw.println("package: no package name specified");
11319                    pw.println("Use -h for help.");
11320                } else {
11321                    dumpPackage = args[opti];
11322                    opti++;
11323                    newArgs = new String[args.length - opti];
11324                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11325                            args.length - opti);
11326                    args = newArgs;
11327                    opti = 0;
11328                    more = true;
11329                }
11330            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11331                synchronized (this) {
11332                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11333                }
11334            } else {
11335                // Dumping a single activity?
11336                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11337                    pw.println("Bad activity command, or no activities match: " + cmd);
11338                    pw.println("Use -h for help.");
11339                }
11340            }
11341            if (!more) {
11342                Binder.restoreCallingIdentity(origId);
11343                return;
11344            }
11345        }
11346
11347        // No piece of data specified, dump everything.
11348        synchronized (this) {
11349            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11350            pw.println();
11351            if (dumpAll) {
11352                pw.println("-------------------------------------------------------------------------------");
11353            }
11354            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11355            pw.println();
11356            if (dumpAll) {
11357                pw.println("-------------------------------------------------------------------------------");
11358            }
11359            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11360            pw.println();
11361            if (dumpAll) {
11362                pw.println("-------------------------------------------------------------------------------");
11363            }
11364            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11365            pw.println();
11366            if (dumpAll) {
11367                pw.println("-------------------------------------------------------------------------------");
11368            }
11369            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11370            pw.println();
11371            if (dumpAll) {
11372                pw.println("-------------------------------------------------------------------------------");
11373            }
11374            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11375        }
11376        Binder.restoreCallingIdentity(origId);
11377    }
11378
11379    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11380            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11381        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11382
11383        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11384                dumpPackage);
11385        boolean needSep = printedAnything;
11386
11387        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11388                dumpPackage, needSep, "  mFocusedActivity: ");
11389        if (printed) {
11390            printedAnything = true;
11391            needSep = false;
11392        }
11393
11394        if (dumpPackage == null) {
11395            if (needSep) {
11396                pw.println();
11397            }
11398            needSep = true;
11399            printedAnything = true;
11400            mStackSupervisor.dump(pw, "  ");
11401        }
11402
11403        if (mRecentTasks.size() > 0) {
11404            boolean printedHeader = false;
11405
11406            final int N = mRecentTasks.size();
11407            for (int i=0; i<N; i++) {
11408                TaskRecord tr = mRecentTasks.get(i);
11409                if (dumpPackage != null) {
11410                    if (tr.realActivity == null ||
11411                            !dumpPackage.equals(tr.realActivity)) {
11412                        continue;
11413                    }
11414                }
11415                if (!printedHeader) {
11416                    if (needSep) {
11417                        pw.println();
11418                    }
11419                    pw.println("  Recent tasks:");
11420                    printedHeader = true;
11421                    printedAnything = true;
11422                }
11423                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11424                        pw.println(tr);
11425                if (dumpAll) {
11426                    mRecentTasks.get(i).dump(pw, "    ");
11427                }
11428            }
11429        }
11430
11431        if (!printedAnything) {
11432            pw.println("  (nothing)");
11433        }
11434    }
11435
11436    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11437            int opti, boolean dumpAll, String dumpPackage) {
11438        boolean needSep = false;
11439        boolean printedAnything = false;
11440        int numPers = 0;
11441
11442        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11443
11444        if (dumpAll) {
11445            final int NP = mProcessNames.getMap().size();
11446            for (int ip=0; ip<NP; ip++) {
11447                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11448                final int NA = procs.size();
11449                for (int ia=0; ia<NA; ia++) {
11450                    ProcessRecord r = procs.valueAt(ia);
11451                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11452                        continue;
11453                    }
11454                    if (!needSep) {
11455                        pw.println("  All known processes:");
11456                        needSep = true;
11457                        printedAnything = true;
11458                    }
11459                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11460                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11461                        pw.print(" "); pw.println(r);
11462                    r.dump(pw, "    ");
11463                    if (r.persistent) {
11464                        numPers++;
11465                    }
11466                }
11467            }
11468        }
11469
11470        if (mIsolatedProcesses.size() > 0) {
11471            boolean printed = false;
11472            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11473                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11474                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11475                    continue;
11476                }
11477                if (!printed) {
11478                    if (needSep) {
11479                        pw.println();
11480                    }
11481                    pw.println("  Isolated process list (sorted by uid):");
11482                    printedAnything = true;
11483                    printed = true;
11484                    needSep = true;
11485                }
11486                pw.println(String.format("%sIsolated #%2d: %s",
11487                        "    ", i, r.toString()));
11488            }
11489        }
11490
11491        if (mLruProcesses.size() > 0) {
11492            if (needSep) {
11493                pw.println();
11494            }
11495            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11496                    pw.print(" total, non-act at ");
11497                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11498                    pw.print(", non-svc at ");
11499                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11500                    pw.println("):");
11501            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11502            needSep = true;
11503            printedAnything = true;
11504        }
11505
11506        if (dumpAll || dumpPackage != null) {
11507            synchronized (mPidsSelfLocked) {
11508                boolean printed = false;
11509                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11510                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11511                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11512                        continue;
11513                    }
11514                    if (!printed) {
11515                        if (needSep) pw.println();
11516                        needSep = true;
11517                        pw.println("  PID mappings:");
11518                        printed = true;
11519                        printedAnything = true;
11520                    }
11521                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11522                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11523                }
11524            }
11525        }
11526
11527        if (mForegroundProcesses.size() > 0) {
11528            synchronized (mPidsSelfLocked) {
11529                boolean printed = false;
11530                for (int i=0; i<mForegroundProcesses.size(); i++) {
11531                    ProcessRecord r = mPidsSelfLocked.get(
11532                            mForegroundProcesses.valueAt(i).pid);
11533                    if (dumpPackage != null && (r == null
11534                            || !r.pkgList.containsKey(dumpPackage))) {
11535                        continue;
11536                    }
11537                    if (!printed) {
11538                        if (needSep) pw.println();
11539                        needSep = true;
11540                        pw.println("  Foreground Processes:");
11541                        printed = true;
11542                        printedAnything = true;
11543                    }
11544                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11545                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11546                }
11547            }
11548        }
11549
11550        if (mPersistentStartingProcesses.size() > 0) {
11551            if (needSep) pw.println();
11552            needSep = true;
11553            printedAnything = true;
11554            pw.println("  Persisent processes that are starting:");
11555            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11556                    "Starting Norm", "Restarting PERS", dumpPackage);
11557        }
11558
11559        if (mRemovedProcesses.size() > 0) {
11560            if (needSep) pw.println();
11561            needSep = true;
11562            printedAnything = true;
11563            pw.println("  Processes that are being removed:");
11564            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11565                    "Removed Norm", "Removed PERS", dumpPackage);
11566        }
11567
11568        if (mProcessesOnHold.size() > 0) {
11569            if (needSep) pw.println();
11570            needSep = true;
11571            printedAnything = true;
11572            pw.println("  Processes that are on old until the system is ready:");
11573            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11574                    "OnHold Norm", "OnHold PERS", dumpPackage);
11575        }
11576
11577        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11578
11579        if (mProcessCrashTimes.getMap().size() > 0) {
11580            boolean printed = false;
11581            long now = SystemClock.uptimeMillis();
11582            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11583            final int NP = pmap.size();
11584            for (int ip=0; ip<NP; ip++) {
11585                String pname = pmap.keyAt(ip);
11586                SparseArray<Long> uids = pmap.valueAt(ip);
11587                final int N = uids.size();
11588                for (int i=0; i<N; i++) {
11589                    int puid = uids.keyAt(i);
11590                    ProcessRecord r = mProcessNames.get(pname, puid);
11591                    if (dumpPackage != null && (r == null
11592                            || !r.pkgList.containsKey(dumpPackage))) {
11593                        continue;
11594                    }
11595                    if (!printed) {
11596                        if (needSep) pw.println();
11597                        needSep = true;
11598                        pw.println("  Time since processes crashed:");
11599                        printed = true;
11600                        printedAnything = true;
11601                    }
11602                    pw.print("    Process "); pw.print(pname);
11603                            pw.print(" uid "); pw.print(puid);
11604                            pw.print(": last crashed ");
11605                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11606                            pw.println(" ago");
11607                }
11608            }
11609        }
11610
11611        if (mBadProcesses.getMap().size() > 0) {
11612            boolean printed = false;
11613            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11614            final int NP = pmap.size();
11615            for (int ip=0; ip<NP; ip++) {
11616                String pname = pmap.keyAt(ip);
11617                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11618                final int N = uids.size();
11619                for (int i=0; i<N; i++) {
11620                    int puid = uids.keyAt(i);
11621                    ProcessRecord r = mProcessNames.get(pname, puid);
11622                    if (dumpPackage != null && (r == null
11623                            || !r.pkgList.containsKey(dumpPackage))) {
11624                        continue;
11625                    }
11626                    if (!printed) {
11627                        if (needSep) pw.println();
11628                        needSep = true;
11629                        pw.println("  Bad processes:");
11630                        printedAnything = true;
11631                    }
11632                    BadProcessInfo info = uids.valueAt(i);
11633                    pw.print("    Bad process "); pw.print(pname);
11634                            pw.print(" uid "); pw.print(puid);
11635                            pw.print(": crashed at time "); pw.println(info.time);
11636                    if (info.shortMsg != null) {
11637                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11638                    }
11639                    if (info.longMsg != null) {
11640                        pw.print("      Long msg: "); pw.println(info.longMsg);
11641                    }
11642                    if (info.stack != null) {
11643                        pw.println("      Stack:");
11644                        int lastPos = 0;
11645                        for (int pos=0; pos<info.stack.length(); pos++) {
11646                            if (info.stack.charAt(pos) == '\n') {
11647                                pw.print("        ");
11648                                pw.write(info.stack, lastPos, pos-lastPos);
11649                                pw.println();
11650                                lastPos = pos+1;
11651                            }
11652                        }
11653                        if (lastPos < info.stack.length()) {
11654                            pw.print("        ");
11655                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11656                            pw.println();
11657                        }
11658                    }
11659                }
11660            }
11661        }
11662
11663        if (dumpPackage == null) {
11664            pw.println();
11665            needSep = false;
11666            pw.println("  mStartedUsers:");
11667            for (int i=0; i<mStartedUsers.size(); i++) {
11668                UserStartedState uss = mStartedUsers.valueAt(i);
11669                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11670                        pw.print(": "); uss.dump("", pw);
11671            }
11672            pw.print("  mStartedUserArray: [");
11673            for (int i=0; i<mStartedUserArray.length; i++) {
11674                if (i > 0) pw.print(", ");
11675                pw.print(mStartedUserArray[i]);
11676            }
11677            pw.println("]");
11678            pw.print("  mUserLru: [");
11679            for (int i=0; i<mUserLru.size(); i++) {
11680                if (i > 0) pw.print(", ");
11681                pw.print(mUserLru.get(i));
11682            }
11683            pw.println("]");
11684            if (dumpAll) {
11685                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11686            }
11687            synchronized (mUserProfileGroupIdsSelfLocked) {
11688                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
11689                    pw.println("  mUserProfileGroupIds:");
11690                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
11691                        pw.print("    User #");
11692                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
11693                        pw.print(" -> profile #");
11694                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
11695                    }
11696                }
11697            }
11698        }
11699        if (mHomeProcess != null && (dumpPackage == null
11700                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11701            if (needSep) {
11702                pw.println();
11703                needSep = false;
11704            }
11705            pw.println("  mHomeProcess: " + mHomeProcess);
11706        }
11707        if (mPreviousProcess != null && (dumpPackage == null
11708                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11709            if (needSep) {
11710                pw.println();
11711                needSep = false;
11712            }
11713            pw.println("  mPreviousProcess: " + mPreviousProcess);
11714        }
11715        if (dumpAll) {
11716            StringBuilder sb = new StringBuilder(128);
11717            sb.append("  mPreviousProcessVisibleTime: ");
11718            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11719            pw.println(sb);
11720        }
11721        if (mHeavyWeightProcess != null && (dumpPackage == null
11722                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11723            if (needSep) {
11724                pw.println();
11725                needSep = false;
11726            }
11727            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11728        }
11729        if (dumpPackage == null) {
11730            pw.println("  mConfiguration: " + mConfiguration);
11731        }
11732        if (dumpAll) {
11733            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11734            if (mCompatModePackages.getPackages().size() > 0) {
11735                boolean printed = false;
11736                for (Map.Entry<String, Integer> entry
11737                        : mCompatModePackages.getPackages().entrySet()) {
11738                    String pkg = entry.getKey();
11739                    int mode = entry.getValue();
11740                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11741                        continue;
11742                    }
11743                    if (!printed) {
11744                        pw.println("  mScreenCompatPackages:");
11745                        printed = true;
11746                    }
11747                    pw.print("    "); pw.print(pkg); pw.print(": ");
11748                            pw.print(mode); pw.println();
11749                }
11750            }
11751        }
11752        if (dumpPackage == null) {
11753            if (mSleeping || mWentToSleep || mLockScreenShown) {
11754                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11755                        + " mLockScreenShown " + mLockScreenShown);
11756            }
11757            if (mShuttingDown || mRunningVoice) {
11758                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11759            }
11760        }
11761        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11762                || mOrigWaitForDebugger) {
11763            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11764                    || dumpPackage.equals(mOrigDebugApp)) {
11765                if (needSep) {
11766                    pw.println();
11767                    needSep = false;
11768                }
11769                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11770                        + " mDebugTransient=" + mDebugTransient
11771                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11772            }
11773        }
11774        if (mOpenGlTraceApp != null) {
11775            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11776                if (needSep) {
11777                    pw.println();
11778                    needSep = false;
11779                }
11780                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11781            }
11782        }
11783        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11784                || mProfileFd != null) {
11785            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11786                if (needSep) {
11787                    pw.println();
11788                    needSep = false;
11789                }
11790                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11791                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11792                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11793                        + mAutoStopProfiler);
11794            }
11795        }
11796        if (dumpPackage == null) {
11797            if (mAlwaysFinishActivities || mController != null) {
11798                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11799                        + " mController=" + mController);
11800            }
11801            if (dumpAll) {
11802                pw.println("  Total persistent processes: " + numPers);
11803                pw.println("  mProcessesReady=" + mProcessesReady
11804                        + " mSystemReady=" + mSystemReady);
11805                pw.println("  mBooting=" + mBooting
11806                        + " mBooted=" + mBooted
11807                        + " mFactoryTest=" + mFactoryTest);
11808                pw.print("  mLastPowerCheckRealtime=");
11809                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11810                        pw.println("");
11811                pw.print("  mLastPowerCheckUptime=");
11812                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11813                        pw.println("");
11814                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11815                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11816                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11817                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11818                        + " (" + mLruProcesses.size() + " total)"
11819                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11820                        + " mNumServiceProcs=" + mNumServiceProcs
11821                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11822                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11823                        + " mLastMemoryLevel" + mLastMemoryLevel
11824                        + " mLastNumProcesses" + mLastNumProcesses);
11825                long now = SystemClock.uptimeMillis();
11826                pw.print("  mLastIdleTime=");
11827                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11828                        pw.print(" mLowRamSinceLastIdle=");
11829                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11830                        pw.println();
11831            }
11832        }
11833
11834        if (!printedAnything) {
11835            pw.println("  (nothing)");
11836        }
11837    }
11838
11839    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11840            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11841        if (mProcessesToGc.size() > 0) {
11842            boolean printed = false;
11843            long now = SystemClock.uptimeMillis();
11844            for (int i=0; i<mProcessesToGc.size(); i++) {
11845                ProcessRecord proc = mProcessesToGc.get(i);
11846                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11847                    continue;
11848                }
11849                if (!printed) {
11850                    if (needSep) pw.println();
11851                    needSep = true;
11852                    pw.println("  Processes that are waiting to GC:");
11853                    printed = true;
11854                }
11855                pw.print("    Process "); pw.println(proc);
11856                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11857                        pw.print(", last gced=");
11858                        pw.print(now-proc.lastRequestedGc);
11859                        pw.print(" ms ago, last lowMem=");
11860                        pw.print(now-proc.lastLowMemory);
11861                        pw.println(" ms ago");
11862
11863            }
11864        }
11865        return needSep;
11866    }
11867
11868    void printOomLevel(PrintWriter pw, String name, int adj) {
11869        pw.print("    ");
11870        if (adj >= 0) {
11871            pw.print(' ');
11872            if (adj < 10) pw.print(' ');
11873        } else {
11874            if (adj > -10) pw.print(' ');
11875        }
11876        pw.print(adj);
11877        pw.print(": ");
11878        pw.print(name);
11879        pw.print(" (");
11880        pw.print(mProcessList.getMemLevel(adj)/1024);
11881        pw.println(" kB)");
11882    }
11883
11884    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11885            int opti, boolean dumpAll) {
11886        boolean needSep = false;
11887
11888        if (mLruProcesses.size() > 0) {
11889            if (needSep) pw.println();
11890            needSep = true;
11891            pw.println("  OOM levels:");
11892            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11893            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11894            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11895            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11896            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11897            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11898            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11899            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11900            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11901            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11902            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11903            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11904            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11905
11906            if (needSep) pw.println();
11907            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11908                    pw.print(" total, non-act at ");
11909                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11910                    pw.print(", non-svc at ");
11911                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11912                    pw.println("):");
11913            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11914            needSep = true;
11915        }
11916
11917        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11918
11919        pw.println();
11920        pw.println("  mHomeProcess: " + mHomeProcess);
11921        pw.println("  mPreviousProcess: " + mPreviousProcess);
11922        if (mHeavyWeightProcess != null) {
11923            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11924        }
11925
11926        return true;
11927    }
11928
11929    /**
11930     * There are three ways to call this:
11931     *  - no provider specified: dump all the providers
11932     *  - a flattened component name that matched an existing provider was specified as the
11933     *    first arg: dump that one provider
11934     *  - the first arg isn't the flattened component name of an existing provider:
11935     *    dump all providers whose component contains the first arg as a substring
11936     */
11937    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11938            int opti, boolean dumpAll) {
11939        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11940    }
11941
11942    static class ItemMatcher {
11943        ArrayList<ComponentName> components;
11944        ArrayList<String> strings;
11945        ArrayList<Integer> objects;
11946        boolean all;
11947
11948        ItemMatcher() {
11949            all = true;
11950        }
11951
11952        void build(String name) {
11953            ComponentName componentName = ComponentName.unflattenFromString(name);
11954            if (componentName != null) {
11955                if (components == null) {
11956                    components = new ArrayList<ComponentName>();
11957                }
11958                components.add(componentName);
11959                all = false;
11960            } else {
11961                int objectId = 0;
11962                // Not a '/' separated full component name; maybe an object ID?
11963                try {
11964                    objectId = Integer.parseInt(name, 16);
11965                    if (objects == null) {
11966                        objects = new ArrayList<Integer>();
11967                    }
11968                    objects.add(objectId);
11969                    all = false;
11970                } catch (RuntimeException e) {
11971                    // Not an integer; just do string match.
11972                    if (strings == null) {
11973                        strings = new ArrayList<String>();
11974                    }
11975                    strings.add(name);
11976                    all = false;
11977                }
11978            }
11979        }
11980
11981        int build(String[] args, int opti) {
11982            for (; opti<args.length; opti++) {
11983                String name = args[opti];
11984                if ("--".equals(name)) {
11985                    return opti+1;
11986                }
11987                build(name);
11988            }
11989            return opti;
11990        }
11991
11992        boolean match(Object object, ComponentName comp) {
11993            if (all) {
11994                return true;
11995            }
11996            if (components != null) {
11997                for (int i=0; i<components.size(); i++) {
11998                    if (components.get(i).equals(comp)) {
11999                        return true;
12000                    }
12001                }
12002            }
12003            if (objects != null) {
12004                for (int i=0; i<objects.size(); i++) {
12005                    if (System.identityHashCode(object) == objects.get(i)) {
12006                        return true;
12007                    }
12008                }
12009            }
12010            if (strings != null) {
12011                String flat = comp.flattenToString();
12012                for (int i=0; i<strings.size(); i++) {
12013                    if (flat.contains(strings.get(i))) {
12014                        return true;
12015                    }
12016                }
12017            }
12018            return false;
12019        }
12020    }
12021
12022    /**
12023     * There are three things that cmd can be:
12024     *  - a flattened component name that matches an existing activity
12025     *  - the cmd arg isn't the flattened component name of an existing activity:
12026     *    dump all activity whose component contains the cmd as a substring
12027     *  - A hex number of the ActivityRecord object instance.
12028     */
12029    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12030            int opti, boolean dumpAll) {
12031        ArrayList<ActivityRecord> activities;
12032
12033        synchronized (this) {
12034            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12035        }
12036
12037        if (activities.size() <= 0) {
12038            return false;
12039        }
12040
12041        String[] newArgs = new String[args.length - opti];
12042        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12043
12044        TaskRecord lastTask = null;
12045        boolean needSep = false;
12046        for (int i=activities.size()-1; i>=0; i--) {
12047            ActivityRecord r = activities.get(i);
12048            if (needSep) {
12049                pw.println();
12050            }
12051            needSep = true;
12052            synchronized (this) {
12053                if (lastTask != r.task) {
12054                    lastTask = r.task;
12055                    pw.print("TASK "); pw.print(lastTask.affinity);
12056                            pw.print(" id="); pw.println(lastTask.taskId);
12057                    if (dumpAll) {
12058                        lastTask.dump(pw, "  ");
12059                    }
12060                }
12061            }
12062            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12063        }
12064        return true;
12065    }
12066
12067    /**
12068     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12069     * there is a thread associated with the activity.
12070     */
12071    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12072            final ActivityRecord r, String[] args, boolean dumpAll) {
12073        String innerPrefix = prefix + "  ";
12074        synchronized (this) {
12075            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12076                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12077                    pw.print(" pid=");
12078                    if (r.app != null) pw.println(r.app.pid);
12079                    else pw.println("(not running)");
12080            if (dumpAll) {
12081                r.dump(pw, innerPrefix);
12082            }
12083        }
12084        if (r.app != null && r.app.thread != null) {
12085            // flush anything that is already in the PrintWriter since the thread is going
12086            // to write to the file descriptor directly
12087            pw.flush();
12088            try {
12089                TransferPipe tp = new TransferPipe();
12090                try {
12091                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12092                            r.appToken, innerPrefix, args);
12093                    tp.go(fd);
12094                } finally {
12095                    tp.kill();
12096                }
12097            } catch (IOException e) {
12098                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12099            } catch (RemoteException e) {
12100                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12101            }
12102        }
12103    }
12104
12105    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12106            int opti, boolean dumpAll, String dumpPackage) {
12107        boolean needSep = false;
12108        boolean onlyHistory = false;
12109        boolean printedAnything = false;
12110
12111        if ("history".equals(dumpPackage)) {
12112            if (opti < args.length && "-s".equals(args[opti])) {
12113                dumpAll = false;
12114            }
12115            onlyHistory = true;
12116            dumpPackage = null;
12117        }
12118
12119        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12120        if (!onlyHistory && dumpAll) {
12121            if (mRegisteredReceivers.size() > 0) {
12122                boolean printed = false;
12123                Iterator it = mRegisteredReceivers.values().iterator();
12124                while (it.hasNext()) {
12125                    ReceiverList r = (ReceiverList)it.next();
12126                    if (dumpPackage != null && (r.app == null ||
12127                            !dumpPackage.equals(r.app.info.packageName))) {
12128                        continue;
12129                    }
12130                    if (!printed) {
12131                        pw.println("  Registered Receivers:");
12132                        needSep = true;
12133                        printed = true;
12134                        printedAnything = true;
12135                    }
12136                    pw.print("  * "); pw.println(r);
12137                    r.dump(pw, "    ");
12138                }
12139            }
12140
12141            if (mReceiverResolver.dump(pw, needSep ?
12142                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12143                    "    ", dumpPackage, false)) {
12144                needSep = true;
12145                printedAnything = true;
12146            }
12147        }
12148
12149        for (BroadcastQueue q : mBroadcastQueues) {
12150            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12151            printedAnything |= needSep;
12152        }
12153
12154        needSep = true;
12155
12156        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12157            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12158                if (needSep) {
12159                    pw.println();
12160                }
12161                needSep = true;
12162                printedAnything = true;
12163                pw.print("  Sticky broadcasts for user ");
12164                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12165                StringBuilder sb = new StringBuilder(128);
12166                for (Map.Entry<String, ArrayList<Intent>> ent
12167                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12168                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12169                    if (dumpAll) {
12170                        pw.println(":");
12171                        ArrayList<Intent> intents = ent.getValue();
12172                        final int N = intents.size();
12173                        for (int i=0; i<N; i++) {
12174                            sb.setLength(0);
12175                            sb.append("    Intent: ");
12176                            intents.get(i).toShortString(sb, false, true, false, false);
12177                            pw.println(sb.toString());
12178                            Bundle bundle = intents.get(i).getExtras();
12179                            if (bundle != null) {
12180                                pw.print("      ");
12181                                pw.println(bundle.toString());
12182                            }
12183                        }
12184                    } else {
12185                        pw.println("");
12186                    }
12187                }
12188            }
12189        }
12190
12191        if (!onlyHistory && dumpAll) {
12192            pw.println();
12193            for (BroadcastQueue queue : mBroadcastQueues) {
12194                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12195                        + queue.mBroadcastsScheduled);
12196            }
12197            pw.println("  mHandler:");
12198            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12199            needSep = true;
12200            printedAnything = true;
12201        }
12202
12203        if (!printedAnything) {
12204            pw.println("  (nothing)");
12205        }
12206    }
12207
12208    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12209            int opti, boolean dumpAll, String dumpPackage) {
12210        boolean needSep;
12211        boolean printedAnything = false;
12212
12213        ItemMatcher matcher = new ItemMatcher();
12214        matcher.build(args, opti);
12215
12216        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12217
12218        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12219        printedAnything |= needSep;
12220
12221        if (mLaunchingProviders.size() > 0) {
12222            boolean printed = false;
12223            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12224                ContentProviderRecord r = mLaunchingProviders.get(i);
12225                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12226                    continue;
12227                }
12228                if (!printed) {
12229                    if (needSep) pw.println();
12230                    needSep = true;
12231                    pw.println("  Launching content providers:");
12232                    printed = true;
12233                    printedAnything = true;
12234                }
12235                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12236                        pw.println(r);
12237            }
12238        }
12239
12240        if (mGrantedUriPermissions.size() > 0) {
12241            boolean printed = false;
12242            int dumpUid = -2;
12243            if (dumpPackage != null) {
12244                try {
12245                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12246                } catch (NameNotFoundException e) {
12247                    dumpUid = -1;
12248                }
12249            }
12250            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12251                int uid = mGrantedUriPermissions.keyAt(i);
12252                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12253                    continue;
12254                }
12255                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12256                if (!printed) {
12257                    if (needSep) pw.println();
12258                    needSep = true;
12259                    pw.println("  Granted Uri Permissions:");
12260                    printed = true;
12261                    printedAnything = true;
12262                }
12263                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12264                for (UriPermission perm : perms.values()) {
12265                    pw.print("    "); pw.println(perm);
12266                    if (dumpAll) {
12267                        perm.dump(pw, "      ");
12268                    }
12269                }
12270            }
12271        }
12272
12273        if (!printedAnything) {
12274            pw.println("  (nothing)");
12275        }
12276    }
12277
12278    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12279            int opti, boolean dumpAll, String dumpPackage) {
12280        boolean printed = false;
12281
12282        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12283
12284        if (mIntentSenderRecords.size() > 0) {
12285            Iterator<WeakReference<PendingIntentRecord>> it
12286                    = mIntentSenderRecords.values().iterator();
12287            while (it.hasNext()) {
12288                WeakReference<PendingIntentRecord> ref = it.next();
12289                PendingIntentRecord rec = ref != null ? ref.get(): null;
12290                if (dumpPackage != null && (rec == null
12291                        || !dumpPackage.equals(rec.key.packageName))) {
12292                    continue;
12293                }
12294                printed = true;
12295                if (rec != null) {
12296                    pw.print("  * "); pw.println(rec);
12297                    if (dumpAll) {
12298                        rec.dump(pw, "    ");
12299                    }
12300                } else {
12301                    pw.print("  * "); pw.println(ref);
12302                }
12303            }
12304        }
12305
12306        if (!printed) {
12307            pw.println("  (nothing)");
12308        }
12309    }
12310
12311    private static final int dumpProcessList(PrintWriter pw,
12312            ActivityManagerService service, List list,
12313            String prefix, String normalLabel, String persistentLabel,
12314            String dumpPackage) {
12315        int numPers = 0;
12316        final int N = list.size()-1;
12317        for (int i=N; i>=0; i--) {
12318            ProcessRecord r = (ProcessRecord)list.get(i);
12319            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12320                continue;
12321            }
12322            pw.println(String.format("%s%s #%2d: %s",
12323                    prefix, (r.persistent ? persistentLabel : normalLabel),
12324                    i, r.toString()));
12325            if (r.persistent) {
12326                numPers++;
12327            }
12328        }
12329        return numPers;
12330    }
12331
12332    private static final boolean dumpProcessOomList(PrintWriter pw,
12333            ActivityManagerService service, List<ProcessRecord> origList,
12334            String prefix, String normalLabel, String persistentLabel,
12335            boolean inclDetails, String dumpPackage) {
12336
12337        ArrayList<Pair<ProcessRecord, Integer>> list
12338                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12339        for (int i=0; i<origList.size(); i++) {
12340            ProcessRecord r = origList.get(i);
12341            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12342                continue;
12343            }
12344            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12345        }
12346
12347        if (list.size() <= 0) {
12348            return false;
12349        }
12350
12351        Comparator<Pair<ProcessRecord, Integer>> comparator
12352                = new Comparator<Pair<ProcessRecord, Integer>>() {
12353            @Override
12354            public int compare(Pair<ProcessRecord, Integer> object1,
12355                    Pair<ProcessRecord, Integer> object2) {
12356                if (object1.first.setAdj != object2.first.setAdj) {
12357                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12358                }
12359                if (object1.second.intValue() != object2.second.intValue()) {
12360                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12361                }
12362                return 0;
12363            }
12364        };
12365
12366        Collections.sort(list, comparator);
12367
12368        final long curRealtime = SystemClock.elapsedRealtime();
12369        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12370        final long curUptime = SystemClock.uptimeMillis();
12371        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12372
12373        for (int i=list.size()-1; i>=0; i--) {
12374            ProcessRecord r = list.get(i).first;
12375            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12376            char schedGroup;
12377            switch (r.setSchedGroup) {
12378                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12379                    schedGroup = 'B';
12380                    break;
12381                case Process.THREAD_GROUP_DEFAULT:
12382                    schedGroup = 'F';
12383                    break;
12384                default:
12385                    schedGroup = '?';
12386                    break;
12387            }
12388            char foreground;
12389            if (r.foregroundActivities) {
12390                foreground = 'A';
12391            } else if (r.foregroundServices) {
12392                foreground = 'S';
12393            } else {
12394                foreground = ' ';
12395            }
12396            String procState = ProcessList.makeProcStateString(r.curProcState);
12397            pw.print(prefix);
12398            pw.print(r.persistent ? persistentLabel : normalLabel);
12399            pw.print(" #");
12400            int num = (origList.size()-1)-list.get(i).second;
12401            if (num < 10) pw.print(' ');
12402            pw.print(num);
12403            pw.print(": ");
12404            pw.print(oomAdj);
12405            pw.print(' ');
12406            pw.print(schedGroup);
12407            pw.print('/');
12408            pw.print(foreground);
12409            pw.print('/');
12410            pw.print(procState);
12411            pw.print(" trm:");
12412            if (r.trimMemoryLevel < 10) pw.print(' ');
12413            pw.print(r.trimMemoryLevel);
12414            pw.print(' ');
12415            pw.print(r.toShortString());
12416            pw.print(" (");
12417            pw.print(r.adjType);
12418            pw.println(')');
12419            if (r.adjSource != null || r.adjTarget != null) {
12420                pw.print(prefix);
12421                pw.print("    ");
12422                if (r.adjTarget instanceof ComponentName) {
12423                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12424                } else if (r.adjTarget != null) {
12425                    pw.print(r.adjTarget.toString());
12426                } else {
12427                    pw.print("{null}");
12428                }
12429                pw.print("<=");
12430                if (r.adjSource instanceof ProcessRecord) {
12431                    pw.print("Proc{");
12432                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12433                    pw.println("}");
12434                } else if (r.adjSource != null) {
12435                    pw.println(r.adjSource.toString());
12436                } else {
12437                    pw.println("{null}");
12438                }
12439            }
12440            if (inclDetails) {
12441                pw.print(prefix);
12442                pw.print("    ");
12443                pw.print("oom: max="); pw.print(r.maxAdj);
12444                pw.print(" curRaw="); pw.print(r.curRawAdj);
12445                pw.print(" setRaw="); pw.print(r.setRawAdj);
12446                pw.print(" cur="); pw.print(r.curAdj);
12447                pw.print(" set="); pw.println(r.setAdj);
12448                pw.print(prefix);
12449                pw.print("    ");
12450                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12451                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12452                pw.print(" lastPss="); pw.print(r.lastPss);
12453                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12454                pw.print(prefix);
12455                pw.print("    ");
12456                pw.print("cached="); pw.print(r.cached);
12457                pw.print(" empty="); pw.print(r.empty);
12458                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12459
12460                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
12461                    if (r.lastWakeTime != 0) {
12462                        long wtime;
12463                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12464                        synchronized (stats) {
12465                            wtime = stats.getProcessWakeTime(r.info.uid,
12466                                    r.pid, curRealtime);
12467                        }
12468                        long timeUsed = wtime - r.lastWakeTime;
12469                        pw.print(prefix);
12470                        pw.print("    ");
12471                        pw.print("keep awake over ");
12472                        TimeUtils.formatDuration(realtimeSince, pw);
12473                        pw.print(" used ");
12474                        TimeUtils.formatDuration(timeUsed, pw);
12475                        pw.print(" (");
12476                        pw.print((timeUsed*100)/realtimeSince);
12477                        pw.println("%)");
12478                    }
12479                    if (r.lastCpuTime != 0) {
12480                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12481                        pw.print(prefix);
12482                        pw.print("    ");
12483                        pw.print("run cpu over ");
12484                        TimeUtils.formatDuration(uptimeSince, pw);
12485                        pw.print(" used ");
12486                        TimeUtils.formatDuration(timeUsed, pw);
12487                        pw.print(" (");
12488                        pw.print((timeUsed*100)/uptimeSince);
12489                        pw.println("%)");
12490                    }
12491                }
12492            }
12493        }
12494        return true;
12495    }
12496
12497    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12498        ArrayList<ProcessRecord> procs;
12499        synchronized (this) {
12500            if (args != null && args.length > start
12501                    && args[start].charAt(0) != '-') {
12502                procs = new ArrayList<ProcessRecord>();
12503                int pid = -1;
12504                try {
12505                    pid = Integer.parseInt(args[start]);
12506                } catch (NumberFormatException e) {
12507                }
12508                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12509                    ProcessRecord proc = mLruProcesses.get(i);
12510                    if (proc.pid == pid) {
12511                        procs.add(proc);
12512                    } else if (proc.processName.equals(args[start])) {
12513                        procs.add(proc);
12514                    }
12515                }
12516                if (procs.size() <= 0) {
12517                    return null;
12518                }
12519            } else {
12520                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12521            }
12522        }
12523        return procs;
12524    }
12525
12526    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12527            PrintWriter pw, String[] args) {
12528        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12529        if (procs == null) {
12530            pw.println("No process found for: " + args[0]);
12531            return;
12532        }
12533
12534        long uptime = SystemClock.uptimeMillis();
12535        long realtime = SystemClock.elapsedRealtime();
12536        pw.println("Applications Graphics Acceleration Info:");
12537        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12538
12539        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12540            ProcessRecord r = procs.get(i);
12541            if (r.thread != null) {
12542                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12543                pw.flush();
12544                try {
12545                    TransferPipe tp = new TransferPipe();
12546                    try {
12547                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12548                        tp.go(fd);
12549                    } finally {
12550                        tp.kill();
12551                    }
12552                } catch (IOException e) {
12553                    pw.println("Failure while dumping the app: " + r);
12554                    pw.flush();
12555                } catch (RemoteException e) {
12556                    pw.println("Got a RemoteException while dumping the app " + r);
12557                    pw.flush();
12558                }
12559            }
12560        }
12561    }
12562
12563    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12564        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12565        if (procs == null) {
12566            pw.println("No process found for: " + args[0]);
12567            return;
12568        }
12569
12570        pw.println("Applications Database Info:");
12571
12572        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12573            ProcessRecord r = procs.get(i);
12574            if (r.thread != null) {
12575                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12576                pw.flush();
12577                try {
12578                    TransferPipe tp = new TransferPipe();
12579                    try {
12580                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12581                        tp.go(fd);
12582                    } finally {
12583                        tp.kill();
12584                    }
12585                } catch (IOException e) {
12586                    pw.println("Failure while dumping the app: " + r);
12587                    pw.flush();
12588                } catch (RemoteException e) {
12589                    pw.println("Got a RemoteException while dumping the app " + r);
12590                    pw.flush();
12591                }
12592            }
12593        }
12594    }
12595
12596    final static class MemItem {
12597        final boolean isProc;
12598        final String label;
12599        final String shortLabel;
12600        final long pss;
12601        final int id;
12602        final boolean hasActivities;
12603        ArrayList<MemItem> subitems;
12604
12605        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12606                boolean _hasActivities) {
12607            isProc = true;
12608            label = _label;
12609            shortLabel = _shortLabel;
12610            pss = _pss;
12611            id = _id;
12612            hasActivities = _hasActivities;
12613        }
12614
12615        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12616            isProc = false;
12617            label = _label;
12618            shortLabel = _shortLabel;
12619            pss = _pss;
12620            id = _id;
12621            hasActivities = false;
12622        }
12623    }
12624
12625    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12626            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12627        if (sort && !isCompact) {
12628            Collections.sort(items, new Comparator<MemItem>() {
12629                @Override
12630                public int compare(MemItem lhs, MemItem rhs) {
12631                    if (lhs.pss < rhs.pss) {
12632                        return 1;
12633                    } else if (lhs.pss > rhs.pss) {
12634                        return -1;
12635                    }
12636                    return 0;
12637                }
12638            });
12639        }
12640
12641        for (int i=0; i<items.size(); i++) {
12642            MemItem mi = items.get(i);
12643            if (!isCompact) {
12644                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12645            } else if (mi.isProc) {
12646                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12647                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12648                pw.println(mi.hasActivities ? ",a" : ",e");
12649            } else {
12650                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12651                pw.println(mi.pss);
12652            }
12653            if (mi.subitems != null) {
12654                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12655                        true, isCompact);
12656            }
12657        }
12658    }
12659
12660    // These are in KB.
12661    static final long[] DUMP_MEM_BUCKETS = new long[] {
12662        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12663        120*1024, 160*1024, 200*1024,
12664        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12665        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12666    };
12667
12668    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12669            boolean stackLike) {
12670        int start = label.lastIndexOf('.');
12671        if (start >= 0) start++;
12672        else start = 0;
12673        int end = label.length();
12674        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12675            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12676                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12677                out.append(bucket);
12678                out.append(stackLike ? "MB." : "MB ");
12679                out.append(label, start, end);
12680                return;
12681            }
12682        }
12683        out.append(memKB/1024);
12684        out.append(stackLike ? "MB." : "MB ");
12685        out.append(label, start, end);
12686    }
12687
12688    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12689            ProcessList.NATIVE_ADJ,
12690            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12691            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12692            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12693            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12694            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12695    };
12696    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12697            "Native",
12698            "System", "Persistent", "Foreground",
12699            "Visible", "Perceptible",
12700            "Heavy Weight", "Backup",
12701            "A Services", "Home",
12702            "Previous", "B Services", "Cached"
12703    };
12704    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12705            "native",
12706            "sys", "pers", "fore",
12707            "vis", "percept",
12708            "heavy", "backup",
12709            "servicea", "home",
12710            "prev", "serviceb", "cached"
12711    };
12712
12713    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12714            long realtime, boolean isCheckinRequest, boolean isCompact) {
12715        if (isCheckinRequest || isCompact) {
12716            // short checkin version
12717            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12718        } else {
12719            pw.println("Applications Memory Usage (kB):");
12720            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12721        }
12722    }
12723
12724    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12725            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12726        boolean dumpDetails = false;
12727        boolean dumpFullDetails = false;
12728        boolean dumpDalvik = false;
12729        boolean oomOnly = false;
12730        boolean isCompact = false;
12731        boolean localOnly = false;
12732
12733        int opti = 0;
12734        while (opti < args.length) {
12735            String opt = args[opti];
12736            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12737                break;
12738            }
12739            opti++;
12740            if ("-a".equals(opt)) {
12741                dumpDetails = true;
12742                dumpFullDetails = true;
12743                dumpDalvik = true;
12744            } else if ("-d".equals(opt)) {
12745                dumpDalvik = true;
12746            } else if ("-c".equals(opt)) {
12747                isCompact = true;
12748            } else if ("--oom".equals(opt)) {
12749                oomOnly = true;
12750            } else if ("--local".equals(opt)) {
12751                localOnly = true;
12752            } else if ("-h".equals(opt)) {
12753                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12754                pw.println("  -a: include all available information for each process.");
12755                pw.println("  -d: include dalvik details when dumping process details.");
12756                pw.println("  -c: dump in a compact machine-parseable representation.");
12757                pw.println("  --oom: only show processes organized by oom adj.");
12758                pw.println("  --local: only collect details locally, don't call process.");
12759                pw.println("If [process] is specified it can be the name or ");
12760                pw.println("pid of a specific process to dump.");
12761                return;
12762            } else {
12763                pw.println("Unknown argument: " + opt + "; use -h for help");
12764            }
12765        }
12766
12767        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12768        long uptime = SystemClock.uptimeMillis();
12769        long realtime = SystemClock.elapsedRealtime();
12770        final long[] tmpLong = new long[1];
12771
12772        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12773        if (procs == null) {
12774            // No Java processes.  Maybe they want to print a native process.
12775            if (args != null && args.length > opti
12776                    && args[opti].charAt(0) != '-') {
12777                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12778                        = new ArrayList<ProcessCpuTracker.Stats>();
12779                updateCpuStatsNow();
12780                int findPid = -1;
12781                try {
12782                    findPid = Integer.parseInt(args[opti]);
12783                } catch (NumberFormatException e) {
12784                }
12785                synchronized (mProcessCpuThread) {
12786                    final int N = mProcessCpuTracker.countStats();
12787                    for (int i=0; i<N; i++) {
12788                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12789                        if (st.pid == findPid || (st.baseName != null
12790                                && st.baseName.equals(args[opti]))) {
12791                            nativeProcs.add(st);
12792                        }
12793                    }
12794                }
12795                if (nativeProcs.size() > 0) {
12796                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12797                            isCompact);
12798                    Debug.MemoryInfo mi = null;
12799                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12800                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12801                        final int pid = r.pid;
12802                        if (!isCheckinRequest && dumpDetails) {
12803                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12804                        }
12805                        if (mi == null) {
12806                            mi = new Debug.MemoryInfo();
12807                        }
12808                        if (dumpDetails || (!brief && !oomOnly)) {
12809                            Debug.getMemoryInfo(pid, mi);
12810                        } else {
12811                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12812                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12813                        }
12814                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12815                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12816                        if (isCheckinRequest) {
12817                            pw.println();
12818                        }
12819                    }
12820                    return;
12821                }
12822            }
12823            pw.println("No process found for: " + args[opti]);
12824            return;
12825        }
12826
12827        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12828            dumpDetails = true;
12829        }
12830
12831        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12832
12833        String[] innerArgs = new String[args.length-opti];
12834        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12835
12836        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12837        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12838        long nativePss=0, dalvikPss=0, otherPss=0;
12839        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12840
12841        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12842        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12843                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12844
12845        long totalPss = 0;
12846        long cachedPss = 0;
12847
12848        Debug.MemoryInfo mi = null;
12849        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12850            final ProcessRecord r = procs.get(i);
12851            final IApplicationThread thread;
12852            final int pid;
12853            final int oomAdj;
12854            final boolean hasActivities;
12855            synchronized (this) {
12856                thread = r.thread;
12857                pid = r.pid;
12858                oomAdj = r.getSetAdjWithServices();
12859                hasActivities = r.activities.size() > 0;
12860            }
12861            if (thread != null) {
12862                if (!isCheckinRequest && dumpDetails) {
12863                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12864                }
12865                if (mi == null) {
12866                    mi = new Debug.MemoryInfo();
12867                }
12868                if (dumpDetails || (!brief && !oomOnly)) {
12869                    Debug.getMemoryInfo(pid, mi);
12870                } else {
12871                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12872                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12873                }
12874                if (dumpDetails) {
12875                    if (localOnly) {
12876                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12877                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12878                        if (isCheckinRequest) {
12879                            pw.println();
12880                        }
12881                    } else {
12882                        try {
12883                            pw.flush();
12884                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12885                                    dumpDalvik, innerArgs);
12886                        } catch (RemoteException e) {
12887                            if (!isCheckinRequest) {
12888                                pw.println("Got RemoteException!");
12889                                pw.flush();
12890                            }
12891                        }
12892                    }
12893                }
12894
12895                final long myTotalPss = mi.getTotalPss();
12896                final long myTotalUss = mi.getTotalUss();
12897
12898                synchronized (this) {
12899                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12900                        // Record this for posterity if the process has been stable.
12901                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12902                    }
12903                }
12904
12905                if (!isCheckinRequest && mi != null) {
12906                    totalPss += myTotalPss;
12907                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12908                            (hasActivities ? " / activities)" : ")"),
12909                            r.processName, myTotalPss, pid, hasActivities);
12910                    procMems.add(pssItem);
12911                    procMemsMap.put(pid, pssItem);
12912
12913                    nativePss += mi.nativePss;
12914                    dalvikPss += mi.dalvikPss;
12915                    otherPss += mi.otherPss;
12916                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12917                        long mem = mi.getOtherPss(j);
12918                        miscPss[j] += mem;
12919                        otherPss -= mem;
12920                    }
12921
12922                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12923                        cachedPss += myTotalPss;
12924                    }
12925
12926                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12927                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12928                                || oomIndex == (oomPss.length-1)) {
12929                            oomPss[oomIndex] += myTotalPss;
12930                            if (oomProcs[oomIndex] == null) {
12931                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12932                            }
12933                            oomProcs[oomIndex].add(pssItem);
12934                            break;
12935                        }
12936                    }
12937                }
12938            }
12939        }
12940
12941        long nativeProcTotalPss = 0;
12942
12943        if (!isCheckinRequest && procs.size() > 1) {
12944            // If we are showing aggregations, also look for native processes to
12945            // include so that our aggregations are more accurate.
12946            updateCpuStatsNow();
12947            synchronized (mProcessCpuThread) {
12948                final int N = mProcessCpuTracker.countStats();
12949                for (int i=0; i<N; i++) {
12950                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12951                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12952                        if (mi == null) {
12953                            mi = new Debug.MemoryInfo();
12954                        }
12955                        if (!brief && !oomOnly) {
12956                            Debug.getMemoryInfo(st.pid, mi);
12957                        } else {
12958                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12959                            mi.nativePrivateDirty = (int)tmpLong[0];
12960                        }
12961
12962                        final long myTotalPss = mi.getTotalPss();
12963                        totalPss += myTotalPss;
12964                        nativeProcTotalPss += myTotalPss;
12965
12966                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12967                                st.name, myTotalPss, st.pid, false);
12968                        procMems.add(pssItem);
12969
12970                        nativePss += mi.nativePss;
12971                        dalvikPss += mi.dalvikPss;
12972                        otherPss += mi.otherPss;
12973                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12974                            long mem = mi.getOtherPss(j);
12975                            miscPss[j] += mem;
12976                            otherPss -= mem;
12977                        }
12978                        oomPss[0] += myTotalPss;
12979                        if (oomProcs[0] == null) {
12980                            oomProcs[0] = new ArrayList<MemItem>();
12981                        }
12982                        oomProcs[0].add(pssItem);
12983                    }
12984                }
12985            }
12986
12987            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12988
12989            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12990            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12991            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12992            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12993                String label = Debug.MemoryInfo.getOtherLabel(j);
12994                catMems.add(new MemItem(label, label, miscPss[j], j));
12995            }
12996
12997            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12998            for (int j=0; j<oomPss.length; j++) {
12999                if (oomPss[j] != 0) {
13000                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13001                            : DUMP_MEM_OOM_LABEL[j];
13002                    MemItem item = new MemItem(label, label, oomPss[j],
13003                            DUMP_MEM_OOM_ADJ[j]);
13004                    item.subitems = oomProcs[j];
13005                    oomMems.add(item);
13006                }
13007            }
13008
13009            if (!brief && !oomOnly && !isCompact) {
13010                pw.println();
13011                pw.println("Total PSS by process:");
13012                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13013                pw.println();
13014            }
13015            if (!isCompact) {
13016                pw.println("Total PSS by OOM adjustment:");
13017            }
13018            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13019            if (!brief && !oomOnly) {
13020                PrintWriter out = categoryPw != null ? categoryPw : pw;
13021                if (!isCompact) {
13022                    out.println();
13023                    out.println("Total PSS by category:");
13024                }
13025                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13026            }
13027            if (!isCompact) {
13028                pw.println();
13029            }
13030            MemInfoReader memInfo = new MemInfoReader();
13031            memInfo.readMemInfo();
13032            if (nativeProcTotalPss > 0) {
13033                synchronized (this) {
13034                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13035                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13036                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13037                            nativeProcTotalPss);
13038                }
13039            }
13040            if (!brief) {
13041                if (!isCompact) {
13042                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13043                    pw.print(" kB (status ");
13044                    switch (mLastMemoryLevel) {
13045                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13046                            pw.println("normal)");
13047                            break;
13048                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13049                            pw.println("moderate)");
13050                            break;
13051                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13052                            pw.println("low)");
13053                            break;
13054                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13055                            pw.println("critical)");
13056                            break;
13057                        default:
13058                            pw.print(mLastMemoryLevel);
13059                            pw.println(")");
13060                            break;
13061                    }
13062                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13063                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13064                            pw.print(cachedPss); pw.print(" cached pss + ");
13065                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13066                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13067                } else {
13068                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13069                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13070                            + memInfo.getFreeSizeKb()); pw.print(",");
13071                    pw.println(totalPss - cachedPss);
13072                }
13073            }
13074            if (!isCompact) {
13075                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13076                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13077                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13078                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13079                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13080                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13081                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13082                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13083                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13084                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13085                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13086            }
13087            if (!brief) {
13088                if (memInfo.getZramTotalSizeKb() != 0) {
13089                    if (!isCompact) {
13090                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13091                                pw.print(" kB physical used for ");
13092                                pw.print(memInfo.getSwapTotalSizeKb()
13093                                        - memInfo.getSwapFreeSizeKb());
13094                                pw.print(" kB in swap (");
13095                                pw.print(memInfo.getSwapTotalSizeKb());
13096                                pw.println(" kB total swap)");
13097                    } else {
13098                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13099                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13100                                pw.println(memInfo.getSwapFreeSizeKb());
13101                    }
13102                }
13103                final int[] SINGLE_LONG_FORMAT = new int[] {
13104                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13105                };
13106                long[] longOut = new long[1];
13107                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13108                        SINGLE_LONG_FORMAT, null, longOut, null);
13109                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13110                longOut[0] = 0;
13111                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13112                        SINGLE_LONG_FORMAT, null, longOut, null);
13113                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13114                longOut[0] = 0;
13115                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13116                        SINGLE_LONG_FORMAT, null, longOut, null);
13117                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13118                longOut[0] = 0;
13119                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13120                        SINGLE_LONG_FORMAT, null, longOut, null);
13121                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13122                if (!isCompact) {
13123                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13124                        pw.print("      KSM: "); pw.print(sharing);
13125                                pw.print(" kB saved from shared ");
13126                                pw.print(shared); pw.println(" kB");
13127                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13128                                pw.print(voltile); pw.println(" kB volatile");
13129                    }
13130                    pw.print("   Tuning: ");
13131                    pw.print(ActivityManager.staticGetMemoryClass());
13132                    pw.print(" (large ");
13133                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13134                    pw.print("), oom ");
13135                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13136                    pw.print(" kB");
13137                    pw.print(", restore limit ");
13138                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13139                    pw.print(" kB");
13140                    if (ActivityManager.isLowRamDeviceStatic()) {
13141                        pw.print(" (low-ram)");
13142                    }
13143                    if (ActivityManager.isHighEndGfx()) {
13144                        pw.print(" (high-end-gfx)");
13145                    }
13146                    pw.println();
13147                } else {
13148                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13149                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13150                    pw.println(voltile);
13151                    pw.print("tuning,");
13152                    pw.print(ActivityManager.staticGetMemoryClass());
13153                    pw.print(',');
13154                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13155                    pw.print(',');
13156                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13157                    if (ActivityManager.isLowRamDeviceStatic()) {
13158                        pw.print(",low-ram");
13159                    }
13160                    if (ActivityManager.isHighEndGfx()) {
13161                        pw.print(",high-end-gfx");
13162                    }
13163                    pw.println();
13164                }
13165            }
13166        }
13167    }
13168
13169    /**
13170     * Searches array of arguments for the specified string
13171     * @param args array of argument strings
13172     * @param value value to search for
13173     * @return true if the value is contained in the array
13174     */
13175    private static boolean scanArgs(String[] args, String value) {
13176        if (args != null) {
13177            for (String arg : args) {
13178                if (value.equals(arg)) {
13179                    return true;
13180                }
13181            }
13182        }
13183        return false;
13184    }
13185
13186    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13187            ContentProviderRecord cpr, boolean always) {
13188        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13189
13190        if (!inLaunching || always) {
13191            synchronized (cpr) {
13192                cpr.launchingApp = null;
13193                cpr.notifyAll();
13194            }
13195            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13196            String names[] = cpr.info.authority.split(";");
13197            for (int j = 0; j < names.length; j++) {
13198                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13199            }
13200        }
13201
13202        for (int i=0; i<cpr.connections.size(); i++) {
13203            ContentProviderConnection conn = cpr.connections.get(i);
13204            if (conn.waiting) {
13205                // If this connection is waiting for the provider, then we don't
13206                // need to mess with its process unless we are always removing
13207                // or for some reason the provider is not currently launching.
13208                if (inLaunching && !always) {
13209                    continue;
13210                }
13211            }
13212            ProcessRecord capp = conn.client;
13213            conn.dead = true;
13214            if (conn.stableCount > 0) {
13215                if (!capp.persistent && capp.thread != null
13216                        && capp.pid != 0
13217                        && capp.pid != MY_PID) {
13218                    killUnneededProcessLocked(capp, "depends on provider "
13219                            + cpr.name.flattenToShortString()
13220                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13221                }
13222            } else if (capp.thread != null && conn.provider.provider != null) {
13223                try {
13224                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13225                } catch (RemoteException e) {
13226                }
13227                // In the protocol here, we don't expect the client to correctly
13228                // clean up this connection, we'll just remove it.
13229                cpr.connections.remove(i);
13230                conn.client.conProviders.remove(conn);
13231            }
13232        }
13233
13234        if (inLaunching && always) {
13235            mLaunchingProviders.remove(cpr);
13236        }
13237        return inLaunching;
13238    }
13239
13240    /**
13241     * Main code for cleaning up a process when it has gone away.  This is
13242     * called both as a result of the process dying, or directly when stopping
13243     * a process when running in single process mode.
13244     */
13245    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13246            boolean restarting, boolean allowRestart, int index) {
13247        if (index >= 0) {
13248            removeLruProcessLocked(app);
13249            ProcessList.remove(app.pid);
13250        }
13251
13252        mProcessesToGc.remove(app);
13253        mPendingPssProcesses.remove(app);
13254
13255        // Dismiss any open dialogs.
13256        if (app.crashDialog != null && !app.forceCrashReport) {
13257            app.crashDialog.dismiss();
13258            app.crashDialog = null;
13259        }
13260        if (app.anrDialog != null) {
13261            app.anrDialog.dismiss();
13262            app.anrDialog = null;
13263        }
13264        if (app.waitDialog != null) {
13265            app.waitDialog.dismiss();
13266            app.waitDialog = null;
13267        }
13268
13269        app.crashing = false;
13270        app.notResponding = false;
13271
13272        app.resetPackageList(mProcessStats);
13273        app.unlinkDeathRecipient();
13274        app.makeInactive(mProcessStats);
13275        app.waitingToKill = null;
13276        app.forcingToForeground = null;
13277        updateProcessForegroundLocked(app, false, false);
13278        app.foregroundActivities = false;
13279        app.hasShownUi = false;
13280        app.treatLikeActivity = false;
13281        app.hasAboveClient = false;
13282        app.hasClientActivities = false;
13283
13284        mServices.killServicesLocked(app, allowRestart);
13285
13286        boolean restart = false;
13287
13288        // Remove published content providers.
13289        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13290            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13291            final boolean always = app.bad || !allowRestart;
13292            if (removeDyingProviderLocked(app, cpr, always) || always) {
13293                // We left the provider in the launching list, need to
13294                // restart it.
13295                restart = true;
13296            }
13297
13298            cpr.provider = null;
13299            cpr.proc = null;
13300        }
13301        app.pubProviders.clear();
13302
13303        // Take care of any launching providers waiting for this process.
13304        if (checkAppInLaunchingProvidersLocked(app, false)) {
13305            restart = true;
13306        }
13307
13308        // Unregister from connected content providers.
13309        if (!app.conProviders.isEmpty()) {
13310            for (int i=0; i<app.conProviders.size(); i++) {
13311                ContentProviderConnection conn = app.conProviders.get(i);
13312                conn.provider.connections.remove(conn);
13313            }
13314            app.conProviders.clear();
13315        }
13316
13317        // At this point there may be remaining entries in mLaunchingProviders
13318        // where we were the only one waiting, so they are no longer of use.
13319        // Look for these and clean up if found.
13320        // XXX Commented out for now.  Trying to figure out a way to reproduce
13321        // the actual situation to identify what is actually going on.
13322        if (false) {
13323            for (int i=0; i<mLaunchingProviders.size(); i++) {
13324                ContentProviderRecord cpr = (ContentProviderRecord)
13325                        mLaunchingProviders.get(i);
13326                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13327                    synchronized (cpr) {
13328                        cpr.launchingApp = null;
13329                        cpr.notifyAll();
13330                    }
13331                }
13332            }
13333        }
13334
13335        skipCurrentReceiverLocked(app);
13336
13337        // Unregister any receivers.
13338        for (int i=app.receivers.size()-1; i>=0; i--) {
13339            removeReceiverLocked(app.receivers.valueAt(i));
13340        }
13341        app.receivers.clear();
13342
13343        // If the app is undergoing backup, tell the backup manager about it
13344        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13345            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13346                    + mBackupTarget.appInfo + " died during backup");
13347            try {
13348                IBackupManager bm = IBackupManager.Stub.asInterface(
13349                        ServiceManager.getService(Context.BACKUP_SERVICE));
13350                bm.agentDisconnected(app.info.packageName);
13351            } catch (RemoteException e) {
13352                // can't happen; backup manager is local
13353            }
13354        }
13355
13356        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13357            ProcessChangeItem item = mPendingProcessChanges.get(i);
13358            if (item.pid == app.pid) {
13359                mPendingProcessChanges.remove(i);
13360                mAvailProcessChanges.add(item);
13361            }
13362        }
13363        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13364
13365        // If the caller is restarting this app, then leave it in its
13366        // current lists and let the caller take care of it.
13367        if (restarting) {
13368            return;
13369        }
13370
13371        if (!app.persistent || app.isolated) {
13372            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13373                    "Removing non-persistent process during cleanup: " + app);
13374            mProcessNames.remove(app.processName, app.uid);
13375            mIsolatedProcesses.remove(app.uid);
13376            if (mHeavyWeightProcess == app) {
13377                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13378                        mHeavyWeightProcess.userId, 0));
13379                mHeavyWeightProcess = null;
13380            }
13381        } else if (!app.removed) {
13382            // This app is persistent, so we need to keep its record around.
13383            // If it is not already on the pending app list, add it there
13384            // and start a new process for it.
13385            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13386                mPersistentStartingProcesses.add(app);
13387                restart = true;
13388            }
13389        }
13390        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13391                "Clean-up removing on hold: " + app);
13392        mProcessesOnHold.remove(app);
13393
13394        if (app == mHomeProcess) {
13395            mHomeProcess = null;
13396        }
13397        if (app == mPreviousProcess) {
13398            mPreviousProcess = null;
13399        }
13400
13401        if (restart && !app.isolated) {
13402            // We have components that still need to be running in the
13403            // process, so re-launch it.
13404            mProcessNames.put(app.processName, app.uid, app);
13405            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13406        } else if (app.pid > 0 && app.pid != MY_PID) {
13407            // Goodbye!
13408            boolean removed;
13409            synchronized (mPidsSelfLocked) {
13410                mPidsSelfLocked.remove(app.pid);
13411                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13412            }
13413            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
13414            if (app.isolated) {
13415                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13416            }
13417            app.setPid(0);
13418        }
13419    }
13420
13421    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13422        // Look through the content providers we are waiting to have launched,
13423        // and if any run in this process then either schedule a restart of
13424        // the process or kill the client waiting for it if this process has
13425        // gone bad.
13426        int NL = mLaunchingProviders.size();
13427        boolean restart = false;
13428        for (int i=0; i<NL; i++) {
13429            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13430            if (cpr.launchingApp == app) {
13431                if (!alwaysBad && !app.bad) {
13432                    restart = true;
13433                } else {
13434                    removeDyingProviderLocked(app, cpr, true);
13435                    // cpr should have been removed from mLaunchingProviders
13436                    NL = mLaunchingProviders.size();
13437                    i--;
13438                }
13439            }
13440        }
13441        return restart;
13442    }
13443
13444    // =========================================================
13445    // SERVICES
13446    // =========================================================
13447
13448    @Override
13449    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13450            int flags) {
13451        enforceNotIsolatedCaller("getServices");
13452        synchronized (this) {
13453            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13454        }
13455    }
13456
13457    @Override
13458    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13459        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13460        synchronized (this) {
13461            return mServices.getRunningServiceControlPanelLocked(name);
13462        }
13463    }
13464
13465    @Override
13466    public ComponentName startService(IApplicationThread caller, Intent service,
13467            String resolvedType, int userId) {
13468        enforceNotIsolatedCaller("startService");
13469        // Refuse possible leaked file descriptors
13470        if (service != null && service.hasFileDescriptors() == true) {
13471            throw new IllegalArgumentException("File descriptors passed in Intent");
13472        }
13473
13474        if (DEBUG_SERVICE)
13475            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13476        synchronized(this) {
13477            final int callingPid = Binder.getCallingPid();
13478            final int callingUid = Binder.getCallingUid();
13479            final long origId = Binder.clearCallingIdentity();
13480            ComponentName res = mServices.startServiceLocked(caller, service,
13481                    resolvedType, callingPid, callingUid, userId);
13482            Binder.restoreCallingIdentity(origId);
13483            return res;
13484        }
13485    }
13486
13487    ComponentName startServiceInPackage(int uid,
13488            Intent service, String resolvedType, int userId) {
13489        synchronized(this) {
13490            if (DEBUG_SERVICE)
13491                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13492            final long origId = Binder.clearCallingIdentity();
13493            ComponentName res = mServices.startServiceLocked(null, service,
13494                    resolvedType, -1, uid, userId);
13495            Binder.restoreCallingIdentity(origId);
13496            return res;
13497        }
13498    }
13499
13500    @Override
13501    public int stopService(IApplicationThread caller, Intent service,
13502            String resolvedType, int userId) {
13503        enforceNotIsolatedCaller("stopService");
13504        // Refuse possible leaked file descriptors
13505        if (service != null && service.hasFileDescriptors() == true) {
13506            throw new IllegalArgumentException("File descriptors passed in Intent");
13507        }
13508
13509        synchronized(this) {
13510            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13511        }
13512    }
13513
13514    @Override
13515    public IBinder peekService(Intent service, String resolvedType) {
13516        enforceNotIsolatedCaller("peekService");
13517        // Refuse possible leaked file descriptors
13518        if (service != null && service.hasFileDescriptors() == true) {
13519            throw new IllegalArgumentException("File descriptors passed in Intent");
13520        }
13521        synchronized(this) {
13522            return mServices.peekServiceLocked(service, resolvedType);
13523        }
13524    }
13525
13526    @Override
13527    public boolean stopServiceToken(ComponentName className, IBinder token,
13528            int startId) {
13529        synchronized(this) {
13530            return mServices.stopServiceTokenLocked(className, token, startId);
13531        }
13532    }
13533
13534    @Override
13535    public void setServiceForeground(ComponentName className, IBinder token,
13536            int id, Notification notification, boolean removeNotification) {
13537        synchronized(this) {
13538            mServices.setServiceForegroundLocked(className, token, id, notification,
13539                    removeNotification);
13540        }
13541    }
13542
13543    @Override
13544    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13545            boolean requireFull, String name, String callerPackage) {
13546        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
13547                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
13548    }
13549
13550    int unsafeConvertIncomingUser(int userId) {
13551        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
13552                ? mCurrentUserId : userId;
13553    }
13554
13555    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13556            int allowMode, String name, String callerPackage) {
13557        final int callingUserId = UserHandle.getUserId(callingUid);
13558        if (callingUserId == userId) {
13559            return userId;
13560        }
13561
13562        // Note that we may be accessing mCurrentUserId outside of a lock...
13563        // shouldn't be a big deal, if this is being called outside
13564        // of a locked context there is intrinsically a race with
13565        // the value the caller will receive and someone else changing it.
13566        // We assume that USER_CURRENT_OR_SELF will use the current user; later
13567        // we will switch to the calling user if access to the current user fails.
13568        int targetUserId = unsafeConvertIncomingUser(userId);
13569
13570        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13571            final boolean allow;
13572            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
13573                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
13574                // If the caller has this permission, they always pass go.  And collect $200.
13575                allow = true;
13576            } else if (allowMode == ALLOW_FULL_ONLY) {
13577                // We require full access, sucks to be you.
13578                allow = false;
13579            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
13580                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
13581                // If the caller does not have either permission, they are always doomed.
13582                allow = false;
13583            } else if (allowMode == ALLOW_NON_FULL) {
13584                // We are blanket allowing non-full access, you lucky caller!
13585                allow = true;
13586            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
13587                // We may or may not allow this depending on whether the two users are
13588                // in the same profile.
13589                synchronized (mUserProfileGroupIdsSelfLocked) {
13590                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
13591                            UserInfo.NO_PROFILE_GROUP_ID);
13592                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
13593                            UserInfo.NO_PROFILE_GROUP_ID);
13594                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
13595                            && callingProfile == targetProfile;
13596                }
13597            } else {
13598                throw new IllegalArgumentException("Unknown mode: " + allowMode);
13599            }
13600            if (!allow) {
13601                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13602                    // In this case, they would like to just execute as their
13603                    // owner user instead of failing.
13604                    targetUserId = callingUserId;
13605                } else {
13606                    StringBuilder builder = new StringBuilder(128);
13607                    builder.append("Permission Denial: ");
13608                    builder.append(name);
13609                    if (callerPackage != null) {
13610                        builder.append(" from ");
13611                        builder.append(callerPackage);
13612                    }
13613                    builder.append(" asks to run as user ");
13614                    builder.append(userId);
13615                    builder.append(" but is calling from user ");
13616                    builder.append(UserHandle.getUserId(callingUid));
13617                    builder.append("; this requires ");
13618                    builder.append(INTERACT_ACROSS_USERS_FULL);
13619                    if (allowMode != ALLOW_FULL_ONLY) {
13620                        builder.append(" or ");
13621                        builder.append(INTERACT_ACROSS_USERS);
13622                    }
13623                    String msg = builder.toString();
13624                    Slog.w(TAG, msg);
13625                    throw new SecurityException(msg);
13626                }
13627            }
13628        }
13629        if (!allowAll && targetUserId < 0) {
13630            throw new IllegalArgumentException(
13631                    "Call does not support special user #" + targetUserId);
13632        }
13633        return targetUserId;
13634    }
13635
13636    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13637            String className, int flags) {
13638        boolean result = false;
13639        // For apps that don't have pre-defined UIDs, check for permission
13640        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13641            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13642                if (ActivityManager.checkUidPermission(
13643                        INTERACT_ACROSS_USERS,
13644                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13645                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13646                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13647                            + " requests FLAG_SINGLE_USER, but app does not hold "
13648                            + INTERACT_ACROSS_USERS;
13649                    Slog.w(TAG, msg);
13650                    throw new SecurityException(msg);
13651                }
13652                // Permission passed
13653                result = true;
13654            }
13655        } else if ("system".equals(componentProcessName)) {
13656            result = true;
13657        } else {
13658            // App with pre-defined UID, check if it's a persistent app
13659            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13660        }
13661        if (DEBUG_MU) {
13662            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13663                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13664        }
13665        return result;
13666    }
13667
13668    /**
13669     * Checks to see if the caller is in the same app as the singleton
13670     * component, or the component is in a special app. It allows special apps
13671     * to export singleton components but prevents exporting singleton
13672     * components for regular apps.
13673     */
13674    boolean isValidSingletonCall(int callingUid, int componentUid) {
13675        int componentAppId = UserHandle.getAppId(componentUid);
13676        return UserHandle.isSameApp(callingUid, componentUid)
13677                || componentAppId == Process.SYSTEM_UID
13678                || componentAppId == Process.PHONE_UID
13679                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13680                        == PackageManager.PERMISSION_GRANTED;
13681    }
13682
13683    public int bindService(IApplicationThread caller, IBinder token,
13684            Intent service, String resolvedType,
13685            IServiceConnection connection, int flags, int userId) {
13686        enforceNotIsolatedCaller("bindService");
13687        // Refuse possible leaked file descriptors
13688        if (service != null && service.hasFileDescriptors() == true) {
13689            throw new IllegalArgumentException("File descriptors passed in Intent");
13690        }
13691
13692        synchronized(this) {
13693            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13694                    connection, flags, userId);
13695        }
13696    }
13697
13698    public boolean unbindService(IServiceConnection connection) {
13699        synchronized (this) {
13700            return mServices.unbindServiceLocked(connection);
13701        }
13702    }
13703
13704    public void publishService(IBinder token, Intent intent, IBinder service) {
13705        // Refuse possible leaked file descriptors
13706        if (intent != null && intent.hasFileDescriptors() == true) {
13707            throw new IllegalArgumentException("File descriptors passed in Intent");
13708        }
13709
13710        synchronized(this) {
13711            if (!(token instanceof ServiceRecord)) {
13712                throw new IllegalArgumentException("Invalid service token");
13713            }
13714            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13715        }
13716    }
13717
13718    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13719        // Refuse possible leaked file descriptors
13720        if (intent != null && intent.hasFileDescriptors() == true) {
13721            throw new IllegalArgumentException("File descriptors passed in Intent");
13722        }
13723
13724        synchronized(this) {
13725            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13726        }
13727    }
13728
13729    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13730        synchronized(this) {
13731            if (!(token instanceof ServiceRecord)) {
13732                throw new IllegalArgumentException("Invalid service token");
13733            }
13734            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13735        }
13736    }
13737
13738    // =========================================================
13739    // BACKUP AND RESTORE
13740    // =========================================================
13741
13742    // Cause the target app to be launched if necessary and its backup agent
13743    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13744    // activity manager to announce its creation.
13745    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13746        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13747        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
13748
13749        synchronized(this) {
13750            // !!! TODO: currently no check here that we're already bound
13751            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13752            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13753            synchronized (stats) {
13754                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13755            }
13756
13757            // Backup agent is now in use, its package can't be stopped.
13758            try {
13759                AppGlobals.getPackageManager().setPackageStoppedState(
13760                        app.packageName, false, UserHandle.getUserId(app.uid));
13761            } catch (RemoteException e) {
13762            } catch (IllegalArgumentException e) {
13763                Slog.w(TAG, "Failed trying to unstop package "
13764                        + app.packageName + ": " + e);
13765            }
13766
13767            BackupRecord r = new BackupRecord(ss, app, backupMode);
13768            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13769                    ? new ComponentName(app.packageName, app.backupAgentName)
13770                    : new ComponentName("android", "FullBackupAgent");
13771            // startProcessLocked() returns existing proc's record if it's already running
13772            ProcessRecord proc = startProcessLocked(app.processName, app,
13773                    false, 0, "backup", hostingName, false, false, false);
13774            if (proc == null) {
13775                Slog.e(TAG, "Unable to start backup agent process " + r);
13776                return false;
13777            }
13778
13779            r.app = proc;
13780            mBackupTarget = r;
13781            mBackupAppName = app.packageName;
13782
13783            // Try not to kill the process during backup
13784            updateOomAdjLocked(proc);
13785
13786            // If the process is already attached, schedule the creation of the backup agent now.
13787            // If it is not yet live, this will be done when it attaches to the framework.
13788            if (proc.thread != null) {
13789                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13790                try {
13791                    proc.thread.scheduleCreateBackupAgent(app,
13792                            compatibilityInfoForPackageLocked(app), backupMode);
13793                } catch (RemoteException e) {
13794                    // Will time out on the backup manager side
13795                }
13796            } else {
13797                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13798            }
13799            // Invariants: at this point, the target app process exists and the application
13800            // is either already running or in the process of coming up.  mBackupTarget and
13801            // mBackupAppName describe the app, so that when it binds back to the AM we
13802            // know that it's scheduled for a backup-agent operation.
13803        }
13804
13805        return true;
13806    }
13807
13808    @Override
13809    public void clearPendingBackup() {
13810        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13811        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13812
13813        synchronized (this) {
13814            mBackupTarget = null;
13815            mBackupAppName = null;
13816        }
13817    }
13818
13819    // A backup agent has just come up
13820    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13821        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13822                + " = " + agent);
13823
13824        synchronized(this) {
13825            if (!agentPackageName.equals(mBackupAppName)) {
13826                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13827                return;
13828            }
13829        }
13830
13831        long oldIdent = Binder.clearCallingIdentity();
13832        try {
13833            IBackupManager bm = IBackupManager.Stub.asInterface(
13834                    ServiceManager.getService(Context.BACKUP_SERVICE));
13835            bm.agentConnected(agentPackageName, agent);
13836        } catch (RemoteException e) {
13837            // can't happen; the backup manager service is local
13838        } catch (Exception e) {
13839            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13840            e.printStackTrace();
13841        } finally {
13842            Binder.restoreCallingIdentity(oldIdent);
13843        }
13844    }
13845
13846    // done with this agent
13847    public void unbindBackupAgent(ApplicationInfo appInfo) {
13848        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13849        if (appInfo == null) {
13850            Slog.w(TAG, "unbind backup agent for null app");
13851            return;
13852        }
13853
13854        synchronized(this) {
13855            try {
13856                if (mBackupAppName == null) {
13857                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13858                    return;
13859                }
13860
13861                if (!mBackupAppName.equals(appInfo.packageName)) {
13862                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13863                    return;
13864                }
13865
13866                // Not backing this app up any more; reset its OOM adjustment
13867                final ProcessRecord proc = mBackupTarget.app;
13868                updateOomAdjLocked(proc);
13869
13870                // If the app crashed during backup, 'thread' will be null here
13871                if (proc.thread != null) {
13872                    try {
13873                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13874                                compatibilityInfoForPackageLocked(appInfo));
13875                    } catch (Exception e) {
13876                        Slog.e(TAG, "Exception when unbinding backup agent:");
13877                        e.printStackTrace();
13878                    }
13879                }
13880            } finally {
13881                mBackupTarget = null;
13882                mBackupAppName = null;
13883            }
13884        }
13885    }
13886    // =========================================================
13887    // BROADCASTS
13888    // =========================================================
13889
13890    private final List getStickiesLocked(String action, IntentFilter filter,
13891            List cur, int userId) {
13892        final ContentResolver resolver = mContext.getContentResolver();
13893        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13894        if (stickies == null) {
13895            return cur;
13896        }
13897        final ArrayList<Intent> list = stickies.get(action);
13898        if (list == null) {
13899            return cur;
13900        }
13901        int N = list.size();
13902        for (int i=0; i<N; i++) {
13903            Intent intent = list.get(i);
13904            if (filter.match(resolver, intent, true, TAG) >= 0) {
13905                if (cur == null) {
13906                    cur = new ArrayList<Intent>();
13907                }
13908                cur.add(intent);
13909            }
13910        }
13911        return cur;
13912    }
13913
13914    boolean isPendingBroadcastProcessLocked(int pid) {
13915        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13916                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13917    }
13918
13919    void skipPendingBroadcastLocked(int pid) {
13920            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13921            for (BroadcastQueue queue : mBroadcastQueues) {
13922                queue.skipPendingBroadcastLocked(pid);
13923            }
13924    }
13925
13926    // The app just attached; send any pending broadcasts that it should receive
13927    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13928        boolean didSomething = false;
13929        for (BroadcastQueue queue : mBroadcastQueues) {
13930            didSomething |= queue.sendPendingBroadcastsLocked(app);
13931        }
13932        return didSomething;
13933    }
13934
13935    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13936            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13937        enforceNotIsolatedCaller("registerReceiver");
13938        int callingUid;
13939        int callingPid;
13940        synchronized(this) {
13941            ProcessRecord callerApp = null;
13942            if (caller != null) {
13943                callerApp = getRecordForAppLocked(caller);
13944                if (callerApp == null) {
13945                    throw new SecurityException(
13946                            "Unable to find app for caller " + caller
13947                            + " (pid=" + Binder.getCallingPid()
13948                            + ") when registering receiver " + receiver);
13949                }
13950                if (callerApp.info.uid != Process.SYSTEM_UID &&
13951                        !callerApp.pkgList.containsKey(callerPackage) &&
13952                        !"android".equals(callerPackage)) {
13953                    throw new SecurityException("Given caller package " + callerPackage
13954                            + " is not running in process " + callerApp);
13955                }
13956                callingUid = callerApp.info.uid;
13957                callingPid = callerApp.pid;
13958            } else {
13959                callerPackage = null;
13960                callingUid = Binder.getCallingUid();
13961                callingPid = Binder.getCallingPid();
13962            }
13963
13964            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13965                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
13966
13967            List allSticky = null;
13968
13969            // Look for any matching sticky broadcasts...
13970            Iterator actions = filter.actionsIterator();
13971            if (actions != null) {
13972                while (actions.hasNext()) {
13973                    String action = (String)actions.next();
13974                    allSticky = getStickiesLocked(action, filter, allSticky,
13975                            UserHandle.USER_ALL);
13976                    allSticky = getStickiesLocked(action, filter, allSticky,
13977                            UserHandle.getUserId(callingUid));
13978                }
13979            } else {
13980                allSticky = getStickiesLocked(null, filter, allSticky,
13981                        UserHandle.USER_ALL);
13982                allSticky = getStickiesLocked(null, filter, allSticky,
13983                        UserHandle.getUserId(callingUid));
13984            }
13985
13986            // The first sticky in the list is returned directly back to
13987            // the client.
13988            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13989
13990            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13991                    + ": " + sticky);
13992
13993            if (receiver == null) {
13994                return sticky;
13995            }
13996
13997            ReceiverList rl
13998                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13999            if (rl == null) {
14000                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14001                        userId, receiver);
14002                if (rl.app != null) {
14003                    rl.app.receivers.add(rl);
14004                } else {
14005                    try {
14006                        receiver.asBinder().linkToDeath(rl, 0);
14007                    } catch (RemoteException e) {
14008                        return sticky;
14009                    }
14010                    rl.linkedToDeath = true;
14011                }
14012                mRegisteredReceivers.put(receiver.asBinder(), rl);
14013            } else if (rl.uid != callingUid) {
14014                throw new IllegalArgumentException(
14015                        "Receiver requested to register for uid " + callingUid
14016                        + " was previously registered for uid " + rl.uid);
14017            } else if (rl.pid != callingPid) {
14018                throw new IllegalArgumentException(
14019                        "Receiver requested to register for pid " + callingPid
14020                        + " was previously registered for pid " + rl.pid);
14021            } else if (rl.userId != userId) {
14022                throw new IllegalArgumentException(
14023                        "Receiver requested to register for user " + userId
14024                        + " was previously registered for user " + rl.userId);
14025            }
14026            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14027                    permission, callingUid, userId);
14028            rl.add(bf);
14029            if (!bf.debugCheck()) {
14030                Slog.w(TAG, "==> For Dynamic broadast");
14031            }
14032            mReceiverResolver.addFilter(bf);
14033
14034            // Enqueue broadcasts for all existing stickies that match
14035            // this filter.
14036            if (allSticky != null) {
14037                ArrayList receivers = new ArrayList();
14038                receivers.add(bf);
14039
14040                int N = allSticky.size();
14041                for (int i=0; i<N; i++) {
14042                    Intent intent = (Intent)allSticky.get(i);
14043                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14044                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14045                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14046                            null, null, false, true, true, -1);
14047                    queue.enqueueParallelBroadcastLocked(r);
14048                    queue.scheduleBroadcastsLocked();
14049                }
14050            }
14051
14052            return sticky;
14053        }
14054    }
14055
14056    public void unregisterReceiver(IIntentReceiver receiver) {
14057        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14058
14059        final long origId = Binder.clearCallingIdentity();
14060        try {
14061            boolean doTrim = false;
14062
14063            synchronized(this) {
14064                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14065                if (rl != null) {
14066                    if (rl.curBroadcast != null) {
14067                        BroadcastRecord r = rl.curBroadcast;
14068                        final boolean doNext = finishReceiverLocked(
14069                                receiver.asBinder(), r.resultCode, r.resultData,
14070                                r.resultExtras, r.resultAbort);
14071                        if (doNext) {
14072                            doTrim = true;
14073                            r.queue.processNextBroadcast(false);
14074                        }
14075                    }
14076
14077                    if (rl.app != null) {
14078                        rl.app.receivers.remove(rl);
14079                    }
14080                    removeReceiverLocked(rl);
14081                    if (rl.linkedToDeath) {
14082                        rl.linkedToDeath = false;
14083                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14084                    }
14085                }
14086            }
14087
14088            // If we actually concluded any broadcasts, we might now be able
14089            // to trim the recipients' apps from our working set
14090            if (doTrim) {
14091                trimApplications();
14092                return;
14093            }
14094
14095        } finally {
14096            Binder.restoreCallingIdentity(origId);
14097        }
14098    }
14099
14100    void removeReceiverLocked(ReceiverList rl) {
14101        mRegisteredReceivers.remove(rl.receiver.asBinder());
14102        int N = rl.size();
14103        for (int i=0; i<N; i++) {
14104            mReceiverResolver.removeFilter(rl.get(i));
14105        }
14106    }
14107
14108    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14109        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14110            ProcessRecord r = mLruProcesses.get(i);
14111            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14112                try {
14113                    r.thread.dispatchPackageBroadcast(cmd, packages);
14114                } catch (RemoteException ex) {
14115                }
14116            }
14117        }
14118    }
14119
14120    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14121            int[] users) {
14122        List<ResolveInfo> receivers = null;
14123        try {
14124            HashSet<ComponentName> singleUserReceivers = null;
14125            boolean scannedFirstReceivers = false;
14126            for (int user : users) {
14127                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14128                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14129                if (user != 0 && newReceivers != null) {
14130                    // If this is not the primary user, we need to check for
14131                    // any receivers that should be filtered out.
14132                    for (int i=0; i<newReceivers.size(); i++) {
14133                        ResolveInfo ri = newReceivers.get(i);
14134                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14135                            newReceivers.remove(i);
14136                            i--;
14137                        }
14138                    }
14139                }
14140                if (newReceivers != null && newReceivers.size() == 0) {
14141                    newReceivers = null;
14142                }
14143                if (receivers == null) {
14144                    receivers = newReceivers;
14145                } else if (newReceivers != null) {
14146                    // We need to concatenate the additional receivers
14147                    // found with what we have do far.  This would be easy,
14148                    // but we also need to de-dup any receivers that are
14149                    // singleUser.
14150                    if (!scannedFirstReceivers) {
14151                        // Collect any single user receivers we had already retrieved.
14152                        scannedFirstReceivers = true;
14153                        for (int i=0; i<receivers.size(); i++) {
14154                            ResolveInfo ri = receivers.get(i);
14155                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14156                                ComponentName cn = new ComponentName(
14157                                        ri.activityInfo.packageName, ri.activityInfo.name);
14158                                if (singleUserReceivers == null) {
14159                                    singleUserReceivers = new HashSet<ComponentName>();
14160                                }
14161                                singleUserReceivers.add(cn);
14162                            }
14163                        }
14164                    }
14165                    // Add the new results to the existing results, tracking
14166                    // and de-dupping single user receivers.
14167                    for (int i=0; i<newReceivers.size(); i++) {
14168                        ResolveInfo ri = newReceivers.get(i);
14169                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14170                            ComponentName cn = new ComponentName(
14171                                    ri.activityInfo.packageName, ri.activityInfo.name);
14172                            if (singleUserReceivers == null) {
14173                                singleUserReceivers = new HashSet<ComponentName>();
14174                            }
14175                            if (!singleUserReceivers.contains(cn)) {
14176                                singleUserReceivers.add(cn);
14177                                receivers.add(ri);
14178                            }
14179                        } else {
14180                            receivers.add(ri);
14181                        }
14182                    }
14183                }
14184            }
14185        } catch (RemoteException ex) {
14186            // pm is in same process, this will never happen.
14187        }
14188        return receivers;
14189    }
14190
14191    private final int broadcastIntentLocked(ProcessRecord callerApp,
14192            String callerPackage, Intent intent, String resolvedType,
14193            IIntentReceiver resultTo, int resultCode, String resultData,
14194            Bundle map, String requiredPermission, int appOp,
14195            boolean ordered, boolean sticky, int callingPid, int callingUid,
14196            int userId) {
14197        intent = new Intent(intent);
14198
14199        // By default broadcasts do not go to stopped apps.
14200        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
14201
14202        if (DEBUG_BROADCAST_LIGHT) Slog.v(
14203            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
14204            + " ordered=" + ordered + " userid=" + userId);
14205        if ((resultTo != null) && !ordered) {
14206            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
14207        }
14208
14209        userId = handleIncomingUser(callingPid, callingUid, userId,
14210                true, ALLOW_NON_FULL, "broadcast", callerPackage);
14211
14212        // Make sure that the user who is receiving this broadcast is started.
14213        // If not, we will just skip it.
14214
14215
14216        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
14217            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14218                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14219                Slog.w(TAG, "Skipping broadcast of " + intent
14220                        + ": user " + userId + " is stopped");
14221                return ActivityManager.BROADCAST_SUCCESS;
14222            }
14223        }
14224
14225        /*
14226         * Prevent non-system code (defined here to be non-persistent
14227         * processes) from sending protected broadcasts.
14228         */
14229        int callingAppId = UserHandle.getAppId(callingUid);
14230        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14231            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14232            || callingAppId == Process.NFC_UID || callingUid == 0) {
14233            // Always okay.
14234        } else if (callerApp == null || !callerApp.persistent) {
14235            try {
14236                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14237                        intent.getAction())) {
14238                    String msg = "Permission Denial: not allowed to send broadcast "
14239                            + intent.getAction() + " from pid="
14240                            + callingPid + ", uid=" + callingUid;
14241                    Slog.w(TAG, msg);
14242                    throw new SecurityException(msg);
14243                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14244                    // Special case for compatibility: we don't want apps to send this,
14245                    // but historically it has not been protected and apps may be using it
14246                    // to poke their own app widget.  So, instead of making it protected,
14247                    // just limit it to the caller.
14248                    if (callerApp == null) {
14249                        String msg = "Permission Denial: not allowed to send broadcast "
14250                                + intent.getAction() + " from unknown caller.";
14251                        Slog.w(TAG, msg);
14252                        throw new SecurityException(msg);
14253                    } else if (intent.getComponent() != null) {
14254                        // They are good enough to send to an explicit component...  verify
14255                        // it is being sent to the calling app.
14256                        if (!intent.getComponent().getPackageName().equals(
14257                                callerApp.info.packageName)) {
14258                            String msg = "Permission Denial: not allowed to send broadcast "
14259                                    + intent.getAction() + " to "
14260                                    + intent.getComponent().getPackageName() + " from "
14261                                    + callerApp.info.packageName;
14262                            Slog.w(TAG, msg);
14263                            throw new SecurityException(msg);
14264                        }
14265                    } else {
14266                        // Limit broadcast to their own package.
14267                        intent.setPackage(callerApp.info.packageName);
14268                    }
14269                }
14270            } catch (RemoteException e) {
14271                Slog.w(TAG, "Remote exception", e);
14272                return ActivityManager.BROADCAST_SUCCESS;
14273            }
14274        }
14275
14276        // Handle special intents: if this broadcast is from the package
14277        // manager about a package being removed, we need to remove all of
14278        // its activities from the history stack.
14279        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14280                intent.getAction());
14281        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14282                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14283                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14284                || uidRemoved) {
14285            if (checkComponentPermission(
14286                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14287                    callingPid, callingUid, -1, true)
14288                    == PackageManager.PERMISSION_GRANTED) {
14289                if (uidRemoved) {
14290                    final Bundle intentExtras = intent.getExtras();
14291                    final int uid = intentExtras != null
14292                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14293                    if (uid >= 0) {
14294                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14295                        synchronized (bs) {
14296                            bs.removeUidStatsLocked(uid);
14297                        }
14298                        mAppOpsService.uidRemoved(uid);
14299                    }
14300                } else {
14301                    // If resources are unavailable just force stop all
14302                    // those packages and flush the attribute cache as well.
14303                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14304                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14305                        if (list != null && (list.length > 0)) {
14306                            for (String pkg : list) {
14307                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14308                                        "storage unmount");
14309                            }
14310                            sendPackageBroadcastLocked(
14311                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14312                        }
14313                    } else {
14314                        Uri data = intent.getData();
14315                        String ssp;
14316                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14317                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14318                                    intent.getAction());
14319                            boolean fullUninstall = removed &&
14320                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14321                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14322                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14323                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14324                                        false, fullUninstall, userId,
14325                                        removed ? "pkg removed" : "pkg changed");
14326                            }
14327                            if (removed) {
14328                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14329                                        new String[] {ssp}, userId);
14330                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14331                                    mAppOpsService.packageRemoved(
14332                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14333
14334                                    // Remove all permissions granted from/to this package
14335                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14336                                }
14337                            }
14338                        }
14339                    }
14340                }
14341            } else {
14342                String msg = "Permission Denial: " + intent.getAction()
14343                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14344                        + ", uid=" + callingUid + ")"
14345                        + " requires "
14346                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14347                Slog.w(TAG, msg);
14348                throw new SecurityException(msg);
14349            }
14350
14351        // Special case for adding a package: by default turn on compatibility
14352        // mode.
14353        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14354            Uri data = intent.getData();
14355            String ssp;
14356            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14357                mCompatModePackages.handlePackageAddedLocked(ssp,
14358                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14359            }
14360        }
14361
14362        /*
14363         * If this is the time zone changed action, queue up a message that will reset the timezone
14364         * of all currently running processes. This message will get queued up before the broadcast
14365         * happens.
14366         */
14367        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14368            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14369        }
14370
14371        /*
14372         * If the user set the time, let all running processes know.
14373         */
14374        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14375            final int is24Hour = intent.getBooleanExtra(
14376                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14377            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14378        }
14379
14380        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14381            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14382        }
14383
14384        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14385            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14386            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14387        }
14388
14389        // Add to the sticky list if requested.
14390        if (sticky) {
14391            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14392                    callingPid, callingUid)
14393                    != PackageManager.PERMISSION_GRANTED) {
14394                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14395                        + callingPid + ", uid=" + callingUid
14396                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14397                Slog.w(TAG, msg);
14398                throw new SecurityException(msg);
14399            }
14400            if (requiredPermission != null) {
14401                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14402                        + " and enforce permission " + requiredPermission);
14403                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14404            }
14405            if (intent.getComponent() != null) {
14406                throw new SecurityException(
14407                        "Sticky broadcasts can't target a specific component");
14408            }
14409            // We use userId directly here, since the "all" target is maintained
14410            // as a separate set of sticky broadcasts.
14411            if (userId != UserHandle.USER_ALL) {
14412                // But first, if this is not a broadcast to all users, then
14413                // make sure it doesn't conflict with an existing broadcast to
14414                // all users.
14415                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14416                        UserHandle.USER_ALL);
14417                if (stickies != null) {
14418                    ArrayList<Intent> list = stickies.get(intent.getAction());
14419                    if (list != null) {
14420                        int N = list.size();
14421                        int i;
14422                        for (i=0; i<N; i++) {
14423                            if (intent.filterEquals(list.get(i))) {
14424                                throw new IllegalArgumentException(
14425                                        "Sticky broadcast " + intent + " for user "
14426                                        + userId + " conflicts with existing global broadcast");
14427                            }
14428                        }
14429                    }
14430                }
14431            }
14432            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14433            if (stickies == null) {
14434                stickies = new ArrayMap<String, ArrayList<Intent>>();
14435                mStickyBroadcasts.put(userId, stickies);
14436            }
14437            ArrayList<Intent> list = stickies.get(intent.getAction());
14438            if (list == null) {
14439                list = new ArrayList<Intent>();
14440                stickies.put(intent.getAction(), list);
14441            }
14442            int N = list.size();
14443            int i;
14444            for (i=0; i<N; i++) {
14445                if (intent.filterEquals(list.get(i))) {
14446                    // This sticky already exists, replace it.
14447                    list.set(i, new Intent(intent));
14448                    break;
14449                }
14450            }
14451            if (i >= N) {
14452                list.add(new Intent(intent));
14453            }
14454        }
14455
14456        int[] users;
14457        if (userId == UserHandle.USER_ALL) {
14458            // Caller wants broadcast to go to all started users.
14459            users = mStartedUserArray;
14460        } else {
14461            // Caller wants broadcast to go to one specific user.
14462            users = new int[] {userId};
14463        }
14464
14465        // Figure out who all will receive this broadcast.
14466        List receivers = null;
14467        List<BroadcastFilter> registeredReceivers = null;
14468        // Need to resolve the intent to interested receivers...
14469        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14470                 == 0) {
14471            receivers = collectReceiverComponents(intent, resolvedType, users);
14472        }
14473        if (intent.getComponent() == null) {
14474            registeredReceivers = mReceiverResolver.queryIntent(intent,
14475                    resolvedType, false, userId);
14476        }
14477
14478        final boolean replacePending =
14479                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14480
14481        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14482                + " replacePending=" + replacePending);
14483
14484        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14485        if (!ordered && NR > 0) {
14486            // If we are not serializing this broadcast, then send the
14487            // registered receivers separately so they don't wait for the
14488            // components to be launched.
14489            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14490            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14491                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14492                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14493                    ordered, sticky, false, userId);
14494            if (DEBUG_BROADCAST) Slog.v(
14495                    TAG, "Enqueueing parallel broadcast " + r);
14496            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14497            if (!replaced) {
14498                queue.enqueueParallelBroadcastLocked(r);
14499                queue.scheduleBroadcastsLocked();
14500            }
14501            registeredReceivers = null;
14502            NR = 0;
14503        }
14504
14505        // Merge into one list.
14506        int ir = 0;
14507        if (receivers != null) {
14508            // A special case for PACKAGE_ADDED: do not allow the package
14509            // being added to see this broadcast.  This prevents them from
14510            // using this as a back door to get run as soon as they are
14511            // installed.  Maybe in the future we want to have a special install
14512            // broadcast or such for apps, but we'd like to deliberately make
14513            // this decision.
14514            String skipPackages[] = null;
14515            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14516                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14517                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14518                Uri data = intent.getData();
14519                if (data != null) {
14520                    String pkgName = data.getSchemeSpecificPart();
14521                    if (pkgName != null) {
14522                        skipPackages = new String[] { pkgName };
14523                    }
14524                }
14525            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14526                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14527            }
14528            if (skipPackages != null && (skipPackages.length > 0)) {
14529                for (String skipPackage : skipPackages) {
14530                    if (skipPackage != null) {
14531                        int NT = receivers.size();
14532                        for (int it=0; it<NT; it++) {
14533                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14534                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14535                                receivers.remove(it);
14536                                it--;
14537                                NT--;
14538                            }
14539                        }
14540                    }
14541                }
14542            }
14543
14544            int NT = receivers != null ? receivers.size() : 0;
14545            int it = 0;
14546            ResolveInfo curt = null;
14547            BroadcastFilter curr = null;
14548            while (it < NT && ir < NR) {
14549                if (curt == null) {
14550                    curt = (ResolveInfo)receivers.get(it);
14551                }
14552                if (curr == null) {
14553                    curr = registeredReceivers.get(ir);
14554                }
14555                if (curr.getPriority() >= curt.priority) {
14556                    // Insert this broadcast record into the final list.
14557                    receivers.add(it, curr);
14558                    ir++;
14559                    curr = null;
14560                    it++;
14561                    NT++;
14562                } else {
14563                    // Skip to the next ResolveInfo in the final list.
14564                    it++;
14565                    curt = null;
14566                }
14567            }
14568        }
14569        while (ir < NR) {
14570            if (receivers == null) {
14571                receivers = new ArrayList();
14572            }
14573            receivers.add(registeredReceivers.get(ir));
14574            ir++;
14575        }
14576
14577        if ((receivers != null && receivers.size() > 0)
14578                || resultTo != null) {
14579            BroadcastQueue queue = broadcastQueueForIntent(intent);
14580            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14581                    callerPackage, callingPid, callingUid, resolvedType,
14582                    requiredPermission, appOp, receivers, resultTo, resultCode,
14583                    resultData, map, ordered, sticky, false, userId);
14584            if (DEBUG_BROADCAST) Slog.v(
14585                    TAG, "Enqueueing ordered broadcast " + r
14586                    + ": prev had " + queue.mOrderedBroadcasts.size());
14587            if (DEBUG_BROADCAST) {
14588                int seq = r.intent.getIntExtra("seq", -1);
14589                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14590            }
14591            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14592            if (!replaced) {
14593                queue.enqueueOrderedBroadcastLocked(r);
14594                queue.scheduleBroadcastsLocked();
14595            }
14596        }
14597
14598        return ActivityManager.BROADCAST_SUCCESS;
14599    }
14600
14601    final Intent verifyBroadcastLocked(Intent intent) {
14602        // Refuse possible leaked file descriptors
14603        if (intent != null && intent.hasFileDescriptors() == true) {
14604            throw new IllegalArgumentException("File descriptors passed in Intent");
14605        }
14606
14607        int flags = intent.getFlags();
14608
14609        if (!mProcessesReady) {
14610            // if the caller really truly claims to know what they're doing, go
14611            // ahead and allow the broadcast without launching any receivers
14612            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14613                intent = new Intent(intent);
14614                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14615            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14616                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14617                        + " before boot completion");
14618                throw new IllegalStateException("Cannot broadcast before boot completed");
14619            }
14620        }
14621
14622        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14623            throw new IllegalArgumentException(
14624                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14625        }
14626
14627        return intent;
14628    }
14629
14630    public final int broadcastIntent(IApplicationThread caller,
14631            Intent intent, String resolvedType, IIntentReceiver resultTo,
14632            int resultCode, String resultData, Bundle map,
14633            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14634        enforceNotIsolatedCaller("broadcastIntent");
14635        synchronized(this) {
14636            intent = verifyBroadcastLocked(intent);
14637
14638            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14639            final int callingPid = Binder.getCallingPid();
14640            final int callingUid = Binder.getCallingUid();
14641            final long origId = Binder.clearCallingIdentity();
14642            int res = broadcastIntentLocked(callerApp,
14643                    callerApp != null ? callerApp.info.packageName : null,
14644                    intent, resolvedType, resultTo,
14645                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14646                    callingPid, callingUid, userId);
14647            Binder.restoreCallingIdentity(origId);
14648            return res;
14649        }
14650    }
14651
14652    int broadcastIntentInPackage(String packageName, int uid,
14653            Intent intent, String resolvedType, IIntentReceiver resultTo,
14654            int resultCode, String resultData, Bundle map,
14655            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14656        synchronized(this) {
14657            intent = verifyBroadcastLocked(intent);
14658
14659            final long origId = Binder.clearCallingIdentity();
14660            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14661                    resultTo, resultCode, resultData, map, requiredPermission,
14662                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14663            Binder.restoreCallingIdentity(origId);
14664            return res;
14665        }
14666    }
14667
14668    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14669        // Refuse possible leaked file descriptors
14670        if (intent != null && intent.hasFileDescriptors() == true) {
14671            throw new IllegalArgumentException("File descriptors passed in Intent");
14672        }
14673
14674        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14675                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
14676
14677        synchronized(this) {
14678            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14679                    != PackageManager.PERMISSION_GRANTED) {
14680                String msg = "Permission Denial: unbroadcastIntent() from pid="
14681                        + Binder.getCallingPid()
14682                        + ", uid=" + Binder.getCallingUid()
14683                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14684                Slog.w(TAG, msg);
14685                throw new SecurityException(msg);
14686            }
14687            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14688            if (stickies != null) {
14689                ArrayList<Intent> list = stickies.get(intent.getAction());
14690                if (list != null) {
14691                    int N = list.size();
14692                    int i;
14693                    for (i=0; i<N; i++) {
14694                        if (intent.filterEquals(list.get(i))) {
14695                            list.remove(i);
14696                            break;
14697                        }
14698                    }
14699                    if (list.size() <= 0) {
14700                        stickies.remove(intent.getAction());
14701                    }
14702                }
14703                if (stickies.size() <= 0) {
14704                    mStickyBroadcasts.remove(userId);
14705                }
14706            }
14707        }
14708    }
14709
14710    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14711            String resultData, Bundle resultExtras, boolean resultAbort) {
14712        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14713        if (r == null) {
14714            Slog.w(TAG, "finishReceiver called but not found on queue");
14715            return false;
14716        }
14717
14718        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14719    }
14720
14721    void backgroundServicesFinishedLocked(int userId) {
14722        for (BroadcastQueue queue : mBroadcastQueues) {
14723            queue.backgroundServicesFinishedLocked(userId);
14724        }
14725    }
14726
14727    public void finishReceiver(IBinder who, int resultCode, String resultData,
14728            Bundle resultExtras, boolean resultAbort) {
14729        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14730
14731        // Refuse possible leaked file descriptors
14732        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14733            throw new IllegalArgumentException("File descriptors passed in Bundle");
14734        }
14735
14736        final long origId = Binder.clearCallingIdentity();
14737        try {
14738            boolean doNext = false;
14739            BroadcastRecord r;
14740
14741            synchronized(this) {
14742                r = broadcastRecordForReceiverLocked(who);
14743                if (r != null) {
14744                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14745                        resultData, resultExtras, resultAbort, true);
14746                }
14747            }
14748
14749            if (doNext) {
14750                r.queue.processNextBroadcast(false);
14751            }
14752            trimApplications();
14753        } finally {
14754            Binder.restoreCallingIdentity(origId);
14755        }
14756    }
14757
14758    // =========================================================
14759    // INSTRUMENTATION
14760    // =========================================================
14761
14762    public boolean startInstrumentation(ComponentName className,
14763            String profileFile, int flags, Bundle arguments,
14764            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14765            int userId, String abiOverride) {
14766        enforceNotIsolatedCaller("startInstrumentation");
14767        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14768                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
14769        // Refuse possible leaked file descriptors
14770        if (arguments != null && arguments.hasFileDescriptors()) {
14771            throw new IllegalArgumentException("File descriptors passed in Bundle");
14772        }
14773
14774        synchronized(this) {
14775            InstrumentationInfo ii = null;
14776            ApplicationInfo ai = null;
14777            try {
14778                ii = mContext.getPackageManager().getInstrumentationInfo(
14779                    className, STOCK_PM_FLAGS);
14780                ai = AppGlobals.getPackageManager().getApplicationInfo(
14781                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14782            } catch (PackageManager.NameNotFoundException e) {
14783            } catch (RemoteException e) {
14784            }
14785            if (ii == null) {
14786                reportStartInstrumentationFailure(watcher, className,
14787                        "Unable to find instrumentation info for: " + className);
14788                return false;
14789            }
14790            if (ai == null) {
14791                reportStartInstrumentationFailure(watcher, className,
14792                        "Unable to find instrumentation target package: " + ii.targetPackage);
14793                return false;
14794            }
14795
14796            int match = mContext.getPackageManager().checkSignatures(
14797                    ii.targetPackage, ii.packageName);
14798            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14799                String msg = "Permission Denial: starting instrumentation "
14800                        + className + " from pid="
14801                        + Binder.getCallingPid()
14802                        + ", uid=" + Binder.getCallingPid()
14803                        + " not allowed because package " + ii.packageName
14804                        + " does not have a signature matching the target "
14805                        + ii.targetPackage;
14806                reportStartInstrumentationFailure(watcher, className, msg);
14807                throw new SecurityException(msg);
14808            }
14809
14810            final long origId = Binder.clearCallingIdentity();
14811            // Instrumentation can kill and relaunch even persistent processes
14812            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14813                    "start instr");
14814            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14815            app.instrumentationClass = className;
14816            app.instrumentationInfo = ai;
14817            app.instrumentationProfileFile = profileFile;
14818            app.instrumentationArguments = arguments;
14819            app.instrumentationWatcher = watcher;
14820            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14821            app.instrumentationResultClass = className;
14822            Binder.restoreCallingIdentity(origId);
14823        }
14824
14825        return true;
14826    }
14827
14828    /**
14829     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14830     * error to the logs, but if somebody is watching, send the report there too.  This enables
14831     * the "am" command to report errors with more information.
14832     *
14833     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14834     * @param cn The component name of the instrumentation.
14835     * @param report The error report.
14836     */
14837    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14838            ComponentName cn, String report) {
14839        Slog.w(TAG, report);
14840        try {
14841            if (watcher != null) {
14842                Bundle results = new Bundle();
14843                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14844                results.putString("Error", report);
14845                watcher.instrumentationStatus(cn, -1, results);
14846            }
14847        } catch (RemoteException e) {
14848            Slog.w(TAG, e);
14849        }
14850    }
14851
14852    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14853        if (app.instrumentationWatcher != null) {
14854            try {
14855                // NOTE:  IInstrumentationWatcher *must* be oneway here
14856                app.instrumentationWatcher.instrumentationFinished(
14857                    app.instrumentationClass,
14858                    resultCode,
14859                    results);
14860            } catch (RemoteException e) {
14861            }
14862        }
14863        if (app.instrumentationUiAutomationConnection != null) {
14864            try {
14865                app.instrumentationUiAutomationConnection.shutdown();
14866            } catch (RemoteException re) {
14867                /* ignore */
14868            }
14869            // Only a UiAutomation can set this flag and now that
14870            // it is finished we make sure it is reset to its default.
14871            mUserIsMonkey = false;
14872        }
14873        app.instrumentationWatcher = null;
14874        app.instrumentationUiAutomationConnection = null;
14875        app.instrumentationClass = null;
14876        app.instrumentationInfo = null;
14877        app.instrumentationProfileFile = null;
14878        app.instrumentationArguments = null;
14879
14880        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14881                "finished inst");
14882    }
14883
14884    public void finishInstrumentation(IApplicationThread target,
14885            int resultCode, Bundle results) {
14886        int userId = UserHandle.getCallingUserId();
14887        // Refuse possible leaked file descriptors
14888        if (results != null && results.hasFileDescriptors()) {
14889            throw new IllegalArgumentException("File descriptors passed in Intent");
14890        }
14891
14892        synchronized(this) {
14893            ProcessRecord app = getRecordForAppLocked(target);
14894            if (app == null) {
14895                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14896                return;
14897            }
14898            final long origId = Binder.clearCallingIdentity();
14899            finishInstrumentationLocked(app, resultCode, results);
14900            Binder.restoreCallingIdentity(origId);
14901        }
14902    }
14903
14904    // =========================================================
14905    // CONFIGURATION
14906    // =========================================================
14907
14908    public ConfigurationInfo getDeviceConfigurationInfo() {
14909        ConfigurationInfo config = new ConfigurationInfo();
14910        synchronized (this) {
14911            config.reqTouchScreen = mConfiguration.touchscreen;
14912            config.reqKeyboardType = mConfiguration.keyboard;
14913            config.reqNavigation = mConfiguration.navigation;
14914            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14915                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14916                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14917            }
14918            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14919                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14920                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14921            }
14922            config.reqGlEsVersion = GL_ES_VERSION;
14923        }
14924        return config;
14925    }
14926
14927    ActivityStack getFocusedStack() {
14928        return mStackSupervisor.getFocusedStack();
14929    }
14930
14931    public Configuration getConfiguration() {
14932        Configuration ci;
14933        synchronized(this) {
14934            ci = new Configuration(mConfiguration);
14935        }
14936        return ci;
14937    }
14938
14939    public void updatePersistentConfiguration(Configuration values) {
14940        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14941                "updateConfiguration()");
14942        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14943                "updateConfiguration()");
14944        if (values == null) {
14945            throw new NullPointerException("Configuration must not be null");
14946        }
14947
14948        synchronized(this) {
14949            final long origId = Binder.clearCallingIdentity();
14950            updateConfigurationLocked(values, null, true, false);
14951            Binder.restoreCallingIdentity(origId);
14952        }
14953    }
14954
14955    public void updateConfiguration(Configuration values) {
14956        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14957                "updateConfiguration()");
14958
14959        synchronized(this) {
14960            if (values == null && mWindowManager != null) {
14961                // sentinel: fetch the current configuration from the window manager
14962                values = mWindowManager.computeNewConfiguration();
14963            }
14964
14965            if (mWindowManager != null) {
14966                mProcessList.applyDisplaySize(mWindowManager);
14967            }
14968
14969            final long origId = Binder.clearCallingIdentity();
14970            if (values != null) {
14971                Settings.System.clearConfiguration(values);
14972            }
14973            updateConfigurationLocked(values, null, false, false);
14974            Binder.restoreCallingIdentity(origId);
14975        }
14976    }
14977
14978    /**
14979     * Do either or both things: (1) change the current configuration, and (2)
14980     * make sure the given activity is running with the (now) current
14981     * configuration.  Returns true if the activity has been left running, or
14982     * false if <var>starting</var> is being destroyed to match the new
14983     * configuration.
14984     * @param persistent TODO
14985     */
14986    boolean updateConfigurationLocked(Configuration values,
14987            ActivityRecord starting, boolean persistent, boolean initLocale) {
14988        int changes = 0;
14989
14990        if (values != null) {
14991            Configuration newConfig = new Configuration(mConfiguration);
14992            changes = newConfig.updateFrom(values);
14993            if (changes != 0) {
14994                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14995                    Slog.i(TAG, "Updating configuration to: " + values);
14996                }
14997
14998                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14999
15000                if (values.locale != null && !initLocale) {
15001                    saveLocaleLocked(values.locale,
15002                                     !values.locale.equals(mConfiguration.locale),
15003                                     values.userSetLocale);
15004                }
15005
15006                mConfigurationSeq++;
15007                if (mConfigurationSeq <= 0) {
15008                    mConfigurationSeq = 1;
15009                }
15010                newConfig.seq = mConfigurationSeq;
15011                mConfiguration = newConfig;
15012                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15013                mUsageStatsService.noteStartConfig(newConfig);
15014
15015                final Configuration configCopy = new Configuration(mConfiguration);
15016
15017                // TODO: If our config changes, should we auto dismiss any currently
15018                // showing dialogs?
15019                mShowDialogs = shouldShowDialogs(newConfig);
15020
15021                AttributeCache ac = AttributeCache.instance();
15022                if (ac != null) {
15023                    ac.updateConfiguration(configCopy);
15024                }
15025
15026                // Make sure all resources in our process are updated
15027                // right now, so that anyone who is going to retrieve
15028                // resource values after we return will be sure to get
15029                // the new ones.  This is especially important during
15030                // boot, where the first config change needs to guarantee
15031                // all resources have that config before following boot
15032                // code is executed.
15033                mSystemThread.applyConfigurationToResources(configCopy);
15034
15035                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15036                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15037                    msg.obj = new Configuration(configCopy);
15038                    mHandler.sendMessage(msg);
15039                }
15040
15041                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15042                    ProcessRecord app = mLruProcesses.get(i);
15043                    try {
15044                        if (app.thread != null) {
15045                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15046                                    + app.processName + " new config " + mConfiguration);
15047                            app.thread.scheduleConfigurationChanged(configCopy);
15048                        }
15049                    } catch (Exception e) {
15050                    }
15051                }
15052                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15053                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15054                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15055                        | Intent.FLAG_RECEIVER_FOREGROUND);
15056                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15057                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15058                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15059                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15060                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15061                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15062                    broadcastIntentLocked(null, null, intent,
15063                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15064                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15065                }
15066            }
15067        }
15068
15069        boolean kept = true;
15070        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15071        // mainStack is null during startup.
15072        if (mainStack != null) {
15073            if (changes != 0 && starting == null) {
15074                // If the configuration changed, and the caller is not already
15075                // in the process of starting an activity, then find the top
15076                // activity to check if its configuration needs to change.
15077                starting = mainStack.topRunningActivityLocked(null);
15078            }
15079
15080            if (starting != null) {
15081                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15082                // And we need to make sure at this point that all other activities
15083                // are made visible with the correct configuration.
15084                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15085            }
15086        }
15087
15088        if (values != null && mWindowManager != null) {
15089            mWindowManager.setNewConfiguration(mConfiguration);
15090        }
15091
15092        return kept;
15093    }
15094
15095    /**
15096     * Decide based on the configuration whether we should shouw the ANR,
15097     * crash, etc dialogs.  The idea is that if there is no affordnace to
15098     * press the on-screen buttons, we shouldn't show the dialog.
15099     *
15100     * A thought: SystemUI might also want to get told about this, the Power
15101     * dialog / global actions also might want different behaviors.
15102     */
15103    private static final boolean shouldShowDialogs(Configuration config) {
15104        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15105                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15106    }
15107
15108    /**
15109     * Save the locale.  You must be inside a synchronized (this) block.
15110     */
15111    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15112        if(isDiff) {
15113            SystemProperties.set("user.language", l.getLanguage());
15114            SystemProperties.set("user.region", l.getCountry());
15115        }
15116
15117        if(isPersist) {
15118            SystemProperties.set("persist.sys.language", l.getLanguage());
15119            SystemProperties.set("persist.sys.country", l.getCountry());
15120            SystemProperties.set("persist.sys.localevar", l.getVariant());
15121        }
15122    }
15123
15124    @Override
15125    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
15126        ActivityRecord srec = ActivityRecord.forToken(token);
15127        return srec != null && srec.task.affinity != null &&
15128                srec.task.affinity.equals(destAffinity);
15129    }
15130
15131    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15132            Intent resultData) {
15133
15134        synchronized (this) {
15135            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15136            if (stack != null) {
15137                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15138            }
15139            return false;
15140        }
15141    }
15142
15143    public int getLaunchedFromUid(IBinder activityToken) {
15144        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15145        if (srec == null) {
15146            return -1;
15147        }
15148        return srec.launchedFromUid;
15149    }
15150
15151    public String getLaunchedFromPackage(IBinder activityToken) {
15152        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15153        if (srec == null) {
15154            return null;
15155        }
15156        return srec.launchedFromPackage;
15157    }
15158
15159    // =========================================================
15160    // LIFETIME MANAGEMENT
15161    // =========================================================
15162
15163    // Returns which broadcast queue the app is the current [or imminent] receiver
15164    // on, or 'null' if the app is not an active broadcast recipient.
15165    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
15166        BroadcastRecord r = app.curReceiver;
15167        if (r != null) {
15168            return r.queue;
15169        }
15170
15171        // It's not the current receiver, but it might be starting up to become one
15172        synchronized (this) {
15173            for (BroadcastQueue queue : mBroadcastQueues) {
15174                r = queue.mPendingBroadcast;
15175                if (r != null && r.curApp == app) {
15176                    // found it; report which queue it's in
15177                    return queue;
15178                }
15179            }
15180        }
15181
15182        return null;
15183    }
15184
15185    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
15186            boolean doingAll, long now) {
15187        if (mAdjSeq == app.adjSeq) {
15188            // This adjustment has already been computed.
15189            return app.curRawAdj;
15190        }
15191
15192        if (app.thread == null) {
15193            app.adjSeq = mAdjSeq;
15194            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15195            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15196            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
15197        }
15198
15199        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
15200        app.adjSource = null;
15201        app.adjTarget = null;
15202        app.empty = false;
15203        app.cached = false;
15204
15205        final int activitiesSize = app.activities.size();
15206
15207        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15208            // The max adjustment doesn't allow this app to be anything
15209            // below foreground, so it is not worth doing work for it.
15210            app.adjType = "fixed";
15211            app.adjSeq = mAdjSeq;
15212            app.curRawAdj = app.maxAdj;
15213            app.foregroundActivities = false;
15214            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
15215            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
15216            // System processes can do UI, and when they do we want to have
15217            // them trim their memory after the user leaves the UI.  To
15218            // facilitate this, here we need to determine whether or not it
15219            // is currently showing UI.
15220            app.systemNoUi = true;
15221            if (app == TOP_APP) {
15222                app.systemNoUi = false;
15223            } else if (activitiesSize > 0) {
15224                for (int j = 0; j < activitiesSize; j++) {
15225                    final ActivityRecord r = app.activities.get(j);
15226                    if (r.visible) {
15227                        app.systemNoUi = false;
15228                    }
15229                }
15230            }
15231            if (!app.systemNoUi) {
15232                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15233            }
15234            return (app.curAdj=app.maxAdj);
15235        }
15236
15237        app.systemNoUi = false;
15238
15239        // Determine the importance of the process, starting with most
15240        // important to least, and assign an appropriate OOM adjustment.
15241        int adj;
15242        int schedGroup;
15243        int procState;
15244        boolean foregroundActivities = false;
15245        BroadcastQueue queue;
15246        if (app == TOP_APP) {
15247            // The last app on the list is the foreground app.
15248            adj = ProcessList.FOREGROUND_APP_ADJ;
15249            schedGroup = Process.THREAD_GROUP_DEFAULT;
15250            app.adjType = "top-activity";
15251            foregroundActivities = true;
15252            procState = ActivityManager.PROCESS_STATE_TOP;
15253        } else if (app.instrumentationClass != null) {
15254            // Don't want to kill running instrumentation.
15255            adj = ProcessList.FOREGROUND_APP_ADJ;
15256            schedGroup = Process.THREAD_GROUP_DEFAULT;
15257            app.adjType = "instrumentation";
15258            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15259        } else if ((queue = isReceivingBroadcast(app)) != null) {
15260            // An app that is currently receiving a broadcast also
15261            // counts as being in the foreground for OOM killer purposes.
15262            // It's placed in a sched group based on the nature of the
15263            // broadcast as reflected by which queue it's active in.
15264            adj = ProcessList.FOREGROUND_APP_ADJ;
15265            schedGroup = (queue == mFgBroadcastQueue)
15266                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15267            app.adjType = "broadcast";
15268            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15269        } else if (app.executingServices.size() > 0) {
15270            // An app that is currently executing a service callback also
15271            // counts as being in the foreground.
15272            adj = ProcessList.FOREGROUND_APP_ADJ;
15273            schedGroup = app.execServicesFg ?
15274                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15275            app.adjType = "exec-service";
15276            procState = ActivityManager.PROCESS_STATE_SERVICE;
15277            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15278        } else {
15279            // As far as we know the process is empty.  We may change our mind later.
15280            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15281            // At this point we don't actually know the adjustment.  Use the cached adj
15282            // value that the caller wants us to.
15283            adj = cachedAdj;
15284            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15285            app.cached = true;
15286            app.empty = true;
15287            app.adjType = "cch-empty";
15288        }
15289
15290        // Examine all activities if not already foreground.
15291        if (!foregroundActivities && activitiesSize > 0) {
15292            for (int j = 0; j < activitiesSize; j++) {
15293                final ActivityRecord r = app.activities.get(j);
15294                if (r.app != app) {
15295                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15296                            + app + "?!?");
15297                    continue;
15298                }
15299                if (r.visible) {
15300                    // App has a visible activity; only upgrade adjustment.
15301                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15302                        adj = ProcessList.VISIBLE_APP_ADJ;
15303                        app.adjType = "visible";
15304                    }
15305                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15306                        procState = ActivityManager.PROCESS_STATE_TOP;
15307                    }
15308                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15309                    app.cached = false;
15310                    app.empty = false;
15311                    foregroundActivities = true;
15312                    break;
15313                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15314                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15315                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15316                        app.adjType = "pausing";
15317                    }
15318                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15319                        procState = ActivityManager.PROCESS_STATE_TOP;
15320                    }
15321                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15322                    app.cached = false;
15323                    app.empty = false;
15324                    foregroundActivities = true;
15325                } else if (r.state == ActivityState.STOPPING) {
15326                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15327                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15328                        app.adjType = "stopping";
15329                    }
15330                    // For the process state, we will at this point consider the
15331                    // process to be cached.  It will be cached either as an activity
15332                    // or empty depending on whether the activity is finishing.  We do
15333                    // this so that we can treat the process as cached for purposes of
15334                    // memory trimming (determing current memory level, trim command to
15335                    // send to process) since there can be an arbitrary number of stopping
15336                    // processes and they should soon all go into the cached state.
15337                    if (!r.finishing) {
15338                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15339                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15340                        }
15341                    }
15342                    app.cached = false;
15343                    app.empty = false;
15344                    foregroundActivities = true;
15345                } else {
15346                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15347                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15348                        app.adjType = "cch-act";
15349                    }
15350                }
15351            }
15352        }
15353
15354        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15355            if (app.foregroundServices) {
15356                // The user is aware of this app, so make it visible.
15357                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15358                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15359                app.cached = false;
15360                app.adjType = "fg-service";
15361                schedGroup = Process.THREAD_GROUP_DEFAULT;
15362            } else if (app.forcingToForeground != null) {
15363                // The user is aware of this app, so make it visible.
15364                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15365                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15366                app.cached = false;
15367                app.adjType = "force-fg";
15368                app.adjSource = app.forcingToForeground;
15369                schedGroup = Process.THREAD_GROUP_DEFAULT;
15370            }
15371        }
15372
15373        if (app == mHeavyWeightProcess) {
15374            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15375                // We don't want to kill the current heavy-weight process.
15376                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15377                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15378                app.cached = false;
15379                app.adjType = "heavy";
15380            }
15381            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15382                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15383            }
15384        }
15385
15386        if (app == mHomeProcess) {
15387            if (adj > ProcessList.HOME_APP_ADJ) {
15388                // This process is hosting what we currently consider to be the
15389                // home app, so we don't want to let it go into the background.
15390                adj = ProcessList.HOME_APP_ADJ;
15391                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15392                app.cached = false;
15393                app.adjType = "home";
15394            }
15395            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15396                procState = ActivityManager.PROCESS_STATE_HOME;
15397            }
15398        }
15399
15400        if (app == mPreviousProcess && app.activities.size() > 0) {
15401            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15402                // This was the previous process that showed UI to the user.
15403                // We want to try to keep it around more aggressively, to give
15404                // a good experience around switching between two apps.
15405                adj = ProcessList.PREVIOUS_APP_ADJ;
15406                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15407                app.cached = false;
15408                app.adjType = "previous";
15409            }
15410            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15411                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15412            }
15413        }
15414
15415        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15416                + " reason=" + app.adjType);
15417
15418        // By default, we use the computed adjustment.  It may be changed if
15419        // there are applications dependent on our services or providers, but
15420        // this gives us a baseline and makes sure we don't get into an
15421        // infinite recursion.
15422        app.adjSeq = mAdjSeq;
15423        app.curRawAdj = adj;
15424        app.hasStartedServices = false;
15425
15426        if (mBackupTarget != null && app == mBackupTarget.app) {
15427            // If possible we want to avoid killing apps while they're being backed up
15428            if (adj > ProcessList.BACKUP_APP_ADJ) {
15429                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15430                adj = ProcessList.BACKUP_APP_ADJ;
15431                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15432                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15433                }
15434                app.adjType = "backup";
15435                app.cached = false;
15436            }
15437            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15438                procState = ActivityManager.PROCESS_STATE_BACKUP;
15439            }
15440        }
15441
15442        boolean mayBeTop = false;
15443
15444        for (int is = app.services.size()-1;
15445                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15446                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15447                        || procState > ActivityManager.PROCESS_STATE_TOP);
15448                is--) {
15449            ServiceRecord s = app.services.valueAt(is);
15450            if (s.startRequested) {
15451                app.hasStartedServices = true;
15452                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15453                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15454                }
15455                if (app.hasShownUi && app != mHomeProcess) {
15456                    // If this process has shown some UI, let it immediately
15457                    // go to the LRU list because it may be pretty heavy with
15458                    // UI stuff.  We'll tag it with a label just to help
15459                    // debug and understand what is going on.
15460                    if (adj > ProcessList.SERVICE_ADJ) {
15461                        app.adjType = "cch-started-ui-services";
15462                    }
15463                } else {
15464                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15465                        // This service has seen some activity within
15466                        // recent memory, so we will keep its process ahead
15467                        // of the background processes.
15468                        if (adj > ProcessList.SERVICE_ADJ) {
15469                            adj = ProcessList.SERVICE_ADJ;
15470                            app.adjType = "started-services";
15471                            app.cached = false;
15472                        }
15473                    }
15474                    // If we have let the service slide into the background
15475                    // state, still have some text describing what it is doing
15476                    // even though the service no longer has an impact.
15477                    if (adj > ProcessList.SERVICE_ADJ) {
15478                        app.adjType = "cch-started-services";
15479                    }
15480                }
15481            }
15482            for (int conni = s.connections.size()-1;
15483                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15484                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15485                            || procState > ActivityManager.PROCESS_STATE_TOP);
15486                    conni--) {
15487                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15488                for (int i = 0;
15489                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15490                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15491                                || procState > ActivityManager.PROCESS_STATE_TOP);
15492                        i++) {
15493                    // XXX should compute this based on the max of
15494                    // all connected clients.
15495                    ConnectionRecord cr = clist.get(i);
15496                    if (cr.binding.client == app) {
15497                        // Binding to ourself is not interesting.
15498                        continue;
15499                    }
15500                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15501                        ProcessRecord client = cr.binding.client;
15502                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15503                                TOP_APP, doingAll, now);
15504                        int clientProcState = client.curProcState;
15505                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15506                            // If the other app is cached for any reason, for purposes here
15507                            // we are going to consider it empty.  The specific cached state
15508                            // doesn't propagate except under certain conditions.
15509                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15510                        }
15511                        String adjType = null;
15512                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15513                            // Not doing bind OOM management, so treat
15514                            // this guy more like a started service.
15515                            if (app.hasShownUi && app != mHomeProcess) {
15516                                // If this process has shown some UI, let it immediately
15517                                // go to the LRU list because it may be pretty heavy with
15518                                // UI stuff.  We'll tag it with a label just to help
15519                                // debug and understand what is going on.
15520                                if (adj > clientAdj) {
15521                                    adjType = "cch-bound-ui-services";
15522                                }
15523                                app.cached = false;
15524                                clientAdj = adj;
15525                                clientProcState = procState;
15526                            } else {
15527                                if (now >= (s.lastActivity
15528                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15529                                    // This service has not seen activity within
15530                                    // recent memory, so allow it to drop to the
15531                                    // LRU list if there is no other reason to keep
15532                                    // it around.  We'll also tag it with a label just
15533                                    // to help debug and undertand what is going on.
15534                                    if (adj > clientAdj) {
15535                                        adjType = "cch-bound-services";
15536                                    }
15537                                    clientAdj = adj;
15538                                }
15539                            }
15540                        }
15541                        if (adj > clientAdj) {
15542                            // If this process has recently shown UI, and
15543                            // the process that is binding to it is less
15544                            // important than being visible, then we don't
15545                            // care about the binding as much as we care
15546                            // about letting this process get into the LRU
15547                            // list to be killed and restarted if needed for
15548                            // memory.
15549                            if (app.hasShownUi && app != mHomeProcess
15550                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15551                                adjType = "cch-bound-ui-services";
15552                            } else {
15553                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15554                                        |Context.BIND_IMPORTANT)) != 0) {
15555                                    adj = clientAdj;
15556                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15557                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15558                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15559                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15560                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15561                                    adj = clientAdj;
15562                                } else {
15563                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15564                                        adj = ProcessList.VISIBLE_APP_ADJ;
15565                                    }
15566                                }
15567                                if (!client.cached) {
15568                                    app.cached = false;
15569                                }
15570                                adjType = "service";
15571                            }
15572                        }
15573                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15574                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15575                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15576                            }
15577                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15578                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15579                                    // Special handling of clients who are in the top state.
15580                                    // We *may* want to consider this process to be in the
15581                                    // top state as well, but only if there is not another
15582                                    // reason for it to be running.  Being on the top is a
15583                                    // special state, meaning you are specifically running
15584                                    // for the current top app.  If the process is already
15585                                    // running in the background for some other reason, it
15586                                    // is more important to continue considering it to be
15587                                    // in the background state.
15588                                    mayBeTop = true;
15589                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15590                                } else {
15591                                    // Special handling for above-top states (persistent
15592                                    // processes).  These should not bring the current process
15593                                    // into the top state, since they are not on top.  Instead
15594                                    // give them the best state after that.
15595                                    clientProcState =
15596                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15597                                }
15598                            }
15599                        } else {
15600                            if (clientProcState <
15601                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15602                                clientProcState =
15603                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15604                            }
15605                        }
15606                        if (procState > clientProcState) {
15607                            procState = clientProcState;
15608                        }
15609                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15610                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15611                            app.pendingUiClean = true;
15612                        }
15613                        if (adjType != null) {
15614                            app.adjType = adjType;
15615                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15616                                    .REASON_SERVICE_IN_USE;
15617                            app.adjSource = cr.binding.client;
15618                            app.adjSourceOom = clientAdj;
15619                            app.adjTarget = s.name;
15620                        }
15621                    }
15622                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15623                        app.treatLikeActivity = true;
15624                    }
15625                    final ActivityRecord a = cr.activity;
15626                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15627                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15628                                (a.visible || a.state == ActivityState.RESUMED
15629                                 || a.state == ActivityState.PAUSING)) {
15630                            adj = ProcessList.FOREGROUND_APP_ADJ;
15631                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15632                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15633                            }
15634                            app.cached = false;
15635                            app.adjType = "service";
15636                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15637                                    .REASON_SERVICE_IN_USE;
15638                            app.adjSource = a;
15639                            app.adjSourceOom = adj;
15640                            app.adjTarget = s.name;
15641                        }
15642                    }
15643                }
15644            }
15645        }
15646
15647        for (int provi = app.pubProviders.size()-1;
15648                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15649                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15650                        || procState > ActivityManager.PROCESS_STATE_TOP);
15651                provi--) {
15652            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15653            for (int i = cpr.connections.size()-1;
15654                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15655                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15656                            || procState > ActivityManager.PROCESS_STATE_TOP);
15657                    i--) {
15658                ContentProviderConnection conn = cpr.connections.get(i);
15659                ProcessRecord client = conn.client;
15660                if (client == app) {
15661                    // Being our own client is not interesting.
15662                    continue;
15663                }
15664                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15665                int clientProcState = client.curProcState;
15666                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15667                    // If the other app is cached for any reason, for purposes here
15668                    // we are going to consider it empty.
15669                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15670                }
15671                if (adj > clientAdj) {
15672                    if (app.hasShownUi && app != mHomeProcess
15673                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15674                        app.adjType = "cch-ui-provider";
15675                    } else {
15676                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15677                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15678                        app.adjType = "provider";
15679                    }
15680                    app.cached &= client.cached;
15681                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15682                            .REASON_PROVIDER_IN_USE;
15683                    app.adjSource = client;
15684                    app.adjSourceOom = clientAdj;
15685                    app.adjTarget = cpr.name;
15686                }
15687                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15688                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15689                        // Special handling of clients who are in the top state.
15690                        // We *may* want to consider this process to be in the
15691                        // top state as well, but only if there is not another
15692                        // reason for it to be running.  Being on the top is a
15693                        // special state, meaning you are specifically running
15694                        // for the current top app.  If the process is already
15695                        // running in the background for some other reason, it
15696                        // is more important to continue considering it to be
15697                        // in the background state.
15698                        mayBeTop = true;
15699                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15700                    } else {
15701                        // Special handling for above-top states (persistent
15702                        // processes).  These should not bring the current process
15703                        // into the top state, since they are not on top.  Instead
15704                        // give them the best state after that.
15705                        clientProcState =
15706                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15707                    }
15708                }
15709                if (procState > clientProcState) {
15710                    procState = clientProcState;
15711                }
15712                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15713                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15714                }
15715            }
15716            // If the provider has external (non-framework) process
15717            // dependencies, ensure that its adjustment is at least
15718            // FOREGROUND_APP_ADJ.
15719            if (cpr.hasExternalProcessHandles()) {
15720                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15721                    adj = ProcessList.FOREGROUND_APP_ADJ;
15722                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15723                    app.cached = false;
15724                    app.adjType = "provider";
15725                    app.adjTarget = cpr.name;
15726                }
15727                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15728                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15729                }
15730            }
15731        }
15732
15733        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15734            // A client of one of our services or providers is in the top state.  We
15735            // *may* want to be in the top state, but not if we are already running in
15736            // the background for some other reason.  For the decision here, we are going
15737            // to pick out a few specific states that we want to remain in when a client
15738            // is top (states that tend to be longer-term) and otherwise allow it to go
15739            // to the top state.
15740            switch (procState) {
15741                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15742                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15743                case ActivityManager.PROCESS_STATE_SERVICE:
15744                    // These all are longer-term states, so pull them up to the top
15745                    // of the background states, but not all the way to the top state.
15746                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15747                    break;
15748                default:
15749                    // Otherwise, top is a better choice, so take it.
15750                    procState = ActivityManager.PROCESS_STATE_TOP;
15751                    break;
15752            }
15753        }
15754
15755        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15756            if (app.hasClientActivities) {
15757                // This is a cached process, but with client activities.  Mark it so.
15758                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15759                app.adjType = "cch-client-act";
15760            } else if (app.treatLikeActivity) {
15761                // This is a cached process, but somebody wants us to treat it like it has
15762                // an activity, okay!
15763                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15764                app.adjType = "cch-as-act";
15765            }
15766        }
15767
15768        if (adj == ProcessList.SERVICE_ADJ) {
15769            if (doingAll) {
15770                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15771                mNewNumServiceProcs++;
15772                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15773                if (!app.serviceb) {
15774                    // This service isn't far enough down on the LRU list to
15775                    // normally be a B service, but if we are low on RAM and it
15776                    // is large we want to force it down since we would prefer to
15777                    // keep launcher over it.
15778                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15779                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15780                        app.serviceHighRam = true;
15781                        app.serviceb = true;
15782                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15783                    } else {
15784                        mNewNumAServiceProcs++;
15785                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15786                    }
15787                } else {
15788                    app.serviceHighRam = false;
15789                }
15790            }
15791            if (app.serviceb) {
15792                adj = ProcessList.SERVICE_B_ADJ;
15793            }
15794        }
15795
15796        app.curRawAdj = adj;
15797
15798        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15799        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15800        if (adj > app.maxAdj) {
15801            adj = app.maxAdj;
15802            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15803                schedGroup = Process.THREAD_GROUP_DEFAULT;
15804            }
15805        }
15806
15807        // Do final modification to adj.  Everything we do between here and applying
15808        // the final setAdj must be done in this function, because we will also use
15809        // it when computing the final cached adj later.  Note that we don't need to
15810        // worry about this for max adj above, since max adj will always be used to
15811        // keep it out of the cached vaues.
15812        app.curAdj = app.modifyRawOomAdj(adj);
15813        app.curSchedGroup = schedGroup;
15814        app.curProcState = procState;
15815        app.foregroundActivities = foregroundActivities;
15816
15817        return app.curRawAdj;
15818    }
15819
15820    /**
15821     * Schedule PSS collection of a process.
15822     */
15823    void requestPssLocked(ProcessRecord proc, int procState) {
15824        if (mPendingPssProcesses.contains(proc)) {
15825            return;
15826        }
15827        if (mPendingPssProcesses.size() == 0) {
15828            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15829        }
15830        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15831        proc.pssProcState = procState;
15832        mPendingPssProcesses.add(proc);
15833    }
15834
15835    /**
15836     * Schedule PSS collection of all processes.
15837     */
15838    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15839        if (!always) {
15840            if (now < (mLastFullPssTime +
15841                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15842                return;
15843            }
15844        }
15845        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15846        mLastFullPssTime = now;
15847        mFullPssPending = true;
15848        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15849        mPendingPssProcesses.clear();
15850        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15851            ProcessRecord app = mLruProcesses.get(i);
15852            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15853                app.pssProcState = app.setProcState;
15854                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15855                        isSleeping(), now);
15856                mPendingPssProcesses.add(app);
15857            }
15858        }
15859        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15860    }
15861
15862    /**
15863     * Ask a given process to GC right now.
15864     */
15865    final void performAppGcLocked(ProcessRecord app) {
15866        try {
15867            app.lastRequestedGc = SystemClock.uptimeMillis();
15868            if (app.thread != null) {
15869                if (app.reportLowMemory) {
15870                    app.reportLowMemory = false;
15871                    app.thread.scheduleLowMemory();
15872                } else {
15873                    app.thread.processInBackground();
15874                }
15875            }
15876        } catch (Exception e) {
15877            // whatever.
15878        }
15879    }
15880
15881    /**
15882     * Returns true if things are idle enough to perform GCs.
15883     */
15884    private final boolean canGcNowLocked() {
15885        boolean processingBroadcasts = false;
15886        for (BroadcastQueue q : mBroadcastQueues) {
15887            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15888                processingBroadcasts = true;
15889            }
15890        }
15891        return !processingBroadcasts
15892                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15893    }
15894
15895    /**
15896     * Perform GCs on all processes that are waiting for it, but only
15897     * if things are idle.
15898     */
15899    final void performAppGcsLocked() {
15900        final int N = mProcessesToGc.size();
15901        if (N <= 0) {
15902            return;
15903        }
15904        if (canGcNowLocked()) {
15905            while (mProcessesToGc.size() > 0) {
15906                ProcessRecord proc = mProcessesToGc.remove(0);
15907                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15908                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15909                            <= SystemClock.uptimeMillis()) {
15910                        // To avoid spamming the system, we will GC processes one
15911                        // at a time, waiting a few seconds between each.
15912                        performAppGcLocked(proc);
15913                        scheduleAppGcsLocked();
15914                        return;
15915                    } else {
15916                        // It hasn't been long enough since we last GCed this
15917                        // process...  put it in the list to wait for its time.
15918                        addProcessToGcListLocked(proc);
15919                        break;
15920                    }
15921                }
15922            }
15923
15924            scheduleAppGcsLocked();
15925        }
15926    }
15927
15928    /**
15929     * If all looks good, perform GCs on all processes waiting for them.
15930     */
15931    final void performAppGcsIfAppropriateLocked() {
15932        if (canGcNowLocked()) {
15933            performAppGcsLocked();
15934            return;
15935        }
15936        // Still not idle, wait some more.
15937        scheduleAppGcsLocked();
15938    }
15939
15940    /**
15941     * Schedule the execution of all pending app GCs.
15942     */
15943    final void scheduleAppGcsLocked() {
15944        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15945
15946        if (mProcessesToGc.size() > 0) {
15947            // Schedule a GC for the time to the next process.
15948            ProcessRecord proc = mProcessesToGc.get(0);
15949            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15950
15951            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15952            long now = SystemClock.uptimeMillis();
15953            if (when < (now+GC_TIMEOUT)) {
15954                when = now + GC_TIMEOUT;
15955            }
15956            mHandler.sendMessageAtTime(msg, when);
15957        }
15958    }
15959
15960    /**
15961     * Add a process to the array of processes waiting to be GCed.  Keeps the
15962     * list in sorted order by the last GC time.  The process can't already be
15963     * on the list.
15964     */
15965    final void addProcessToGcListLocked(ProcessRecord proc) {
15966        boolean added = false;
15967        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15968            if (mProcessesToGc.get(i).lastRequestedGc <
15969                    proc.lastRequestedGc) {
15970                added = true;
15971                mProcessesToGc.add(i+1, proc);
15972                break;
15973            }
15974        }
15975        if (!added) {
15976            mProcessesToGc.add(0, proc);
15977        }
15978    }
15979
15980    /**
15981     * Set up to ask a process to GC itself.  This will either do it
15982     * immediately, or put it on the list of processes to gc the next
15983     * time things are idle.
15984     */
15985    final void scheduleAppGcLocked(ProcessRecord app) {
15986        long now = SystemClock.uptimeMillis();
15987        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15988            return;
15989        }
15990        if (!mProcessesToGc.contains(app)) {
15991            addProcessToGcListLocked(app);
15992            scheduleAppGcsLocked();
15993        }
15994    }
15995
15996    final void checkExcessivePowerUsageLocked(boolean doKills) {
15997        updateCpuStatsNow();
15998
15999        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16000        boolean doWakeKills = doKills;
16001        boolean doCpuKills = doKills;
16002        if (mLastPowerCheckRealtime == 0) {
16003            doWakeKills = false;
16004        }
16005        if (mLastPowerCheckUptime == 0) {
16006            doCpuKills = false;
16007        }
16008        if (stats.isScreenOn()) {
16009            doWakeKills = false;
16010        }
16011        final long curRealtime = SystemClock.elapsedRealtime();
16012        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16013        final long curUptime = SystemClock.uptimeMillis();
16014        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16015        mLastPowerCheckRealtime = curRealtime;
16016        mLastPowerCheckUptime = curUptime;
16017        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16018            doWakeKills = false;
16019        }
16020        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16021            doCpuKills = false;
16022        }
16023        int i = mLruProcesses.size();
16024        while (i > 0) {
16025            i--;
16026            ProcessRecord app = mLruProcesses.get(i);
16027            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16028                long wtime;
16029                synchronized (stats) {
16030                    wtime = stats.getProcessWakeTime(app.info.uid,
16031                            app.pid, curRealtime);
16032                }
16033                long wtimeUsed = wtime - app.lastWakeTime;
16034                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16035                if (DEBUG_POWER) {
16036                    StringBuilder sb = new StringBuilder(128);
16037                    sb.append("Wake for ");
16038                    app.toShortString(sb);
16039                    sb.append(": over ");
16040                    TimeUtils.formatDuration(realtimeSince, sb);
16041                    sb.append(" used ");
16042                    TimeUtils.formatDuration(wtimeUsed, sb);
16043                    sb.append(" (");
16044                    sb.append((wtimeUsed*100)/realtimeSince);
16045                    sb.append("%)");
16046                    Slog.i(TAG, sb.toString());
16047                    sb.setLength(0);
16048                    sb.append("CPU for ");
16049                    app.toShortString(sb);
16050                    sb.append(": over ");
16051                    TimeUtils.formatDuration(uptimeSince, sb);
16052                    sb.append(" used ");
16053                    TimeUtils.formatDuration(cputimeUsed, sb);
16054                    sb.append(" (");
16055                    sb.append((cputimeUsed*100)/uptimeSince);
16056                    sb.append("%)");
16057                    Slog.i(TAG, sb.toString());
16058                }
16059                // If a process has held a wake lock for more
16060                // than 50% of the time during this period,
16061                // that sounds bad.  Kill!
16062                if (doWakeKills && realtimeSince > 0
16063                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16064                    synchronized (stats) {
16065                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16066                                realtimeSince, wtimeUsed);
16067                    }
16068                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
16069                            + " during " + realtimeSince);
16070                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16071                } else if (doCpuKills && uptimeSince > 0
16072                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16073                    synchronized (stats) {
16074                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16075                                uptimeSince, cputimeUsed);
16076                    }
16077                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
16078                            + " during " + uptimeSince);
16079                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16080                } else {
16081                    app.lastWakeTime = wtime;
16082                    app.lastCpuTime = app.curCpuTime;
16083                }
16084            }
16085        }
16086    }
16087
16088    private final boolean applyOomAdjLocked(ProcessRecord app,
16089            ProcessRecord TOP_APP, boolean doingAll, long now) {
16090        boolean success = true;
16091
16092        if (app.curRawAdj != app.setRawAdj) {
16093            app.setRawAdj = app.curRawAdj;
16094        }
16095
16096        int changes = 0;
16097
16098        if (app.curAdj != app.setAdj) {
16099            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16100            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16101                TAG, "Set " + app.pid + " " + app.processName +
16102                " adj " + app.curAdj + ": " + app.adjType);
16103            app.setAdj = app.curAdj;
16104        }
16105
16106        if (app.setSchedGroup != app.curSchedGroup) {
16107            app.setSchedGroup = app.curSchedGroup;
16108            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16109                    "Setting process group of " + app.processName
16110                    + " to " + app.curSchedGroup);
16111            if (app.waitingToKill != null &&
16112                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16113                killUnneededProcessLocked(app, app.waitingToKill);
16114                success = false;
16115            } else {
16116                if (true) {
16117                    long oldId = Binder.clearCallingIdentity();
16118                    try {
16119                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16120                    } catch (Exception e) {
16121                        Slog.w(TAG, "Failed setting process group of " + app.pid
16122                                + " to " + app.curSchedGroup);
16123                        e.printStackTrace();
16124                    } finally {
16125                        Binder.restoreCallingIdentity(oldId);
16126                    }
16127                } else {
16128                    if (app.thread != null) {
16129                        try {
16130                            app.thread.setSchedulingGroup(app.curSchedGroup);
16131                        } catch (RemoteException e) {
16132                        }
16133                    }
16134                }
16135                Process.setSwappiness(app.pid,
16136                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16137            }
16138        }
16139        if (app.repForegroundActivities != app.foregroundActivities) {
16140            app.repForegroundActivities = app.foregroundActivities;
16141            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16142        }
16143        if (app.repProcState != app.curProcState) {
16144            app.repProcState = app.curProcState;
16145            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16146            if (app.thread != null) {
16147                try {
16148                    if (false) {
16149                        //RuntimeException h = new RuntimeException("here");
16150                        Slog.i(TAG, "Sending new process state " + app.repProcState
16151                                + " to " + app /*, h*/);
16152                    }
16153                    app.thread.setProcessState(app.repProcState);
16154                } catch (RemoteException e) {
16155                }
16156            }
16157        }
16158        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16159                app.setProcState)) {
16160            app.lastStateTime = now;
16161            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16162                    isSleeping(), now);
16163            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16164                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16165                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16166                    + (app.nextPssTime-now) + ": " + app);
16167        } else {
16168            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16169                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16170                requestPssLocked(app, app.setProcState);
16171                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16172                        isSleeping(), now);
16173            } else if (false && DEBUG_PSS) {
16174                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16175            }
16176        }
16177        if (app.setProcState != app.curProcState) {
16178            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16179                    "Proc state change of " + app.processName
16180                    + " to " + app.curProcState);
16181            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
16182            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
16183            if (setImportant && !curImportant) {
16184                // This app is no longer something we consider important enough to allow to
16185                // use arbitrary amounts of battery power.  Note
16186                // its current wake lock time to later know to kill it if
16187                // it is not behaving well.
16188                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16189                synchronized (stats) {
16190                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
16191                            app.pid, SystemClock.elapsedRealtime());
16192                }
16193                app.lastCpuTime = app.curCpuTime;
16194
16195            }
16196            app.setProcState = app.curProcState;
16197            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16198                app.notCachedSinceIdle = false;
16199            }
16200            if (!doingAll) {
16201                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
16202            } else {
16203                app.procStateChanged = true;
16204            }
16205        }
16206
16207        if (changes != 0) {
16208            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16209            int i = mPendingProcessChanges.size()-1;
16210            ProcessChangeItem item = null;
16211            while (i >= 0) {
16212                item = mPendingProcessChanges.get(i);
16213                if (item.pid == app.pid) {
16214                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16215                    break;
16216                }
16217                i--;
16218            }
16219            if (i < 0) {
16220                // No existing item in pending changes; need a new one.
16221                final int NA = mAvailProcessChanges.size();
16222                if (NA > 0) {
16223                    item = mAvailProcessChanges.remove(NA-1);
16224                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16225                } else {
16226                    item = new ProcessChangeItem();
16227                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16228                }
16229                item.changes = 0;
16230                item.pid = app.pid;
16231                item.uid = app.info.uid;
16232                if (mPendingProcessChanges.size() == 0) {
16233                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16234                            "*** Enqueueing dispatch processes changed!");
16235                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16236                }
16237                mPendingProcessChanges.add(item);
16238            }
16239            item.changes |= changes;
16240            item.processState = app.repProcState;
16241            item.foregroundActivities = app.repForegroundActivities;
16242            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16243                    + Integer.toHexString(System.identityHashCode(item))
16244                    + " " + app.toShortString() + ": changes=" + item.changes
16245                    + " procState=" + item.processState
16246                    + " foreground=" + item.foregroundActivities
16247                    + " type=" + app.adjType + " source=" + app.adjSource
16248                    + " target=" + app.adjTarget);
16249        }
16250
16251        return success;
16252    }
16253
16254    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
16255        if (proc.thread != null) {
16256            if (proc.baseProcessTracker != null) {
16257                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16258            }
16259            if (proc.repProcState >= 0) {
16260                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
16261                        proc.repProcState);
16262            }
16263        }
16264    }
16265
16266    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16267            ProcessRecord TOP_APP, boolean doingAll, long now) {
16268        if (app.thread == null) {
16269            return false;
16270        }
16271
16272        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16273
16274        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
16275    }
16276
16277    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16278            boolean oomAdj) {
16279        if (isForeground != proc.foregroundServices) {
16280            proc.foregroundServices = isForeground;
16281            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16282                    proc.info.uid);
16283            if (isForeground) {
16284                if (curProcs == null) {
16285                    curProcs = new ArrayList<ProcessRecord>();
16286                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16287                }
16288                if (!curProcs.contains(proc)) {
16289                    curProcs.add(proc);
16290                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16291                            proc.info.packageName, proc.info.uid);
16292                }
16293            } else {
16294                if (curProcs != null) {
16295                    if (curProcs.remove(proc)) {
16296                        mBatteryStatsService.noteEvent(
16297                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16298                                proc.info.packageName, proc.info.uid);
16299                        if (curProcs.size() <= 0) {
16300                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16301                        }
16302                    }
16303                }
16304            }
16305            if (oomAdj) {
16306                updateOomAdjLocked();
16307            }
16308        }
16309    }
16310
16311    private final ActivityRecord resumedAppLocked() {
16312        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16313        String pkg;
16314        int uid;
16315        if (act != null) {
16316            pkg = act.packageName;
16317            uid = act.info.applicationInfo.uid;
16318        } else {
16319            pkg = null;
16320            uid = -1;
16321        }
16322        // Has the UID or resumed package name changed?
16323        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16324                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16325            if (mCurResumedPackage != null) {
16326                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16327                        mCurResumedPackage, mCurResumedUid);
16328            }
16329            mCurResumedPackage = pkg;
16330            mCurResumedUid = uid;
16331            if (mCurResumedPackage != null) {
16332                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16333                        mCurResumedPackage, mCurResumedUid);
16334            }
16335        }
16336        return act;
16337    }
16338
16339    final boolean updateOomAdjLocked(ProcessRecord app) {
16340        final ActivityRecord TOP_ACT = resumedAppLocked();
16341        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16342        final boolean wasCached = app.cached;
16343
16344        mAdjSeq++;
16345
16346        // This is the desired cached adjusment we want to tell it to use.
16347        // If our app is currently cached, we know it, and that is it.  Otherwise,
16348        // we don't know it yet, and it needs to now be cached we will then
16349        // need to do a complete oom adj.
16350        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16351                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16352        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16353                SystemClock.uptimeMillis());
16354        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16355            // Changed to/from cached state, so apps after it in the LRU
16356            // list may also be changed.
16357            updateOomAdjLocked();
16358        }
16359        return success;
16360    }
16361
16362    final void updateOomAdjLocked() {
16363        final ActivityRecord TOP_ACT = resumedAppLocked();
16364        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16365        final long now = SystemClock.uptimeMillis();
16366        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16367        final int N = mLruProcesses.size();
16368
16369        if (false) {
16370            RuntimeException e = new RuntimeException();
16371            e.fillInStackTrace();
16372            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16373        }
16374
16375        mAdjSeq++;
16376        mNewNumServiceProcs = 0;
16377        mNewNumAServiceProcs = 0;
16378
16379        final int emptyProcessLimit;
16380        final int cachedProcessLimit;
16381        if (mProcessLimit <= 0) {
16382            emptyProcessLimit = cachedProcessLimit = 0;
16383        } else if (mProcessLimit == 1) {
16384            emptyProcessLimit = 1;
16385            cachedProcessLimit = 0;
16386        } else {
16387            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16388            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16389        }
16390
16391        // Let's determine how many processes we have running vs.
16392        // how many slots we have for background processes; we may want
16393        // to put multiple processes in a slot of there are enough of
16394        // them.
16395        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16396                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16397        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16398        if (numEmptyProcs > cachedProcessLimit) {
16399            // If there are more empty processes than our limit on cached
16400            // processes, then use the cached process limit for the factor.
16401            // This ensures that the really old empty processes get pushed
16402            // down to the bottom, so if we are running low on memory we will
16403            // have a better chance at keeping around more cached processes
16404            // instead of a gazillion empty processes.
16405            numEmptyProcs = cachedProcessLimit;
16406        }
16407        int emptyFactor = numEmptyProcs/numSlots;
16408        if (emptyFactor < 1) emptyFactor = 1;
16409        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16410        if (cachedFactor < 1) cachedFactor = 1;
16411        int stepCached = 0;
16412        int stepEmpty = 0;
16413        int numCached = 0;
16414        int numEmpty = 0;
16415        int numTrimming = 0;
16416
16417        mNumNonCachedProcs = 0;
16418        mNumCachedHiddenProcs = 0;
16419
16420        // First update the OOM adjustment for each of the
16421        // application processes based on their current state.
16422        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16423        int nextCachedAdj = curCachedAdj+1;
16424        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16425        int nextEmptyAdj = curEmptyAdj+2;
16426        for (int i=N-1; i>=0; i--) {
16427            ProcessRecord app = mLruProcesses.get(i);
16428            if (!app.killedByAm && app.thread != null) {
16429                app.procStateChanged = false;
16430                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16431
16432                // If we haven't yet assigned the final cached adj
16433                // to the process, do that now.
16434                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16435                    switch (app.curProcState) {
16436                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16437                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16438                            // This process is a cached process holding activities...
16439                            // assign it the next cached value for that type, and then
16440                            // step that cached level.
16441                            app.curRawAdj = curCachedAdj;
16442                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16443                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16444                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16445                                    + ")");
16446                            if (curCachedAdj != nextCachedAdj) {
16447                                stepCached++;
16448                                if (stepCached >= cachedFactor) {
16449                                    stepCached = 0;
16450                                    curCachedAdj = nextCachedAdj;
16451                                    nextCachedAdj += 2;
16452                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16453                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16454                                    }
16455                                }
16456                            }
16457                            break;
16458                        default:
16459                            // For everything else, assign next empty cached process
16460                            // level and bump that up.  Note that this means that
16461                            // long-running services that have dropped down to the
16462                            // cached level will be treated as empty (since their process
16463                            // state is still as a service), which is what we want.
16464                            app.curRawAdj = curEmptyAdj;
16465                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16466                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16467                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16468                                    + ")");
16469                            if (curEmptyAdj != nextEmptyAdj) {
16470                                stepEmpty++;
16471                                if (stepEmpty >= emptyFactor) {
16472                                    stepEmpty = 0;
16473                                    curEmptyAdj = nextEmptyAdj;
16474                                    nextEmptyAdj += 2;
16475                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16476                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16477                                    }
16478                                }
16479                            }
16480                            break;
16481                    }
16482                }
16483
16484                applyOomAdjLocked(app, TOP_APP, true, now);
16485
16486                // Count the number of process types.
16487                switch (app.curProcState) {
16488                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16489                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16490                        mNumCachedHiddenProcs++;
16491                        numCached++;
16492                        if (numCached > cachedProcessLimit) {
16493                            killUnneededProcessLocked(app, "cached #" + numCached);
16494                        }
16495                        break;
16496                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16497                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16498                                && app.lastActivityTime < oldTime) {
16499                            killUnneededProcessLocked(app, "empty for "
16500                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16501                                    / 1000) + "s");
16502                        } else {
16503                            numEmpty++;
16504                            if (numEmpty > emptyProcessLimit) {
16505                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16506                            }
16507                        }
16508                        break;
16509                    default:
16510                        mNumNonCachedProcs++;
16511                        break;
16512                }
16513
16514                if (app.isolated && app.services.size() <= 0) {
16515                    // If this is an isolated process, and there are no
16516                    // services running in it, then the process is no longer
16517                    // needed.  We agressively kill these because we can by
16518                    // definition not re-use the same process again, and it is
16519                    // good to avoid having whatever code was running in them
16520                    // left sitting around after no longer needed.
16521                    killUnneededProcessLocked(app, "isolated not needed");
16522                }
16523
16524                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16525                        && !app.killedByAm) {
16526                    numTrimming++;
16527                }
16528            }
16529        }
16530
16531        mNumServiceProcs = mNewNumServiceProcs;
16532
16533        // Now determine the memory trimming level of background processes.
16534        // Unfortunately we need to start at the back of the list to do this
16535        // properly.  We only do this if the number of background apps we
16536        // are managing to keep around is less than half the maximum we desire;
16537        // if we are keeping a good number around, we'll let them use whatever
16538        // memory they want.
16539        final int numCachedAndEmpty = numCached + numEmpty;
16540        int memFactor;
16541        if (numCached <= ProcessList.TRIM_CACHED_APPS
16542                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16543            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16544                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16545            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16546                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16547            } else {
16548                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16549            }
16550        } else {
16551            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16552        }
16553        // We always allow the memory level to go up (better).  We only allow it to go
16554        // down if we are in a state where that is allowed, *and* the total number of processes
16555        // has gone down since last time.
16556        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16557                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16558                + " last=" + mLastNumProcesses);
16559        if (memFactor > mLastMemoryLevel) {
16560            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16561                memFactor = mLastMemoryLevel;
16562                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16563            }
16564        }
16565        mLastMemoryLevel = memFactor;
16566        mLastNumProcesses = mLruProcesses.size();
16567        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16568        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16569        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16570            if (mLowRamStartTime == 0) {
16571                mLowRamStartTime = now;
16572            }
16573            int step = 0;
16574            int fgTrimLevel;
16575            switch (memFactor) {
16576                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16577                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16578                    break;
16579                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16580                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16581                    break;
16582                default:
16583                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16584                    break;
16585            }
16586            int factor = numTrimming/3;
16587            int minFactor = 2;
16588            if (mHomeProcess != null) minFactor++;
16589            if (mPreviousProcess != null) minFactor++;
16590            if (factor < minFactor) factor = minFactor;
16591            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16592            for (int i=N-1; i>=0; i--) {
16593                ProcessRecord app = mLruProcesses.get(i);
16594                if (allChanged || app.procStateChanged) {
16595                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16596                    app.procStateChanged = false;
16597                }
16598                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16599                        && !app.killedByAm) {
16600                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16601                        try {
16602                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16603                                    "Trimming memory of " + app.processName
16604                                    + " to " + curLevel);
16605                            app.thread.scheduleTrimMemory(curLevel);
16606                        } catch (RemoteException e) {
16607                        }
16608                        if (false) {
16609                            // For now we won't do this; our memory trimming seems
16610                            // to be good enough at this point that destroying
16611                            // activities causes more harm than good.
16612                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16613                                    && app != mHomeProcess && app != mPreviousProcess) {
16614                                // Need to do this on its own message because the stack may not
16615                                // be in a consistent state at this point.
16616                                // For these apps we will also finish their activities
16617                                // to help them free memory.
16618                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16619                            }
16620                        }
16621                    }
16622                    app.trimMemoryLevel = curLevel;
16623                    step++;
16624                    if (step >= factor) {
16625                        step = 0;
16626                        switch (curLevel) {
16627                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16628                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16629                                break;
16630                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16631                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16632                                break;
16633                        }
16634                    }
16635                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16636                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16637                            && app.thread != null) {
16638                        try {
16639                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16640                                    "Trimming memory of heavy-weight " + app.processName
16641                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16642                            app.thread.scheduleTrimMemory(
16643                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16644                        } catch (RemoteException e) {
16645                        }
16646                    }
16647                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16648                } else {
16649                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16650                            || app.systemNoUi) && app.pendingUiClean) {
16651                        // If this application is now in the background and it
16652                        // had done UI, then give it the special trim level to
16653                        // have it free UI resources.
16654                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16655                        if (app.trimMemoryLevel < level && app.thread != null) {
16656                            try {
16657                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16658                                        "Trimming memory of bg-ui " + app.processName
16659                                        + " to " + level);
16660                                app.thread.scheduleTrimMemory(level);
16661                            } catch (RemoteException e) {
16662                            }
16663                        }
16664                        app.pendingUiClean = false;
16665                    }
16666                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16667                        try {
16668                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16669                                    "Trimming memory of fg " + app.processName
16670                                    + " to " + fgTrimLevel);
16671                            app.thread.scheduleTrimMemory(fgTrimLevel);
16672                        } catch (RemoteException e) {
16673                        }
16674                    }
16675                    app.trimMemoryLevel = fgTrimLevel;
16676                }
16677            }
16678        } else {
16679            if (mLowRamStartTime != 0) {
16680                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16681                mLowRamStartTime = 0;
16682            }
16683            for (int i=N-1; i>=0; i--) {
16684                ProcessRecord app = mLruProcesses.get(i);
16685                if (allChanged || app.procStateChanged) {
16686                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16687                    app.procStateChanged = false;
16688                }
16689                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16690                        || app.systemNoUi) && app.pendingUiClean) {
16691                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16692                            && app.thread != null) {
16693                        try {
16694                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16695                                    "Trimming memory of ui hidden " + app.processName
16696                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16697                            app.thread.scheduleTrimMemory(
16698                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16699                        } catch (RemoteException e) {
16700                        }
16701                    }
16702                    app.pendingUiClean = false;
16703                }
16704                app.trimMemoryLevel = 0;
16705            }
16706        }
16707
16708        if (mAlwaysFinishActivities) {
16709            // Need to do this on its own message because the stack may not
16710            // be in a consistent state at this point.
16711            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16712        }
16713
16714        if (allChanged) {
16715            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16716        }
16717
16718        if (mProcessStats.shouldWriteNowLocked(now)) {
16719            mHandler.post(new Runnable() {
16720                @Override public void run() {
16721                    synchronized (ActivityManagerService.this) {
16722                        mProcessStats.writeStateAsyncLocked();
16723                    }
16724                }
16725            });
16726        }
16727
16728        if (DEBUG_OOM_ADJ) {
16729            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16730        }
16731    }
16732
16733    final void trimApplications() {
16734        synchronized (this) {
16735            int i;
16736
16737            // First remove any unused application processes whose package
16738            // has been removed.
16739            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16740                final ProcessRecord app = mRemovedProcesses.get(i);
16741                if (app.activities.size() == 0
16742                        && app.curReceiver == null && app.services.size() == 0) {
16743                    Slog.i(
16744                        TAG, "Exiting empty application process "
16745                        + app.processName + " ("
16746                        + (app.thread != null ? app.thread.asBinder() : null)
16747                        + ")\n");
16748                    if (app.pid > 0 && app.pid != MY_PID) {
16749                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16750                                app.processName, app.setAdj, "empty");
16751                        app.killedByAm = true;
16752                        Process.killProcessQuiet(app.pid);
16753                        Process.killProcessGroup(app.info.uid, app.pid);
16754                    } else {
16755                        try {
16756                            app.thread.scheduleExit();
16757                        } catch (Exception e) {
16758                            // Ignore exceptions.
16759                        }
16760                    }
16761                    cleanUpApplicationRecordLocked(app, false, true, -1);
16762                    mRemovedProcesses.remove(i);
16763
16764                    if (app.persistent) {
16765                        addAppLocked(app.info, false, null /* ABI override */);
16766                    }
16767                }
16768            }
16769
16770            // Now update the oom adj for all processes.
16771            updateOomAdjLocked();
16772        }
16773    }
16774
16775    /** This method sends the specified signal to each of the persistent apps */
16776    public void signalPersistentProcesses(int sig) throws RemoteException {
16777        if (sig != Process.SIGNAL_USR1) {
16778            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16779        }
16780
16781        synchronized (this) {
16782            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16783                    != PackageManager.PERMISSION_GRANTED) {
16784                throw new SecurityException("Requires permission "
16785                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16786            }
16787
16788            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16789                ProcessRecord r = mLruProcesses.get(i);
16790                if (r.thread != null && r.persistent) {
16791                    Process.sendSignal(r.pid, sig);
16792                }
16793            }
16794        }
16795    }
16796
16797    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16798        if (proc == null || proc == mProfileProc) {
16799            proc = mProfileProc;
16800            path = mProfileFile;
16801            profileType = mProfileType;
16802            clearProfilerLocked();
16803        }
16804        if (proc == null) {
16805            return;
16806        }
16807        try {
16808            proc.thread.profilerControl(false, path, null, profileType);
16809        } catch (RemoteException e) {
16810            throw new IllegalStateException("Process disappeared");
16811        }
16812    }
16813
16814    private void clearProfilerLocked() {
16815        if (mProfileFd != null) {
16816            try {
16817                mProfileFd.close();
16818            } catch (IOException e) {
16819            }
16820        }
16821        mProfileApp = null;
16822        mProfileProc = null;
16823        mProfileFile = null;
16824        mProfileType = 0;
16825        mAutoStopProfiler = false;
16826    }
16827
16828    public boolean profileControl(String process, int userId, boolean start,
16829            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16830
16831        try {
16832            synchronized (this) {
16833                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16834                // its own permission.
16835                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16836                        != PackageManager.PERMISSION_GRANTED) {
16837                    throw new SecurityException("Requires permission "
16838                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16839                }
16840
16841                if (start && fd == null) {
16842                    throw new IllegalArgumentException("null fd");
16843                }
16844
16845                ProcessRecord proc = null;
16846                if (process != null) {
16847                    proc = findProcessLocked(process, userId, "profileControl");
16848                }
16849
16850                if (start && (proc == null || proc.thread == null)) {
16851                    throw new IllegalArgumentException("Unknown process: " + process);
16852                }
16853
16854                if (start) {
16855                    stopProfilerLocked(null, null, 0);
16856                    setProfileApp(proc.info, proc.processName, path, fd, false);
16857                    mProfileProc = proc;
16858                    mProfileType = profileType;
16859                    try {
16860                        fd = fd.dup();
16861                    } catch (IOException e) {
16862                        fd = null;
16863                    }
16864                    proc.thread.profilerControl(start, path, fd, profileType);
16865                    fd = null;
16866                    mProfileFd = null;
16867                } else {
16868                    stopProfilerLocked(proc, path, profileType);
16869                    if (fd != null) {
16870                        try {
16871                            fd.close();
16872                        } catch (IOException e) {
16873                        }
16874                    }
16875                }
16876
16877                return true;
16878            }
16879        } catch (RemoteException e) {
16880            throw new IllegalStateException("Process disappeared");
16881        } finally {
16882            if (fd != null) {
16883                try {
16884                    fd.close();
16885                } catch (IOException e) {
16886                }
16887            }
16888        }
16889    }
16890
16891    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16892        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16893                userId, true, ALLOW_FULL_ONLY, callName, null);
16894        ProcessRecord proc = null;
16895        try {
16896            int pid = Integer.parseInt(process);
16897            synchronized (mPidsSelfLocked) {
16898                proc = mPidsSelfLocked.get(pid);
16899            }
16900        } catch (NumberFormatException e) {
16901        }
16902
16903        if (proc == null) {
16904            ArrayMap<String, SparseArray<ProcessRecord>> all
16905                    = mProcessNames.getMap();
16906            SparseArray<ProcessRecord> procs = all.get(process);
16907            if (procs != null && procs.size() > 0) {
16908                proc = procs.valueAt(0);
16909                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16910                    for (int i=1; i<procs.size(); i++) {
16911                        ProcessRecord thisProc = procs.valueAt(i);
16912                        if (thisProc.userId == userId) {
16913                            proc = thisProc;
16914                            break;
16915                        }
16916                    }
16917                }
16918            }
16919        }
16920
16921        return proc;
16922    }
16923
16924    public boolean dumpHeap(String process, int userId, boolean managed,
16925            String path, ParcelFileDescriptor fd) throws RemoteException {
16926
16927        try {
16928            synchronized (this) {
16929                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16930                // its own permission (same as profileControl).
16931                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16932                        != PackageManager.PERMISSION_GRANTED) {
16933                    throw new SecurityException("Requires permission "
16934                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16935                }
16936
16937                if (fd == null) {
16938                    throw new IllegalArgumentException("null fd");
16939                }
16940
16941                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16942                if (proc == null || proc.thread == null) {
16943                    throw new IllegalArgumentException("Unknown process: " + process);
16944                }
16945
16946                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16947                if (!isDebuggable) {
16948                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16949                        throw new SecurityException("Process not debuggable: " + proc);
16950                    }
16951                }
16952
16953                proc.thread.dumpHeap(managed, path, fd);
16954                fd = null;
16955                return true;
16956            }
16957        } catch (RemoteException e) {
16958            throw new IllegalStateException("Process disappeared");
16959        } finally {
16960            if (fd != null) {
16961                try {
16962                    fd.close();
16963                } catch (IOException e) {
16964                }
16965            }
16966        }
16967    }
16968
16969    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16970    public void monitor() {
16971        synchronized (this) { }
16972    }
16973
16974    void onCoreSettingsChange(Bundle settings) {
16975        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16976            ProcessRecord processRecord = mLruProcesses.get(i);
16977            try {
16978                if (processRecord.thread != null) {
16979                    processRecord.thread.setCoreSettings(settings);
16980                }
16981            } catch (RemoteException re) {
16982                /* ignore */
16983            }
16984        }
16985    }
16986
16987    // Multi-user methods
16988
16989    /**
16990     * Start user, if its not already running, but don't bring it to foreground.
16991     */
16992    @Override
16993    public boolean startUserInBackground(final int userId) {
16994        return startUser(userId, /* foreground */ false);
16995    }
16996
16997    /**
16998     * Refreshes the list of users related to the current user when either a
16999     * user switch happens or when a new related user is started in the
17000     * background.
17001     */
17002    private void updateCurrentProfileIdsLocked() {
17003        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17004                mCurrentUserId, false /* enabledOnly */);
17005        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17006        for (int i = 0; i < currentProfileIds.length; i++) {
17007            currentProfileIds[i] = profiles.get(i).id;
17008        }
17009        mCurrentProfileIds = currentProfileIds;
17010
17011        synchronized (mUserProfileGroupIdsSelfLocked) {
17012            mUserProfileGroupIdsSelfLocked.clear();
17013            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17014            for (int i = 0; i < users.size(); i++) {
17015                UserInfo user = users.get(i);
17016                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17017                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17018                }
17019            }
17020        }
17021    }
17022
17023    private Set getProfileIdsLocked(int userId) {
17024        Set userIds = new HashSet<Integer>();
17025        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17026                userId, false /* enabledOnly */);
17027        for (UserInfo user : profiles) {
17028            userIds.add(Integer.valueOf(user.id));
17029        }
17030        return userIds;
17031    }
17032
17033    @Override
17034    public boolean switchUser(final int userId) {
17035        return startUser(userId, /* foregound */ true);
17036    }
17037
17038    private boolean startUser(final int userId, boolean foreground) {
17039        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17040                != PackageManager.PERMISSION_GRANTED) {
17041            String msg = "Permission Denial: switchUser() from pid="
17042                    + Binder.getCallingPid()
17043                    + ", uid=" + Binder.getCallingUid()
17044                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17045            Slog.w(TAG, msg);
17046            throw new SecurityException(msg);
17047        }
17048
17049        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17050
17051        final long ident = Binder.clearCallingIdentity();
17052        try {
17053            synchronized (this) {
17054                final int oldUserId = mCurrentUserId;
17055                if (oldUserId == userId) {
17056                    return true;
17057                }
17058
17059                mStackSupervisor.setLockTaskModeLocked(null, false);
17060
17061                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17062                if (userInfo == null) {
17063                    Slog.w(TAG, "No user info for user #" + userId);
17064                    return false;
17065                }
17066
17067                if (foreground) {
17068                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17069                            R.anim.screen_user_enter);
17070                }
17071
17072                boolean needStart = false;
17073
17074                // If the user we are switching to is not currently started, then
17075                // we need to start it now.
17076                if (mStartedUsers.get(userId) == null) {
17077                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17078                    updateStartedUserArrayLocked();
17079                    needStart = true;
17080                }
17081
17082                final Integer userIdInt = Integer.valueOf(userId);
17083                mUserLru.remove(userIdInt);
17084                mUserLru.add(userIdInt);
17085
17086                if (foreground) {
17087                    mCurrentUserId = userId;
17088                    updateCurrentProfileIdsLocked();
17089                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17090                    // Once the internal notion of the active user has switched, we lock the device
17091                    // with the option to show the user switcher on the keyguard.
17092                    mWindowManager.lockNow(null);
17093                } else {
17094                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17095                    updateCurrentProfileIdsLocked();
17096                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17097                    mUserLru.remove(currentUserIdInt);
17098                    mUserLru.add(currentUserIdInt);
17099                }
17100
17101                final UserStartedState uss = mStartedUsers.get(userId);
17102
17103                // Make sure user is in the started state.  If it is currently
17104                // stopping, we need to knock that off.
17105                if (uss.mState == UserStartedState.STATE_STOPPING) {
17106                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17107                    // so we can just fairly silently bring the user back from
17108                    // the almost-dead.
17109                    uss.mState = UserStartedState.STATE_RUNNING;
17110                    updateStartedUserArrayLocked();
17111                    needStart = true;
17112                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17113                    // This means ACTION_SHUTDOWN has been sent, so we will
17114                    // need to treat this as a new boot of the user.
17115                    uss.mState = UserStartedState.STATE_BOOTING;
17116                    updateStartedUserArrayLocked();
17117                    needStart = true;
17118                }
17119
17120                if (uss.mState == UserStartedState.STATE_BOOTING) {
17121                    // Booting up a new user, need to tell system services about it.
17122                    // Note that this is on the same handler as scheduling of broadcasts,
17123                    // which is important because it needs to go first.
17124                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
17125                }
17126
17127                if (foreground) {
17128                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
17129                            oldUserId));
17130                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17131                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17132                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
17133                            oldUserId, userId, uss));
17134                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
17135                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
17136                }
17137
17138                if (needStart) {
17139                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
17140                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17141                            | Intent.FLAG_RECEIVER_FOREGROUND);
17142                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17143                    broadcastIntentLocked(null, null, intent,
17144                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17145                            false, false, MY_PID, Process.SYSTEM_UID, userId);
17146                }
17147
17148                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
17149                    if (userId != UserHandle.USER_OWNER) {
17150                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
17151                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17152                        broadcastIntentLocked(null, null, intent, null,
17153                                new IIntentReceiver.Stub() {
17154                                    public void performReceive(Intent intent, int resultCode,
17155                                            String data, Bundle extras, boolean ordered,
17156                                            boolean sticky, int sendingUser) {
17157                                        userInitialized(uss, userId);
17158                                    }
17159                                }, 0, null, null, null, AppOpsManager.OP_NONE,
17160                                true, false, MY_PID, Process.SYSTEM_UID,
17161                                userId);
17162                        uss.initializing = true;
17163                    } else {
17164                        getUserManagerLocked().makeInitialized(userInfo.id);
17165                    }
17166                }
17167
17168                if (foreground) {
17169                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
17170                    if (homeInFront) {
17171                        startHomeActivityLocked(userId);
17172                    } else {
17173                        mStackSupervisor.resumeTopActivitiesLocked();
17174                    }
17175                    EventLogTags.writeAmSwitchUser(userId);
17176                    getUserManagerLocked().userForeground(userId);
17177                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
17178                } else {
17179                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
17180                }
17181
17182                if (needStart) {
17183                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
17184                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17185                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17186                    broadcastIntentLocked(null, null, intent,
17187                            null, new IIntentReceiver.Stub() {
17188                                @Override
17189                                public void performReceive(Intent intent, int resultCode, String data,
17190                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
17191                                        throws RemoteException {
17192                                }
17193                            }, 0, null, null,
17194                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17195                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17196                }
17197            }
17198        } finally {
17199            Binder.restoreCallingIdentity(ident);
17200        }
17201
17202        return true;
17203    }
17204
17205    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
17206        long ident = Binder.clearCallingIdentity();
17207        try {
17208            Intent intent;
17209            if (oldUserId >= 0) {
17210                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
17211                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
17212                int count = profiles.size();
17213                for (int i = 0; i < count; i++) {
17214                    int profileUserId = profiles.get(i).id;
17215                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
17216                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17217                            | Intent.FLAG_RECEIVER_FOREGROUND);
17218                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17219                    broadcastIntentLocked(null, null, intent,
17220                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17221                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17222                }
17223            }
17224            if (newUserId >= 0) {
17225                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
17226                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
17227                int count = profiles.size();
17228                for (int i = 0; i < count; i++) {
17229                    int profileUserId = profiles.get(i).id;
17230                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
17231                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17232                            | Intent.FLAG_RECEIVER_FOREGROUND);
17233                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17234                    broadcastIntentLocked(null, null, intent,
17235                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17236                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17237                }
17238                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17239                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17240                        | Intent.FLAG_RECEIVER_FOREGROUND);
17241                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17242                broadcastIntentLocked(null, null, intent,
17243                        null, null, 0, null, null,
17244                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17245                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17246            }
17247        } finally {
17248            Binder.restoreCallingIdentity(ident);
17249        }
17250    }
17251
17252    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17253            final int newUserId) {
17254        final int N = mUserSwitchObservers.beginBroadcast();
17255        if (N > 0) {
17256            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17257                int mCount = 0;
17258                @Override
17259                public void sendResult(Bundle data) throws RemoteException {
17260                    synchronized (ActivityManagerService.this) {
17261                        if (mCurUserSwitchCallback == this) {
17262                            mCount++;
17263                            if (mCount == N) {
17264                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17265                            }
17266                        }
17267                    }
17268                }
17269            };
17270            synchronized (this) {
17271                uss.switching = true;
17272                mCurUserSwitchCallback = callback;
17273            }
17274            for (int i=0; i<N; i++) {
17275                try {
17276                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17277                            newUserId, callback);
17278                } catch (RemoteException e) {
17279                }
17280            }
17281        } else {
17282            synchronized (this) {
17283                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17284            }
17285        }
17286        mUserSwitchObservers.finishBroadcast();
17287    }
17288
17289    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17290        synchronized (this) {
17291            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17292            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17293        }
17294    }
17295
17296    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17297        mCurUserSwitchCallback = null;
17298        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17299        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17300                oldUserId, newUserId, uss));
17301    }
17302
17303    void userInitialized(UserStartedState uss, int newUserId) {
17304        completeSwitchAndInitalize(uss, newUserId, true, false);
17305    }
17306
17307    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17308        completeSwitchAndInitalize(uss, newUserId, false, true);
17309    }
17310
17311    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17312            boolean clearInitializing, boolean clearSwitching) {
17313        boolean unfrozen = false;
17314        synchronized (this) {
17315            if (clearInitializing) {
17316                uss.initializing = false;
17317                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17318            }
17319            if (clearSwitching) {
17320                uss.switching = false;
17321            }
17322            if (!uss.switching && !uss.initializing) {
17323                mWindowManager.stopFreezingScreen();
17324                unfrozen = true;
17325            }
17326        }
17327        if (unfrozen) {
17328            final int N = mUserSwitchObservers.beginBroadcast();
17329            for (int i=0; i<N; i++) {
17330                try {
17331                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17332                } catch (RemoteException e) {
17333                }
17334            }
17335            mUserSwitchObservers.finishBroadcast();
17336        }
17337    }
17338
17339    void scheduleStartProfilesLocked() {
17340        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17341            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17342                    DateUtils.SECOND_IN_MILLIS);
17343        }
17344    }
17345
17346    void startProfilesLocked() {
17347        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17348        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17349                mCurrentUserId, false /* enabledOnly */);
17350        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17351        for (UserInfo user : profiles) {
17352            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17353                    && user.id != mCurrentUserId) {
17354                toStart.add(user);
17355            }
17356        }
17357        final int n = toStart.size();
17358        int i = 0;
17359        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17360            startUserInBackground(toStart.get(i).id);
17361        }
17362        if (i < n) {
17363            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17364        }
17365    }
17366
17367    void finishUserBoot(UserStartedState uss) {
17368        synchronized (this) {
17369            if (uss.mState == UserStartedState.STATE_BOOTING
17370                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17371                uss.mState = UserStartedState.STATE_RUNNING;
17372                final int userId = uss.mHandle.getIdentifier();
17373                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17374                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17375                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17376                broadcastIntentLocked(null, null, intent,
17377                        null, null, 0, null, null,
17378                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17379                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17380            }
17381        }
17382    }
17383
17384    void finishUserSwitch(UserStartedState uss) {
17385        synchronized (this) {
17386            finishUserBoot(uss);
17387
17388            startProfilesLocked();
17389
17390            int num = mUserLru.size();
17391            int i = 0;
17392            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17393                Integer oldUserId = mUserLru.get(i);
17394                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17395                if (oldUss == null) {
17396                    // Shouldn't happen, but be sane if it does.
17397                    mUserLru.remove(i);
17398                    num--;
17399                    continue;
17400                }
17401                if (oldUss.mState == UserStartedState.STATE_STOPPING
17402                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17403                    // This user is already stopping, doesn't count.
17404                    num--;
17405                    i++;
17406                    continue;
17407                }
17408                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17409                    // Owner and current can't be stopped, but count as running.
17410                    i++;
17411                    continue;
17412                }
17413                // This is a user to be stopped.
17414                stopUserLocked(oldUserId, null);
17415                num--;
17416                i++;
17417            }
17418        }
17419    }
17420
17421    @Override
17422    public int stopUser(final int userId, final IStopUserCallback callback) {
17423        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17424                != PackageManager.PERMISSION_GRANTED) {
17425            String msg = "Permission Denial: switchUser() from pid="
17426                    + Binder.getCallingPid()
17427                    + ", uid=" + Binder.getCallingUid()
17428                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17429            Slog.w(TAG, msg);
17430            throw new SecurityException(msg);
17431        }
17432        if (userId <= 0) {
17433            throw new IllegalArgumentException("Can't stop primary user " + userId);
17434        }
17435        synchronized (this) {
17436            return stopUserLocked(userId, callback);
17437        }
17438    }
17439
17440    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17441        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17442        if (mCurrentUserId == userId) {
17443            return ActivityManager.USER_OP_IS_CURRENT;
17444        }
17445
17446        final UserStartedState uss = mStartedUsers.get(userId);
17447        if (uss == null) {
17448            // User is not started, nothing to do...  but we do need to
17449            // callback if requested.
17450            if (callback != null) {
17451                mHandler.post(new Runnable() {
17452                    @Override
17453                    public void run() {
17454                        try {
17455                            callback.userStopped(userId);
17456                        } catch (RemoteException e) {
17457                        }
17458                    }
17459                });
17460            }
17461            return ActivityManager.USER_OP_SUCCESS;
17462        }
17463
17464        if (callback != null) {
17465            uss.mStopCallbacks.add(callback);
17466        }
17467
17468        if (uss.mState != UserStartedState.STATE_STOPPING
17469                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17470            uss.mState = UserStartedState.STATE_STOPPING;
17471            updateStartedUserArrayLocked();
17472
17473            long ident = Binder.clearCallingIdentity();
17474            try {
17475                // We are going to broadcast ACTION_USER_STOPPING and then
17476                // once that is done send a final ACTION_SHUTDOWN and then
17477                // stop the user.
17478                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17479                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17480                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17481                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17482                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17483                // This is the result receiver for the final shutdown broadcast.
17484                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17485                    @Override
17486                    public void performReceive(Intent intent, int resultCode, String data,
17487                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17488                        finishUserStop(uss);
17489                    }
17490                };
17491                // This is the result receiver for the initial stopping broadcast.
17492                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17493                    @Override
17494                    public void performReceive(Intent intent, int resultCode, String data,
17495                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17496                        // On to the next.
17497                        synchronized (ActivityManagerService.this) {
17498                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17499                                // Whoops, we are being started back up.  Abort, abort!
17500                                return;
17501                            }
17502                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17503                        }
17504                        mBatteryStatsService.noteEvent(
17505                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
17506                                Integer.toString(userId), userId);
17507                        mSystemServiceManager.stopUser(userId);
17508                        broadcastIntentLocked(null, null, shutdownIntent,
17509                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17510                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17511                    }
17512                };
17513                // Kick things off.
17514                broadcastIntentLocked(null, null, stoppingIntent,
17515                        null, stoppingReceiver, 0, null, null,
17516                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17517                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17518            } finally {
17519                Binder.restoreCallingIdentity(ident);
17520            }
17521        }
17522
17523        return ActivityManager.USER_OP_SUCCESS;
17524    }
17525
17526    void finishUserStop(UserStartedState uss) {
17527        final int userId = uss.mHandle.getIdentifier();
17528        boolean stopped;
17529        ArrayList<IStopUserCallback> callbacks;
17530        synchronized (this) {
17531            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17532            if (mStartedUsers.get(userId) != uss) {
17533                stopped = false;
17534            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17535                stopped = false;
17536            } else {
17537                stopped = true;
17538                // User can no longer run.
17539                mStartedUsers.remove(userId);
17540                mUserLru.remove(Integer.valueOf(userId));
17541                updateStartedUserArrayLocked();
17542
17543                // Clean up all state and processes associated with the user.
17544                // Kill all the processes for the user.
17545                forceStopUserLocked(userId, "finish user");
17546            }
17547        }
17548
17549        for (int i=0; i<callbacks.size(); i++) {
17550            try {
17551                if (stopped) callbacks.get(i).userStopped(userId);
17552                else callbacks.get(i).userStopAborted(userId);
17553            } catch (RemoteException e) {
17554            }
17555        }
17556
17557        if (stopped) {
17558            mSystemServiceManager.cleanupUser(userId);
17559            synchronized (this) {
17560                mStackSupervisor.removeUserLocked(userId);
17561            }
17562        }
17563    }
17564
17565    @Override
17566    public UserInfo getCurrentUser() {
17567        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
17568                != PackageManager.PERMISSION_GRANTED) && (
17569                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17570                != PackageManager.PERMISSION_GRANTED)) {
17571            String msg = "Permission Denial: getCurrentUser() from pid="
17572                    + Binder.getCallingPid()
17573                    + ", uid=" + Binder.getCallingUid()
17574                    + " requires " + INTERACT_ACROSS_USERS;
17575            Slog.w(TAG, msg);
17576            throw new SecurityException(msg);
17577        }
17578        synchronized (this) {
17579            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17580        }
17581    }
17582
17583    int getCurrentUserIdLocked() {
17584        return mCurrentUserId;
17585    }
17586
17587    @Override
17588    public boolean isUserRunning(int userId, boolean orStopped) {
17589        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17590                != PackageManager.PERMISSION_GRANTED) {
17591            String msg = "Permission Denial: isUserRunning() from pid="
17592                    + Binder.getCallingPid()
17593                    + ", uid=" + Binder.getCallingUid()
17594                    + " requires " + INTERACT_ACROSS_USERS;
17595            Slog.w(TAG, msg);
17596            throw new SecurityException(msg);
17597        }
17598        synchronized (this) {
17599            return isUserRunningLocked(userId, orStopped);
17600        }
17601    }
17602
17603    boolean isUserRunningLocked(int userId, boolean orStopped) {
17604        UserStartedState state = mStartedUsers.get(userId);
17605        if (state == null) {
17606            return false;
17607        }
17608        if (orStopped) {
17609            return true;
17610        }
17611        return state.mState != UserStartedState.STATE_STOPPING
17612                && state.mState != UserStartedState.STATE_SHUTDOWN;
17613    }
17614
17615    @Override
17616    public int[] getRunningUserIds() {
17617        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17618                != PackageManager.PERMISSION_GRANTED) {
17619            String msg = "Permission Denial: isUserRunning() from pid="
17620                    + Binder.getCallingPid()
17621                    + ", uid=" + Binder.getCallingUid()
17622                    + " requires " + INTERACT_ACROSS_USERS;
17623            Slog.w(TAG, msg);
17624            throw new SecurityException(msg);
17625        }
17626        synchronized (this) {
17627            return mStartedUserArray;
17628        }
17629    }
17630
17631    private void updateStartedUserArrayLocked() {
17632        int num = 0;
17633        for (int i=0; i<mStartedUsers.size();  i++) {
17634            UserStartedState uss = mStartedUsers.valueAt(i);
17635            // This list does not include stopping users.
17636            if (uss.mState != UserStartedState.STATE_STOPPING
17637                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17638                num++;
17639            }
17640        }
17641        mStartedUserArray = new int[num];
17642        num = 0;
17643        for (int i=0; i<mStartedUsers.size();  i++) {
17644            UserStartedState uss = mStartedUsers.valueAt(i);
17645            if (uss.mState != UserStartedState.STATE_STOPPING
17646                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17647                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17648                num++;
17649            }
17650        }
17651    }
17652
17653    @Override
17654    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17655        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17656                != PackageManager.PERMISSION_GRANTED) {
17657            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17658                    + Binder.getCallingPid()
17659                    + ", uid=" + Binder.getCallingUid()
17660                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17661            Slog.w(TAG, msg);
17662            throw new SecurityException(msg);
17663        }
17664
17665        mUserSwitchObservers.register(observer);
17666    }
17667
17668    @Override
17669    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17670        mUserSwitchObservers.unregister(observer);
17671    }
17672
17673    private boolean userExists(int userId) {
17674        if (userId == 0) {
17675            return true;
17676        }
17677        UserManagerService ums = getUserManagerLocked();
17678        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17679    }
17680
17681    int[] getUsersLocked() {
17682        UserManagerService ums = getUserManagerLocked();
17683        return ums != null ? ums.getUserIds() : new int[] { 0 };
17684    }
17685
17686    UserManagerService getUserManagerLocked() {
17687        if (mUserManager == null) {
17688            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17689            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17690        }
17691        return mUserManager;
17692    }
17693
17694    private int applyUserId(int uid, int userId) {
17695        return UserHandle.getUid(userId, uid);
17696    }
17697
17698    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17699        if (info == null) return null;
17700        ApplicationInfo newInfo = new ApplicationInfo(info);
17701        newInfo.uid = applyUserId(info.uid, userId);
17702        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17703                + info.packageName;
17704        return newInfo;
17705    }
17706
17707    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17708        if (aInfo == null
17709                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17710            return aInfo;
17711        }
17712
17713        ActivityInfo info = new ActivityInfo(aInfo);
17714        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17715        return info;
17716    }
17717
17718    private final class LocalService extends ActivityManagerInternal {
17719        @Override
17720        public void goingToSleep() {
17721            ActivityManagerService.this.goingToSleep();
17722        }
17723
17724        @Override
17725        public void wakingUp() {
17726            ActivityManagerService.this.wakingUp();
17727        }
17728    }
17729
17730    /**
17731     * An implementation of IAppTask, that allows an app to manage its own tasks via
17732     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17733     * only the process that calls getAppTasks() can call the AppTask methods.
17734     */
17735    class AppTaskImpl extends IAppTask.Stub {
17736        private int mTaskId;
17737        private int mCallingUid;
17738
17739        public AppTaskImpl(int taskId, int callingUid) {
17740            mTaskId = taskId;
17741            mCallingUid = callingUid;
17742        }
17743
17744        @Override
17745        public void finishAndRemoveTask() {
17746            // Ensure that we are called from the same process that created this AppTask
17747            if (mCallingUid != Binder.getCallingUid()) {
17748                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17749                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17750                return;
17751            }
17752
17753            synchronized (ActivityManagerService.this) {
17754                long origId = Binder.clearCallingIdentity();
17755                try {
17756                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17757                    if (tr != null) {
17758                        // Only kill the process if we are not a new document
17759                        int flags = tr.getBaseIntent().getFlags();
17760                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17761                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17762                        removeTaskByIdLocked(mTaskId,
17763                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17764                    }
17765                } finally {
17766                    Binder.restoreCallingIdentity(origId);
17767                }
17768            }
17769        }
17770
17771        @Override
17772        public ActivityManager.RecentTaskInfo getTaskInfo() {
17773            // Ensure that we are called from the same process that created this AppTask
17774            if (mCallingUid != Binder.getCallingUid()) {
17775                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17776                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17777                return null;
17778            }
17779
17780            synchronized (ActivityManagerService.this) {
17781                long origId = Binder.clearCallingIdentity();
17782                try {
17783                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17784                    if (tr != null) {
17785                        return createRecentTaskInfoFromTaskRecord(tr);
17786                    }
17787                } finally {
17788                    Binder.restoreCallingIdentity(origId);
17789                }
17790                return null;
17791            }
17792        }
17793    }
17794}
17795