ActivityManagerService.java revision fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7
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.performDexOptIfNeeded(packageName, null /* instruction set */)) {
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    @Override
4719    public void addPackageDependency(String packageName) {
4720        synchronized (this) {
4721            int callingPid = Binder.getCallingPid();
4722            if (callingPid == Process.myPid()) {
4723                //  Yeah, um, no.
4724                Slog.w(TAG, "Can't addPackageDependency on system process");
4725                return;
4726            }
4727            ProcessRecord proc;
4728            synchronized (mPidsSelfLocked) {
4729                proc = mPidsSelfLocked.get(Binder.getCallingPid());
4730            }
4731            if (proc != null) {
4732                if (proc.pkgDeps == null) {
4733                    proc.pkgDeps = new ArraySet<String>(1);
4734                }
4735                proc.pkgDeps.add(packageName);
4736            }
4737        }
4738    }
4739
4740    /*
4741     * The pkg name and app id have to be specified.
4742     */
4743    @Override
4744    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4745        if (pkg == null) {
4746            return;
4747        }
4748        // Make sure the uid is valid.
4749        if (appid < 0) {
4750            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4751            return;
4752        }
4753        int callerUid = Binder.getCallingUid();
4754        // Only the system server can kill an application
4755        if (callerUid == Process.SYSTEM_UID) {
4756            // Post an aysnc message to kill the application
4757            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4758            msg.arg1 = appid;
4759            msg.arg2 = 0;
4760            Bundle bundle = new Bundle();
4761            bundle.putString("pkg", pkg);
4762            bundle.putString("reason", reason);
4763            msg.obj = bundle;
4764            mHandler.sendMessage(msg);
4765        } else {
4766            throw new SecurityException(callerUid + " cannot kill pkg: " +
4767                    pkg);
4768        }
4769    }
4770
4771    @Override
4772    public void closeSystemDialogs(String reason) {
4773        enforceNotIsolatedCaller("closeSystemDialogs");
4774
4775        final int pid = Binder.getCallingPid();
4776        final int uid = Binder.getCallingUid();
4777        final long origId = Binder.clearCallingIdentity();
4778        try {
4779            synchronized (this) {
4780                // Only allow this from foreground processes, so that background
4781                // applications can't abuse it to prevent system UI from being shown.
4782                if (uid >= Process.FIRST_APPLICATION_UID) {
4783                    ProcessRecord proc;
4784                    synchronized (mPidsSelfLocked) {
4785                        proc = mPidsSelfLocked.get(pid);
4786                    }
4787                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4788                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4789                                + " from background process " + proc);
4790                        return;
4791                    }
4792                }
4793                closeSystemDialogsLocked(reason);
4794            }
4795        } finally {
4796            Binder.restoreCallingIdentity(origId);
4797        }
4798    }
4799
4800    void closeSystemDialogsLocked(String reason) {
4801        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4802        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4803                | Intent.FLAG_RECEIVER_FOREGROUND);
4804        if (reason != null) {
4805            intent.putExtra("reason", reason);
4806        }
4807        mWindowManager.closeSystemDialogs(reason);
4808
4809        mStackSupervisor.closeSystemDialogsLocked();
4810
4811        broadcastIntentLocked(null, null, intent, null,
4812                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4813                Process.SYSTEM_UID, UserHandle.USER_ALL);
4814    }
4815
4816    @Override
4817    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4818        enforceNotIsolatedCaller("getProcessMemoryInfo");
4819        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4820        for (int i=pids.length-1; i>=0; i--) {
4821            ProcessRecord proc;
4822            int oomAdj;
4823            synchronized (this) {
4824                synchronized (mPidsSelfLocked) {
4825                    proc = mPidsSelfLocked.get(pids[i]);
4826                    oomAdj = proc != null ? proc.setAdj : 0;
4827                }
4828            }
4829            infos[i] = new Debug.MemoryInfo();
4830            Debug.getMemoryInfo(pids[i], infos[i]);
4831            if (proc != null) {
4832                synchronized (this) {
4833                    if (proc.thread != null && proc.setAdj == oomAdj) {
4834                        // Record this for posterity if the process has been stable.
4835                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4836                                infos[i].getTotalUss(), false, proc.pkgList);
4837                    }
4838                }
4839            }
4840        }
4841        return infos;
4842    }
4843
4844    @Override
4845    public long[] getProcessPss(int[] pids) {
4846        enforceNotIsolatedCaller("getProcessPss");
4847        long[] pss = new long[pids.length];
4848        for (int i=pids.length-1; i>=0; i--) {
4849            ProcessRecord proc;
4850            int oomAdj;
4851            synchronized (this) {
4852                synchronized (mPidsSelfLocked) {
4853                    proc = mPidsSelfLocked.get(pids[i]);
4854                    oomAdj = proc != null ? proc.setAdj : 0;
4855                }
4856            }
4857            long[] tmpUss = new long[1];
4858            pss[i] = Debug.getPss(pids[i], tmpUss);
4859            if (proc != null) {
4860                synchronized (this) {
4861                    if (proc.thread != null && proc.setAdj == oomAdj) {
4862                        // Record this for posterity if the process has been stable.
4863                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4864                    }
4865                }
4866            }
4867        }
4868        return pss;
4869    }
4870
4871    @Override
4872    public void killApplicationProcess(String processName, int uid) {
4873        if (processName == null) {
4874            return;
4875        }
4876
4877        int callerUid = Binder.getCallingUid();
4878        // Only the system server can kill an application
4879        if (callerUid == Process.SYSTEM_UID) {
4880            synchronized (this) {
4881                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4882                if (app != null && app.thread != null) {
4883                    try {
4884                        app.thread.scheduleSuicide();
4885                    } catch (RemoteException e) {
4886                        // If the other end already died, then our work here is done.
4887                    }
4888                } else {
4889                    Slog.w(TAG, "Process/uid not found attempting kill of "
4890                            + processName + " / " + uid);
4891                }
4892            }
4893        } else {
4894            throw new SecurityException(callerUid + " cannot kill app process: " +
4895                    processName);
4896        }
4897    }
4898
4899    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4900        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4901                false, true, false, false, UserHandle.getUserId(uid), reason);
4902        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4903                Uri.fromParts("package", packageName, null));
4904        if (!mProcessesReady) {
4905            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4906                    | Intent.FLAG_RECEIVER_FOREGROUND);
4907        }
4908        intent.putExtra(Intent.EXTRA_UID, uid);
4909        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4910        broadcastIntentLocked(null, null, intent,
4911                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4912                false, false,
4913                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4914    }
4915
4916    private void forceStopUserLocked(int userId, String reason) {
4917        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4918        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4919        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4920                | Intent.FLAG_RECEIVER_FOREGROUND);
4921        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4922        broadcastIntentLocked(null, null, intent,
4923                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4924                false, false,
4925                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4926    }
4927
4928    private final boolean killPackageProcessesLocked(String packageName, int appId,
4929            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4930            boolean doit, boolean evenPersistent, String reason) {
4931        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4932
4933        // Remove all processes this package may have touched: all with the
4934        // same UID (except for the system or root user), and all whose name
4935        // matches the package name.
4936        final int NP = mProcessNames.getMap().size();
4937        for (int ip=0; ip<NP; ip++) {
4938            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4939            final int NA = apps.size();
4940            for (int ia=0; ia<NA; ia++) {
4941                ProcessRecord app = apps.valueAt(ia);
4942                if (app.persistent && !evenPersistent) {
4943                    // we don't kill persistent processes
4944                    continue;
4945                }
4946                if (app.removed) {
4947                    if (doit) {
4948                        procs.add(app);
4949                    }
4950                    continue;
4951                }
4952
4953                // Skip process if it doesn't meet our oom adj requirement.
4954                if (app.setAdj < minOomAdj) {
4955                    continue;
4956                }
4957
4958                // If no package is specified, we call all processes under the
4959                // give user id.
4960                if (packageName == null) {
4961                    if (app.userId != userId) {
4962                        continue;
4963                    }
4964                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4965                        continue;
4966                    }
4967                // Package has been specified, we want to hit all processes
4968                // that match it.  We need to qualify this by the processes
4969                // that are running under the specified app and user ID.
4970                } else {
4971                    final boolean isDep = app.pkgDeps != null
4972                            && app.pkgDeps.contains(packageName);
4973                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
4974                        continue;
4975                    }
4976                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4977                        continue;
4978                    }
4979                    if (!app.pkgList.containsKey(packageName) && !isDep) {
4980                        continue;
4981                    }
4982                }
4983
4984                // Process has passed all conditions, kill it!
4985                if (!doit) {
4986                    return true;
4987                }
4988                app.removed = true;
4989                procs.add(app);
4990            }
4991        }
4992
4993        int N = procs.size();
4994        for (int i=0; i<N; i++) {
4995            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4996        }
4997        updateOomAdjLocked();
4998        return N > 0;
4999    }
5000
5001    private final boolean forceStopPackageLocked(String name, int appId,
5002            boolean callerWillRestart, boolean purgeCache, boolean doit,
5003            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5004        int i;
5005        int N;
5006
5007        if (userId == UserHandle.USER_ALL && name == null) {
5008            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5009        }
5010
5011        if (appId < 0 && name != null) {
5012            try {
5013                appId = UserHandle.getAppId(
5014                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5015            } catch (RemoteException e) {
5016            }
5017        }
5018
5019        if (doit) {
5020            if (name != null) {
5021                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5022                        + " user=" + userId + ": " + reason);
5023            } else {
5024                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5025            }
5026
5027            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5028            for (int ip=pmap.size()-1; ip>=0; ip--) {
5029                SparseArray<Long> ba = pmap.valueAt(ip);
5030                for (i=ba.size()-1; i>=0; i--) {
5031                    boolean remove = false;
5032                    final int entUid = ba.keyAt(i);
5033                    if (name != null) {
5034                        if (userId == UserHandle.USER_ALL) {
5035                            if (UserHandle.getAppId(entUid) == appId) {
5036                                remove = true;
5037                            }
5038                        } else {
5039                            if (entUid == UserHandle.getUid(userId, appId)) {
5040                                remove = true;
5041                            }
5042                        }
5043                    } else if (UserHandle.getUserId(entUid) == userId) {
5044                        remove = true;
5045                    }
5046                    if (remove) {
5047                        ba.removeAt(i);
5048                    }
5049                }
5050                if (ba.size() == 0) {
5051                    pmap.removeAt(ip);
5052                }
5053            }
5054        }
5055
5056        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5057                -100, callerWillRestart, true, doit, evenPersistent,
5058                name == null ? ("stop user " + userId) : ("stop " + name));
5059
5060        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5061            if (!doit) {
5062                return true;
5063            }
5064            didSomething = true;
5065        }
5066
5067        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5068            if (!doit) {
5069                return true;
5070            }
5071            didSomething = true;
5072        }
5073
5074        if (name == null) {
5075            // Remove all sticky broadcasts from this user.
5076            mStickyBroadcasts.remove(userId);
5077        }
5078
5079        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5080        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5081                userId, providers)) {
5082            if (!doit) {
5083                return true;
5084            }
5085            didSomething = true;
5086        }
5087        N = providers.size();
5088        for (i=0; i<N; i++) {
5089            removeDyingProviderLocked(null, providers.get(i), true);
5090        }
5091
5092        // Remove transient permissions granted from/to this package/user
5093        removeUriPermissionsForPackageLocked(name, userId, false);
5094
5095        if (name == null || uninstalling) {
5096            // Remove pending intents.  For now we only do this when force
5097            // stopping users, because we have some problems when doing this
5098            // for packages -- app widgets are not currently cleaned up for
5099            // such packages, so they can be left with bad pending intents.
5100            if (mIntentSenderRecords.size() > 0) {
5101                Iterator<WeakReference<PendingIntentRecord>> it
5102                        = mIntentSenderRecords.values().iterator();
5103                while (it.hasNext()) {
5104                    WeakReference<PendingIntentRecord> wpir = it.next();
5105                    if (wpir == null) {
5106                        it.remove();
5107                        continue;
5108                    }
5109                    PendingIntentRecord pir = wpir.get();
5110                    if (pir == null) {
5111                        it.remove();
5112                        continue;
5113                    }
5114                    if (name == null) {
5115                        // Stopping user, remove all objects for the user.
5116                        if (pir.key.userId != userId) {
5117                            // Not the same user, skip it.
5118                            continue;
5119                        }
5120                    } else {
5121                        if (UserHandle.getAppId(pir.uid) != appId) {
5122                            // Different app id, skip it.
5123                            continue;
5124                        }
5125                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5126                            // Different user, skip it.
5127                            continue;
5128                        }
5129                        if (!pir.key.packageName.equals(name)) {
5130                            // Different package, skip it.
5131                            continue;
5132                        }
5133                    }
5134                    if (!doit) {
5135                        return true;
5136                    }
5137                    didSomething = true;
5138                    it.remove();
5139                    pir.canceled = true;
5140                    if (pir.key.activity != null) {
5141                        pir.key.activity.pendingResults.remove(pir.ref);
5142                    }
5143                }
5144            }
5145        }
5146
5147        if (doit) {
5148            if (purgeCache && name != null) {
5149                AttributeCache ac = AttributeCache.instance();
5150                if (ac != null) {
5151                    ac.removePackage(name);
5152                }
5153            }
5154            if (mBooted) {
5155                mStackSupervisor.resumeTopActivitiesLocked();
5156                mStackSupervisor.scheduleIdleLocked();
5157            }
5158        }
5159
5160        return didSomething;
5161    }
5162
5163    private final boolean removeProcessLocked(ProcessRecord app,
5164            boolean callerWillRestart, boolean allowRestart, String reason) {
5165        final String name = app.processName;
5166        final int uid = app.uid;
5167        if (DEBUG_PROCESSES) Slog.d(
5168            TAG, "Force removing proc " + app.toShortString() + " (" + name
5169            + "/" + uid + ")");
5170
5171        mProcessNames.remove(name, uid);
5172        mIsolatedProcesses.remove(app.uid);
5173        if (mHeavyWeightProcess == app) {
5174            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5175                    mHeavyWeightProcess.userId, 0));
5176            mHeavyWeightProcess = null;
5177        }
5178        boolean needRestart = false;
5179        if (app.pid > 0 && app.pid != MY_PID) {
5180            int pid = app.pid;
5181            synchronized (mPidsSelfLocked) {
5182                mPidsSelfLocked.remove(pid);
5183                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5184            }
5185            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5186            if (app.isolated) {
5187                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5188            }
5189            killUnneededProcessLocked(app, reason);
5190            Process.killProcessGroup(app.info.uid, app.pid);
5191            handleAppDiedLocked(app, true, allowRestart);
5192            removeLruProcessLocked(app);
5193
5194            if (app.persistent && !app.isolated) {
5195                if (!callerWillRestart) {
5196                    addAppLocked(app.info, false, null /* ABI override */);
5197                } else {
5198                    needRestart = true;
5199                }
5200            }
5201        } else {
5202            mRemovedProcesses.add(app);
5203        }
5204
5205        return needRestart;
5206    }
5207
5208    private final void processStartTimedOutLocked(ProcessRecord app) {
5209        final int pid = app.pid;
5210        boolean gone = false;
5211        synchronized (mPidsSelfLocked) {
5212            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5213            if (knownApp != null && knownApp.thread == null) {
5214                mPidsSelfLocked.remove(pid);
5215                gone = true;
5216            }
5217        }
5218
5219        if (gone) {
5220            Slog.w(TAG, "Process " + app + " failed to attach");
5221            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5222                    pid, app.uid, app.processName);
5223            mProcessNames.remove(app.processName, app.uid);
5224            mIsolatedProcesses.remove(app.uid);
5225            if (mHeavyWeightProcess == app) {
5226                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5227                        mHeavyWeightProcess.userId, 0));
5228                mHeavyWeightProcess = null;
5229            }
5230            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5231            if (app.isolated) {
5232                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5233            }
5234            // Take care of any launching providers waiting for this process.
5235            checkAppInLaunchingProvidersLocked(app, true);
5236            // Take care of any services that are waiting for the process.
5237            mServices.processStartTimedOutLocked(app);
5238            killUnneededProcessLocked(app, "start timeout");
5239            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5240                Slog.w(TAG, "Unattached app died before backup, skipping");
5241                try {
5242                    IBackupManager bm = IBackupManager.Stub.asInterface(
5243                            ServiceManager.getService(Context.BACKUP_SERVICE));
5244                    bm.agentDisconnected(app.info.packageName);
5245                } catch (RemoteException e) {
5246                    // Can't happen; the backup manager is local
5247                }
5248            }
5249            if (isPendingBroadcastProcessLocked(pid)) {
5250                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5251                skipPendingBroadcastLocked(pid);
5252            }
5253        } else {
5254            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5255        }
5256    }
5257
5258    private final boolean attachApplicationLocked(IApplicationThread thread,
5259            int pid) {
5260
5261        // Find the application record that is being attached...  either via
5262        // the pid if we are running in multiple processes, or just pull the
5263        // next app record if we are emulating process with anonymous threads.
5264        ProcessRecord app;
5265        if (pid != MY_PID && pid >= 0) {
5266            synchronized (mPidsSelfLocked) {
5267                app = mPidsSelfLocked.get(pid);
5268            }
5269        } else {
5270            app = null;
5271        }
5272
5273        if (app == null) {
5274            Slog.w(TAG, "No pending application record for pid " + pid
5275                    + " (IApplicationThread " + thread + "); dropping process");
5276            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5277            if (pid > 0 && pid != MY_PID) {
5278                Process.killProcessQuiet(pid);
5279                //TODO: Process.killProcessGroup(app.info.uid, pid);
5280            } else {
5281                try {
5282                    thread.scheduleExit();
5283                } catch (Exception e) {
5284                    // Ignore exceptions.
5285                }
5286            }
5287            return false;
5288        }
5289
5290        // If this application record is still attached to a previous
5291        // process, clean it up now.
5292        if (app.thread != null) {
5293            handleAppDiedLocked(app, true, true);
5294        }
5295
5296        // Tell the process all about itself.
5297
5298        if (localLOGV) Slog.v(
5299                TAG, "Binding process pid " + pid + " to record " + app);
5300
5301        final String processName = app.processName;
5302        try {
5303            AppDeathRecipient adr = new AppDeathRecipient(
5304                    app, pid, thread);
5305            thread.asBinder().linkToDeath(adr, 0);
5306            app.deathRecipient = adr;
5307        } catch (RemoteException e) {
5308            app.resetPackageList(mProcessStats);
5309            startProcessLocked(app, "link fail", processName, null /* ABI override */);
5310            return false;
5311        }
5312
5313        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5314
5315        app.makeActive(thread, mProcessStats);
5316        app.curAdj = app.setAdj = -100;
5317        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5318        app.forcingToForeground = null;
5319        updateProcessForegroundLocked(app, false, false);
5320        app.hasShownUi = false;
5321        app.debugging = false;
5322        app.cached = false;
5323
5324        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5325
5326        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5327        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5328
5329        if (!normalMode) {
5330            Slog.i(TAG, "Launching preboot mode app: " + app);
5331        }
5332
5333        if (localLOGV) Slog.v(
5334            TAG, "New app record " + app
5335            + " thread=" + thread.asBinder() + " pid=" + pid);
5336        try {
5337            int testMode = IApplicationThread.DEBUG_OFF;
5338            if (mDebugApp != null && mDebugApp.equals(processName)) {
5339                testMode = mWaitForDebugger
5340                    ? IApplicationThread.DEBUG_WAIT
5341                    : IApplicationThread.DEBUG_ON;
5342                app.debugging = true;
5343                if (mDebugTransient) {
5344                    mDebugApp = mOrigDebugApp;
5345                    mWaitForDebugger = mOrigWaitForDebugger;
5346                }
5347            }
5348            String profileFile = app.instrumentationProfileFile;
5349            ParcelFileDescriptor profileFd = null;
5350            boolean profileAutoStop = false;
5351            if (mProfileApp != null && mProfileApp.equals(processName)) {
5352                mProfileProc = app;
5353                profileFile = mProfileFile;
5354                profileFd = mProfileFd;
5355                profileAutoStop = mAutoStopProfiler;
5356            }
5357            boolean enableOpenGlTrace = false;
5358            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5359                enableOpenGlTrace = true;
5360                mOpenGlTraceApp = null;
5361            }
5362
5363            // If the app is being launched for restore or full backup, set it up specially
5364            boolean isRestrictedBackupMode = false;
5365            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5366                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5367                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5368                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5369            }
5370
5371            ensurePackageDexOpt(app.instrumentationInfo != null
5372                    ? app.instrumentationInfo.packageName
5373                    : app.info.packageName);
5374            if (app.instrumentationClass != null) {
5375                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5376            }
5377            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5378                    + processName + " with config " + mConfiguration);
5379            ApplicationInfo appInfo = app.instrumentationInfo != null
5380                    ? app.instrumentationInfo : app.info;
5381            app.compat = compatibilityInfoForPackageLocked(appInfo);
5382            if (profileFd != null) {
5383                profileFd = profileFd.dup();
5384            }
5385            thread.bindApplication(processName, appInfo, providers,
5386                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5387                    app.instrumentationArguments, app.instrumentationWatcher,
5388                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5389                    isRestrictedBackupMode || !normalMode, app.persistent,
5390                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5391                    mCoreSettingsObserver.getCoreSettingsLocked());
5392            updateLruProcessLocked(app, false, null);
5393            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5394        } catch (Exception e) {
5395            // todo: Yikes!  What should we do?  For now we will try to
5396            // start another process, but that could easily get us in
5397            // an infinite loop of restarting processes...
5398            Slog.w(TAG, "Exception thrown during bind!", e);
5399
5400            app.resetPackageList(mProcessStats);
5401            app.unlinkDeathRecipient();
5402            startProcessLocked(app, "bind fail", processName, null /* ABI override */);
5403            return false;
5404        }
5405
5406        // Remove this record from the list of starting applications.
5407        mPersistentStartingProcesses.remove(app);
5408        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5409                "Attach application locked removing on hold: " + app);
5410        mProcessesOnHold.remove(app);
5411
5412        boolean badApp = false;
5413        boolean didSomething = false;
5414
5415        // See if the top visible activity is waiting to run in this process...
5416        if (normalMode) {
5417            try {
5418                if (mStackSupervisor.attachApplicationLocked(app)) {
5419                    didSomething = true;
5420                }
5421            } catch (Exception e) {
5422                badApp = true;
5423            }
5424        }
5425
5426        // Find any services that should be running in this process...
5427        if (!badApp) {
5428            try {
5429                didSomething |= mServices.attachApplicationLocked(app, processName);
5430            } catch (Exception e) {
5431                badApp = true;
5432            }
5433        }
5434
5435        // Check if a next-broadcast receiver is in this process...
5436        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5437            try {
5438                didSomething |= sendPendingBroadcastsLocked(app);
5439            } catch (Exception e) {
5440                // If the app died trying to launch the receiver we declare it 'bad'
5441                badApp = true;
5442            }
5443        }
5444
5445        // Check whether the next backup agent is in this process...
5446        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5447            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5448            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5449            try {
5450                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5451                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5452                        mBackupTarget.backupMode);
5453            } catch (Exception e) {
5454                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5455                e.printStackTrace();
5456            }
5457        }
5458
5459        if (badApp) {
5460            // todo: Also need to kill application to deal with all
5461            // kinds of exceptions.
5462            handleAppDiedLocked(app, false, true);
5463            return false;
5464        }
5465
5466        if (!didSomething) {
5467            updateOomAdjLocked();
5468        }
5469
5470        return true;
5471    }
5472
5473    @Override
5474    public final void attachApplication(IApplicationThread thread) {
5475        synchronized (this) {
5476            int callingPid = Binder.getCallingPid();
5477            final long origId = Binder.clearCallingIdentity();
5478            attachApplicationLocked(thread, callingPid);
5479            Binder.restoreCallingIdentity(origId);
5480        }
5481    }
5482
5483    @Override
5484    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5485        final long origId = Binder.clearCallingIdentity();
5486        synchronized (this) {
5487            ActivityStack stack = ActivityRecord.getStackLocked(token);
5488            if (stack != null) {
5489                ActivityRecord r =
5490                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5491                if (stopProfiling) {
5492                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5493                        try {
5494                            mProfileFd.close();
5495                        } catch (IOException e) {
5496                        }
5497                        clearProfilerLocked();
5498                    }
5499                }
5500            }
5501        }
5502        Binder.restoreCallingIdentity(origId);
5503    }
5504
5505    void enableScreenAfterBoot() {
5506        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5507                SystemClock.uptimeMillis());
5508        mWindowManager.enableScreenAfterBoot();
5509
5510        synchronized (this) {
5511            updateEventDispatchingLocked();
5512        }
5513    }
5514
5515    @Override
5516    public void showBootMessage(final CharSequence msg, final boolean always) {
5517        enforceNotIsolatedCaller("showBootMessage");
5518        mWindowManager.showBootMessage(msg, always);
5519    }
5520
5521    @Override
5522    public void dismissKeyguardOnNextActivity() {
5523        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5524        final long token = Binder.clearCallingIdentity();
5525        try {
5526            synchronized (this) {
5527                if (DEBUG_LOCKSCREEN) logLockScreen("");
5528                if (mLockScreenShown) {
5529                    mLockScreenShown = false;
5530                    comeOutOfSleepIfNeededLocked();
5531                }
5532                mStackSupervisor.setDismissKeyguard(true);
5533            }
5534        } finally {
5535            Binder.restoreCallingIdentity(token);
5536        }
5537    }
5538
5539    final void finishBooting() {
5540        // Register receivers to handle package update events
5541        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5542
5543        synchronized (this) {
5544            // Ensure that any processes we had put on hold are now started
5545            // up.
5546            final int NP = mProcessesOnHold.size();
5547            if (NP > 0) {
5548                ArrayList<ProcessRecord> procs =
5549                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5550                for (int ip=0; ip<NP; ip++) {
5551                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5552                            + procs.get(ip));
5553                    startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */);
5554                }
5555            }
5556
5557            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5558                // Start looking for apps that are abusing wake locks.
5559                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5560                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5561                // Tell anyone interested that we are done booting!
5562                SystemProperties.set("sys.boot_completed", "1");
5563                SystemProperties.set("dev.bootcomplete", "1");
5564                for (int i=0; i<mStartedUsers.size(); i++) {
5565                    UserStartedState uss = mStartedUsers.valueAt(i);
5566                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5567                        uss.mState = UserStartedState.STATE_RUNNING;
5568                        final int userId = mStartedUsers.keyAt(i);
5569                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5570                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5571                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5572                        broadcastIntentLocked(null, null, intent, null,
5573                                new IIntentReceiver.Stub() {
5574                                    @Override
5575                                    public void performReceive(Intent intent, int resultCode,
5576                                            String data, Bundle extras, boolean ordered,
5577                                            boolean sticky, int sendingUser) {
5578                                        synchronized (ActivityManagerService.this) {
5579                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5580                                                    true, false);
5581                                        }
5582                                    }
5583                                },
5584                                0, null, null,
5585                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5586                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5587                                userId);
5588                    }
5589                }
5590                scheduleStartProfilesLocked();
5591            }
5592        }
5593    }
5594
5595    final void ensureBootCompleted() {
5596        boolean booting;
5597        boolean enableScreen;
5598        synchronized (this) {
5599            booting = mBooting;
5600            mBooting = false;
5601            enableScreen = !mBooted;
5602            mBooted = true;
5603        }
5604
5605        if (booting) {
5606            finishBooting();
5607        }
5608
5609        if (enableScreen) {
5610            enableScreenAfterBoot();
5611        }
5612    }
5613
5614    @Override
5615    public final void activityResumed(IBinder token) {
5616        final long origId = Binder.clearCallingIdentity();
5617        synchronized(this) {
5618            ActivityStack stack = ActivityRecord.getStackLocked(token);
5619            if (stack != null) {
5620                ActivityRecord.activityResumedLocked(token);
5621            }
5622        }
5623        Binder.restoreCallingIdentity(origId);
5624    }
5625
5626    @Override
5627    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5628        final long origId = Binder.clearCallingIdentity();
5629        synchronized(this) {
5630            ActivityStack stack = ActivityRecord.getStackLocked(token);
5631            if (stack != null) {
5632                stack.activityPausedLocked(token, false, persistentState);
5633            }
5634        }
5635        Binder.restoreCallingIdentity(origId);
5636    }
5637
5638    @Override
5639    public final void activityStopped(IBinder token, Bundle icicle,
5640            PersistableBundle persistentState, CharSequence description) {
5641        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5642
5643        // Refuse possible leaked file descriptors
5644        if (icicle != null && icicle.hasFileDescriptors()) {
5645            throw new IllegalArgumentException("File descriptors passed in Bundle");
5646        }
5647
5648        final long origId = Binder.clearCallingIdentity();
5649
5650        synchronized (this) {
5651            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5652            if (r != null) {
5653                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5654            }
5655        }
5656
5657        trimApplications();
5658
5659        Binder.restoreCallingIdentity(origId);
5660    }
5661
5662    @Override
5663    public final void activityDestroyed(IBinder token) {
5664        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5665        synchronized (this) {
5666            ActivityStack stack = ActivityRecord.getStackLocked(token);
5667            if (stack != null) {
5668                stack.activityDestroyedLocked(token);
5669            }
5670        }
5671    }
5672
5673    @Override
5674    public final void mediaResourcesReleased(IBinder token) {
5675        final long origId = Binder.clearCallingIdentity();
5676        try {
5677            synchronized (this) {
5678                ActivityStack stack = ActivityRecord.getStackLocked(token);
5679                if (stack != null) {
5680                    stack.mediaResourcesReleased(token);
5681                }
5682            }
5683        } finally {
5684            Binder.restoreCallingIdentity(origId);
5685        }
5686    }
5687
5688    @Override
5689    public final void notifyLaunchTaskBehindComplete(IBinder token) {
5690        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
5691    }
5692
5693    @Override
5694    public String getCallingPackage(IBinder token) {
5695        synchronized (this) {
5696            ActivityRecord r = getCallingRecordLocked(token);
5697            return r != null ? r.info.packageName : null;
5698        }
5699    }
5700
5701    @Override
5702    public ComponentName getCallingActivity(IBinder token) {
5703        synchronized (this) {
5704            ActivityRecord r = getCallingRecordLocked(token);
5705            return r != null ? r.intent.getComponent() : null;
5706        }
5707    }
5708
5709    private ActivityRecord getCallingRecordLocked(IBinder token) {
5710        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5711        if (r == null) {
5712            return null;
5713        }
5714        return r.resultTo;
5715    }
5716
5717    @Override
5718    public ComponentName getActivityClassForToken(IBinder token) {
5719        synchronized(this) {
5720            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5721            if (r == null) {
5722                return null;
5723            }
5724            return r.intent.getComponent();
5725        }
5726    }
5727
5728    @Override
5729    public String getPackageForToken(IBinder token) {
5730        synchronized(this) {
5731            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5732            if (r == null) {
5733                return null;
5734            }
5735            return r.packageName;
5736        }
5737    }
5738
5739    @Override
5740    public IIntentSender getIntentSender(int type,
5741            String packageName, IBinder token, String resultWho,
5742            int requestCode, Intent[] intents, String[] resolvedTypes,
5743            int flags, Bundle options, int userId) {
5744        enforceNotIsolatedCaller("getIntentSender");
5745        // Refuse possible leaked file descriptors
5746        if (intents != null) {
5747            if (intents.length < 1) {
5748                throw new IllegalArgumentException("Intents array length must be >= 1");
5749            }
5750            for (int i=0; i<intents.length; i++) {
5751                Intent intent = intents[i];
5752                if (intent != null) {
5753                    if (intent.hasFileDescriptors()) {
5754                        throw new IllegalArgumentException("File descriptors passed in Intent");
5755                    }
5756                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5757                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5758                        throw new IllegalArgumentException(
5759                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5760                    }
5761                    intents[i] = new Intent(intent);
5762                }
5763            }
5764            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5765                throw new IllegalArgumentException(
5766                        "Intent array length does not match resolvedTypes length");
5767            }
5768        }
5769        if (options != null) {
5770            if (options.hasFileDescriptors()) {
5771                throw new IllegalArgumentException("File descriptors passed in options");
5772            }
5773        }
5774
5775        synchronized(this) {
5776            int callingUid = Binder.getCallingUid();
5777            int origUserId = userId;
5778            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5779                    type == ActivityManager.INTENT_SENDER_BROADCAST,
5780                    ALLOW_NON_FULL, "getIntentSender", null);
5781            if (origUserId == UserHandle.USER_CURRENT) {
5782                // We don't want to evaluate this until the pending intent is
5783                // actually executed.  However, we do want to always do the
5784                // security checking for it above.
5785                userId = UserHandle.USER_CURRENT;
5786            }
5787            try {
5788                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5789                    int uid = AppGlobals.getPackageManager()
5790                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5791                    if (!UserHandle.isSameApp(callingUid, uid)) {
5792                        String msg = "Permission Denial: getIntentSender() from pid="
5793                            + Binder.getCallingPid()
5794                            + ", uid=" + Binder.getCallingUid()
5795                            + ", (need uid=" + uid + ")"
5796                            + " is not allowed to send as package " + packageName;
5797                        Slog.w(TAG, msg);
5798                        throw new SecurityException(msg);
5799                    }
5800                }
5801
5802                return getIntentSenderLocked(type, packageName, callingUid, userId,
5803                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5804
5805            } catch (RemoteException e) {
5806                throw new SecurityException(e);
5807            }
5808        }
5809    }
5810
5811    IIntentSender getIntentSenderLocked(int type, String packageName,
5812            int callingUid, int userId, IBinder token, String resultWho,
5813            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5814            Bundle options) {
5815        if (DEBUG_MU)
5816            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5817        ActivityRecord activity = null;
5818        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5819            activity = ActivityRecord.isInStackLocked(token);
5820            if (activity == null) {
5821                return null;
5822            }
5823            if (activity.finishing) {
5824                return null;
5825            }
5826        }
5827
5828        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5829        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5830        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5831        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5832                |PendingIntent.FLAG_UPDATE_CURRENT);
5833
5834        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5835                type, packageName, activity, resultWho,
5836                requestCode, intents, resolvedTypes, flags, options, userId);
5837        WeakReference<PendingIntentRecord> ref;
5838        ref = mIntentSenderRecords.get(key);
5839        PendingIntentRecord rec = ref != null ? ref.get() : null;
5840        if (rec != null) {
5841            if (!cancelCurrent) {
5842                if (updateCurrent) {
5843                    if (rec.key.requestIntent != null) {
5844                        rec.key.requestIntent.replaceExtras(intents != null ?
5845                                intents[intents.length - 1] : null);
5846                    }
5847                    if (intents != null) {
5848                        intents[intents.length-1] = rec.key.requestIntent;
5849                        rec.key.allIntents = intents;
5850                        rec.key.allResolvedTypes = resolvedTypes;
5851                    } else {
5852                        rec.key.allIntents = null;
5853                        rec.key.allResolvedTypes = null;
5854                    }
5855                }
5856                return rec;
5857            }
5858            rec.canceled = true;
5859            mIntentSenderRecords.remove(key);
5860        }
5861        if (noCreate) {
5862            return rec;
5863        }
5864        rec = new PendingIntentRecord(this, key, callingUid);
5865        mIntentSenderRecords.put(key, rec.ref);
5866        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5867            if (activity.pendingResults == null) {
5868                activity.pendingResults
5869                        = new HashSet<WeakReference<PendingIntentRecord>>();
5870            }
5871            activity.pendingResults.add(rec.ref);
5872        }
5873        return rec;
5874    }
5875
5876    @Override
5877    public void cancelIntentSender(IIntentSender sender) {
5878        if (!(sender instanceof PendingIntentRecord)) {
5879            return;
5880        }
5881        synchronized(this) {
5882            PendingIntentRecord rec = (PendingIntentRecord)sender;
5883            try {
5884                int uid = AppGlobals.getPackageManager()
5885                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5886                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5887                    String msg = "Permission Denial: cancelIntentSender() from pid="
5888                        + Binder.getCallingPid()
5889                        + ", uid=" + Binder.getCallingUid()
5890                        + " is not allowed to cancel packges "
5891                        + rec.key.packageName;
5892                    Slog.w(TAG, msg);
5893                    throw new SecurityException(msg);
5894                }
5895            } catch (RemoteException e) {
5896                throw new SecurityException(e);
5897            }
5898            cancelIntentSenderLocked(rec, true);
5899        }
5900    }
5901
5902    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5903        rec.canceled = true;
5904        mIntentSenderRecords.remove(rec.key);
5905        if (cleanActivity && rec.key.activity != null) {
5906            rec.key.activity.pendingResults.remove(rec.ref);
5907        }
5908    }
5909
5910    @Override
5911    public String getPackageForIntentSender(IIntentSender pendingResult) {
5912        if (!(pendingResult instanceof PendingIntentRecord)) {
5913            return null;
5914        }
5915        try {
5916            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5917            return res.key.packageName;
5918        } catch (ClassCastException e) {
5919        }
5920        return null;
5921    }
5922
5923    @Override
5924    public int getUidForIntentSender(IIntentSender sender) {
5925        if (sender instanceof PendingIntentRecord) {
5926            try {
5927                PendingIntentRecord res = (PendingIntentRecord)sender;
5928                return res.uid;
5929            } catch (ClassCastException e) {
5930            }
5931        }
5932        return -1;
5933    }
5934
5935    @Override
5936    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5937        if (!(pendingResult instanceof PendingIntentRecord)) {
5938            return false;
5939        }
5940        try {
5941            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5942            if (res.key.allIntents == null) {
5943                return false;
5944            }
5945            for (int i=0; i<res.key.allIntents.length; i++) {
5946                Intent intent = res.key.allIntents[i];
5947                if (intent.getPackage() != null && intent.getComponent() != null) {
5948                    return false;
5949                }
5950            }
5951            return true;
5952        } catch (ClassCastException e) {
5953        }
5954        return false;
5955    }
5956
5957    @Override
5958    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5959        if (!(pendingResult instanceof PendingIntentRecord)) {
5960            return false;
5961        }
5962        try {
5963            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5964            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5965                return true;
5966            }
5967            return false;
5968        } catch (ClassCastException e) {
5969        }
5970        return false;
5971    }
5972
5973    @Override
5974    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5975        if (!(pendingResult instanceof PendingIntentRecord)) {
5976            return null;
5977        }
5978        try {
5979            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5980            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5981        } catch (ClassCastException e) {
5982        }
5983        return null;
5984    }
5985
5986    @Override
5987    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5988        if (!(pendingResult instanceof PendingIntentRecord)) {
5989            return null;
5990        }
5991        try {
5992            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5993            Intent intent = res.key.requestIntent;
5994            if (intent != null) {
5995                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5996                        || res.lastTagPrefix.equals(prefix))) {
5997                    return res.lastTag;
5998                }
5999                res.lastTagPrefix = prefix;
6000                StringBuilder sb = new StringBuilder(128);
6001                if (prefix != null) {
6002                    sb.append(prefix);
6003                }
6004                if (intent.getAction() != null) {
6005                    sb.append(intent.getAction());
6006                } else if (intent.getComponent() != null) {
6007                    intent.getComponent().appendShortString(sb);
6008                } else {
6009                    sb.append("?");
6010                }
6011                return res.lastTag = sb.toString();
6012            }
6013        } catch (ClassCastException e) {
6014        }
6015        return null;
6016    }
6017
6018    @Override
6019    public void setProcessLimit(int max) {
6020        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6021                "setProcessLimit()");
6022        synchronized (this) {
6023            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6024            mProcessLimitOverride = max;
6025        }
6026        trimApplications();
6027    }
6028
6029    @Override
6030    public int getProcessLimit() {
6031        synchronized (this) {
6032            return mProcessLimitOverride;
6033        }
6034    }
6035
6036    void foregroundTokenDied(ForegroundToken token) {
6037        synchronized (ActivityManagerService.this) {
6038            synchronized (mPidsSelfLocked) {
6039                ForegroundToken cur
6040                    = mForegroundProcesses.get(token.pid);
6041                if (cur != token) {
6042                    return;
6043                }
6044                mForegroundProcesses.remove(token.pid);
6045                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6046                if (pr == null) {
6047                    return;
6048                }
6049                pr.forcingToForeground = null;
6050                updateProcessForegroundLocked(pr, false, false);
6051            }
6052            updateOomAdjLocked();
6053        }
6054    }
6055
6056    @Override
6057    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6058        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6059                "setProcessForeground()");
6060        synchronized(this) {
6061            boolean changed = false;
6062
6063            synchronized (mPidsSelfLocked) {
6064                ProcessRecord pr = mPidsSelfLocked.get(pid);
6065                if (pr == null && isForeground) {
6066                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6067                    return;
6068                }
6069                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6070                if (oldToken != null) {
6071                    oldToken.token.unlinkToDeath(oldToken, 0);
6072                    mForegroundProcesses.remove(pid);
6073                    if (pr != null) {
6074                        pr.forcingToForeground = null;
6075                    }
6076                    changed = true;
6077                }
6078                if (isForeground && token != null) {
6079                    ForegroundToken newToken = new ForegroundToken() {
6080                        @Override
6081                        public void binderDied() {
6082                            foregroundTokenDied(this);
6083                        }
6084                    };
6085                    newToken.pid = pid;
6086                    newToken.token = token;
6087                    try {
6088                        token.linkToDeath(newToken, 0);
6089                        mForegroundProcesses.put(pid, newToken);
6090                        pr.forcingToForeground = token;
6091                        changed = true;
6092                    } catch (RemoteException e) {
6093                        // If the process died while doing this, we will later
6094                        // do the cleanup with the process death link.
6095                    }
6096                }
6097            }
6098
6099            if (changed) {
6100                updateOomAdjLocked();
6101            }
6102        }
6103    }
6104
6105    // =========================================================
6106    // PERMISSIONS
6107    // =========================================================
6108
6109    static class PermissionController extends IPermissionController.Stub {
6110        ActivityManagerService mActivityManagerService;
6111        PermissionController(ActivityManagerService activityManagerService) {
6112            mActivityManagerService = activityManagerService;
6113        }
6114
6115        @Override
6116        public boolean checkPermission(String permission, int pid, int uid) {
6117            return mActivityManagerService.checkPermission(permission, pid,
6118                    uid) == PackageManager.PERMISSION_GRANTED;
6119        }
6120    }
6121
6122    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6123        @Override
6124        public int checkComponentPermission(String permission, int pid, int uid,
6125                int owningUid, boolean exported) {
6126            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6127                    owningUid, exported);
6128        }
6129
6130        @Override
6131        public Object getAMSLock() {
6132            return ActivityManagerService.this;
6133        }
6134    }
6135
6136    /**
6137     * This can be called with or without the global lock held.
6138     */
6139    int checkComponentPermission(String permission, int pid, int uid,
6140            int owningUid, boolean exported) {
6141        // We might be performing an operation on behalf of an indirect binder
6142        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6143        // client identity accordingly before proceeding.
6144        Identity tlsIdentity = sCallerIdentity.get();
6145        if (tlsIdentity != null) {
6146            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6147                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6148            uid = tlsIdentity.uid;
6149            pid = tlsIdentity.pid;
6150        }
6151
6152        if (pid == MY_PID) {
6153            return PackageManager.PERMISSION_GRANTED;
6154        }
6155
6156        return ActivityManager.checkComponentPermission(permission, uid,
6157                owningUid, exported);
6158    }
6159
6160    /**
6161     * As the only public entry point for permissions checking, this method
6162     * can enforce the semantic that requesting a check on a null global
6163     * permission is automatically denied.  (Internally a null permission
6164     * string is used when calling {@link #checkComponentPermission} in cases
6165     * when only uid-based security is needed.)
6166     *
6167     * This can be called with or without the global lock held.
6168     */
6169    @Override
6170    public int checkPermission(String permission, int pid, int uid) {
6171        if (permission == null) {
6172            return PackageManager.PERMISSION_DENIED;
6173        }
6174        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6175    }
6176
6177    /**
6178     * Binder IPC calls go through the public entry point.
6179     * This can be called with or without the global lock held.
6180     */
6181    int checkCallingPermission(String permission) {
6182        return checkPermission(permission,
6183                Binder.getCallingPid(),
6184                UserHandle.getAppId(Binder.getCallingUid()));
6185    }
6186
6187    /**
6188     * This can be called with or without the global lock held.
6189     */
6190    void enforceCallingPermission(String permission, String func) {
6191        if (checkCallingPermission(permission)
6192                == PackageManager.PERMISSION_GRANTED) {
6193            return;
6194        }
6195
6196        String msg = "Permission Denial: " + func + " from pid="
6197                + Binder.getCallingPid()
6198                + ", uid=" + Binder.getCallingUid()
6199                + " requires " + permission;
6200        Slog.w(TAG, msg);
6201        throw new SecurityException(msg);
6202    }
6203
6204    /**
6205     * Determine if UID is holding permissions required to access {@link Uri} in
6206     * the given {@link ProviderInfo}. Final permission checking is always done
6207     * in {@link ContentProvider}.
6208     */
6209    private final boolean checkHoldingPermissionsLocked(
6210            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6211        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6212                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6213        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6214            return false;
6215        }
6216        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6217    }
6218
6219    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6220            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6221        if (pi.applicationInfo.uid == uid) {
6222            return true;
6223        } else if (!pi.exported) {
6224            return false;
6225        }
6226
6227        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6228        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6229        try {
6230            // check if target holds top-level <provider> permissions
6231            if (!readMet && pi.readPermission != null && considerUidPermissions
6232                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6233                readMet = true;
6234            }
6235            if (!writeMet && pi.writePermission != null && considerUidPermissions
6236                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6237                writeMet = true;
6238            }
6239
6240            // track if unprotected read/write is allowed; any denied
6241            // <path-permission> below removes this ability
6242            boolean allowDefaultRead = pi.readPermission == null;
6243            boolean allowDefaultWrite = pi.writePermission == null;
6244
6245            // check if target holds any <path-permission> that match uri
6246            final PathPermission[] pps = pi.pathPermissions;
6247            if (pps != null) {
6248                final String path = grantUri.uri.getPath();
6249                int i = pps.length;
6250                while (i > 0 && (!readMet || !writeMet)) {
6251                    i--;
6252                    PathPermission pp = pps[i];
6253                    if (pp.match(path)) {
6254                        if (!readMet) {
6255                            final String pprperm = pp.getReadPermission();
6256                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6257                                    + pprperm + " for " + pp.getPath()
6258                                    + ": match=" + pp.match(path)
6259                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6260                            if (pprperm != null) {
6261                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6262                                        == PERMISSION_GRANTED) {
6263                                    readMet = true;
6264                                } else {
6265                                    allowDefaultRead = false;
6266                                }
6267                            }
6268                        }
6269                        if (!writeMet) {
6270                            final String ppwperm = pp.getWritePermission();
6271                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6272                                    + ppwperm + " for " + pp.getPath()
6273                                    + ": match=" + pp.match(path)
6274                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6275                            if (ppwperm != null) {
6276                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6277                                        == PERMISSION_GRANTED) {
6278                                    writeMet = true;
6279                                } else {
6280                                    allowDefaultWrite = false;
6281                                }
6282                            }
6283                        }
6284                    }
6285                }
6286            }
6287
6288            // grant unprotected <provider> read/write, if not blocked by
6289            // <path-permission> above
6290            if (allowDefaultRead) readMet = true;
6291            if (allowDefaultWrite) writeMet = true;
6292
6293        } catch (RemoteException e) {
6294            return false;
6295        }
6296
6297        return readMet && writeMet;
6298    }
6299
6300    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6301        ProviderInfo pi = null;
6302        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6303        if (cpr != null) {
6304            pi = cpr.info;
6305        } else {
6306            try {
6307                pi = AppGlobals.getPackageManager().resolveContentProvider(
6308                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6309            } catch (RemoteException ex) {
6310            }
6311        }
6312        return pi;
6313    }
6314
6315    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6316        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6317        if (targetUris != null) {
6318            return targetUris.get(grantUri);
6319        }
6320        return null;
6321    }
6322
6323    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6324            String targetPkg, int targetUid, GrantUri grantUri) {
6325        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6326        if (targetUris == null) {
6327            targetUris = Maps.newArrayMap();
6328            mGrantedUriPermissions.put(targetUid, targetUris);
6329        }
6330
6331        UriPermission perm = targetUris.get(grantUri);
6332        if (perm == null) {
6333            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6334            targetUris.put(grantUri, perm);
6335        }
6336
6337        return perm;
6338    }
6339
6340    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6341            final int modeFlags) {
6342        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6343        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6344                : UriPermission.STRENGTH_OWNED;
6345
6346        // Root gets to do everything.
6347        if (uid == 0) {
6348            return true;
6349        }
6350
6351        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6352        if (perms == null) return false;
6353
6354        // First look for exact match
6355        final UriPermission exactPerm = perms.get(grantUri);
6356        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6357            return true;
6358        }
6359
6360        // No exact match, look for prefixes
6361        final int N = perms.size();
6362        for (int i = 0; i < N; i++) {
6363            final UriPermission perm = perms.valueAt(i);
6364            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6365                    && perm.getStrength(modeFlags) >= minStrength) {
6366                return true;
6367            }
6368        }
6369
6370        return false;
6371    }
6372
6373    @Override
6374    public int checkUriPermission(Uri uri, int pid, int uid,
6375            final int modeFlags, int userId) {
6376        enforceNotIsolatedCaller("checkUriPermission");
6377
6378        // Another redirected-binder-call permissions check as in
6379        // {@link checkComponentPermission}.
6380        Identity tlsIdentity = sCallerIdentity.get();
6381        if (tlsIdentity != null) {
6382            uid = tlsIdentity.uid;
6383            pid = tlsIdentity.pid;
6384        }
6385
6386        // Our own process gets to do everything.
6387        if (pid == MY_PID) {
6388            return PackageManager.PERMISSION_GRANTED;
6389        }
6390        synchronized (this) {
6391            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6392                    ? PackageManager.PERMISSION_GRANTED
6393                    : PackageManager.PERMISSION_DENIED;
6394        }
6395    }
6396
6397    /**
6398     * Check if the targetPkg can be granted permission to access uri by
6399     * the callingUid using the given modeFlags.  Throws a security exception
6400     * if callingUid is not allowed to do this.  Returns the uid of the target
6401     * if the URI permission grant should be performed; returns -1 if it is not
6402     * needed (for example targetPkg already has permission to access the URI).
6403     * If you already know the uid of the target, you can supply it in
6404     * lastTargetUid else set that to -1.
6405     */
6406    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6407            final int modeFlags, int lastTargetUid) {
6408        if (!Intent.isAccessUriMode(modeFlags)) {
6409            return -1;
6410        }
6411
6412        if (targetPkg != null) {
6413            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6414                    "Checking grant " + targetPkg + " permission to " + grantUri);
6415        }
6416
6417        final IPackageManager pm = AppGlobals.getPackageManager();
6418
6419        // If this is not a content: uri, we can't do anything with it.
6420        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6421            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6422                    "Can't grant URI permission for non-content URI: " + grantUri);
6423            return -1;
6424        }
6425
6426        final String authority = grantUri.uri.getAuthority();
6427        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6428        if (pi == null) {
6429            Slog.w(TAG, "No content provider found for permission check: " +
6430                    grantUri.uri.toSafeString());
6431            return -1;
6432        }
6433
6434        int targetUid = lastTargetUid;
6435        if (targetUid < 0 && targetPkg != null) {
6436            try {
6437                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6438                if (targetUid < 0) {
6439                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6440                            "Can't grant URI permission no uid for: " + targetPkg);
6441                    return -1;
6442                }
6443            } catch (RemoteException ex) {
6444                return -1;
6445            }
6446        }
6447
6448        if (targetUid >= 0) {
6449            // First...  does the target actually need this permission?
6450            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6451                // No need to grant the target this permission.
6452                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6453                        "Target " + targetPkg + " already has full permission to " + grantUri);
6454                return -1;
6455            }
6456        } else {
6457            // First...  there is no target package, so can anyone access it?
6458            boolean allowed = pi.exported;
6459            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6460                if (pi.readPermission != null) {
6461                    allowed = false;
6462                }
6463            }
6464            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6465                if (pi.writePermission != null) {
6466                    allowed = false;
6467                }
6468            }
6469            if (allowed) {
6470                return -1;
6471            }
6472        }
6473
6474        /* There is a special cross user grant if:
6475         * - The target is on another user.
6476         * - Apps on the current user can access the uri without any uid permissions.
6477         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6478         * grant uri permissions.
6479         */
6480        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6481                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6482                modeFlags, false /*without considering the uid permissions*/);
6483
6484        // Second...  is the provider allowing granting of URI permissions?
6485        if (!specialCrossUserGrant) {
6486            if (!pi.grantUriPermissions) {
6487                throw new SecurityException("Provider " + pi.packageName
6488                        + "/" + pi.name
6489                        + " does not allow granting of Uri permissions (uri "
6490                        + grantUri + ")");
6491            }
6492            if (pi.uriPermissionPatterns != null) {
6493                final int N = pi.uriPermissionPatterns.length;
6494                boolean allowed = false;
6495                for (int i=0; i<N; i++) {
6496                    if (pi.uriPermissionPatterns[i] != null
6497                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6498                        allowed = true;
6499                        break;
6500                    }
6501                }
6502                if (!allowed) {
6503                    throw new SecurityException("Provider " + pi.packageName
6504                            + "/" + pi.name
6505                            + " does not allow granting of permission to path of Uri "
6506                            + grantUri);
6507                }
6508            }
6509        }
6510
6511        // Third...  does the caller itself have permission to access
6512        // this uri?
6513        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6514            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6515                // Require they hold a strong enough Uri permission
6516                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6517                    throw new SecurityException("Uid " + callingUid
6518                            + " does not have permission to uri " + grantUri);
6519                }
6520            }
6521        }
6522        return targetUid;
6523    }
6524
6525    @Override
6526    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6527            final int modeFlags, int userId) {
6528        enforceNotIsolatedCaller("checkGrantUriPermission");
6529        synchronized(this) {
6530            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6531                    new GrantUri(userId, uri, false), modeFlags, -1);
6532        }
6533    }
6534
6535    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6536            final int modeFlags, UriPermissionOwner owner) {
6537        if (!Intent.isAccessUriMode(modeFlags)) {
6538            return;
6539        }
6540
6541        // So here we are: the caller has the assumed permission
6542        // to the uri, and the target doesn't.  Let's now give this to
6543        // the target.
6544
6545        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6546                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6547
6548        final String authority = grantUri.uri.getAuthority();
6549        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6550        if (pi == null) {
6551            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6552            return;
6553        }
6554
6555        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6556            grantUri.prefix = true;
6557        }
6558        final UriPermission perm = findOrCreateUriPermissionLocked(
6559                pi.packageName, targetPkg, targetUid, grantUri);
6560        perm.grantModes(modeFlags, owner);
6561    }
6562
6563    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6564            final int modeFlags, UriPermissionOwner owner) {
6565        if (targetPkg == null) {
6566            throw new NullPointerException("targetPkg");
6567        }
6568
6569        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6570                -1);
6571        if (targetUid < 0) {
6572            return;
6573        }
6574
6575        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6576                owner);
6577    }
6578
6579    static class NeededUriGrants extends ArrayList<GrantUri> {
6580        final String targetPkg;
6581        final int targetUid;
6582        final int flags;
6583
6584        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6585            this.targetPkg = targetPkg;
6586            this.targetUid = targetUid;
6587            this.flags = flags;
6588        }
6589    }
6590
6591    /**
6592     * Like checkGrantUriPermissionLocked, but takes an Intent.
6593     */
6594    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6595            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6596        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6597                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6598                + " clip=" + (intent != null ? intent.getClipData() : null)
6599                + " from " + intent + "; flags=0x"
6600                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6601
6602        if (targetPkg == null) {
6603            throw new NullPointerException("targetPkg");
6604        }
6605
6606        if (intent == null) {
6607            return null;
6608        }
6609        Uri data = intent.getData();
6610        ClipData clip = intent.getClipData();
6611        if (data == null && clip == null) {
6612            return null;
6613        }
6614        final IPackageManager pm = AppGlobals.getPackageManager();
6615        int targetUid;
6616        if (needed != null) {
6617            targetUid = needed.targetUid;
6618        } else {
6619            try {
6620                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6621            } catch (RemoteException ex) {
6622                return null;
6623            }
6624            if (targetUid < 0) {
6625                if (DEBUG_URI_PERMISSION) {
6626                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6627                            + " on user " + targetUserId);
6628                }
6629                return null;
6630            }
6631        }
6632        if (data != null) {
6633            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6634            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6635                    targetUid);
6636            if (targetUid > 0) {
6637                if (needed == null) {
6638                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6639                }
6640                needed.add(grantUri);
6641            }
6642        }
6643        if (clip != null) {
6644            for (int i=0; i<clip.getItemCount(); i++) {
6645                Uri uri = clip.getItemAt(i).getUri();
6646                if (uri != null) {
6647                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6648                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6649                            targetUid);
6650                    if (targetUid > 0) {
6651                        if (needed == null) {
6652                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6653                        }
6654                        needed.add(grantUri);
6655                    }
6656                } else {
6657                    Intent clipIntent = clip.getItemAt(i).getIntent();
6658                    if (clipIntent != null) {
6659                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6660                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6661                        if (newNeeded != null) {
6662                            needed = newNeeded;
6663                        }
6664                    }
6665                }
6666            }
6667        }
6668
6669        return needed;
6670    }
6671
6672    /**
6673     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6674     */
6675    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6676            UriPermissionOwner owner) {
6677        if (needed != null) {
6678            for (int i=0; i<needed.size(); i++) {
6679                GrantUri grantUri = needed.get(i);
6680                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6681                        grantUri, needed.flags, owner);
6682            }
6683        }
6684    }
6685
6686    void grantUriPermissionFromIntentLocked(int callingUid,
6687            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6688        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6689                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6690        if (needed == null) {
6691            return;
6692        }
6693
6694        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6695    }
6696
6697    @Override
6698    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6699            final int modeFlags, int userId) {
6700        enforceNotIsolatedCaller("grantUriPermission");
6701        GrantUri grantUri = new GrantUri(userId, uri, false);
6702        synchronized(this) {
6703            final ProcessRecord r = getRecordForAppLocked(caller);
6704            if (r == null) {
6705                throw new SecurityException("Unable to find app for caller "
6706                        + caller
6707                        + " when granting permission to uri " + grantUri);
6708            }
6709            if (targetPkg == null) {
6710                throw new IllegalArgumentException("null target");
6711            }
6712            if (grantUri == null) {
6713                throw new IllegalArgumentException("null uri");
6714            }
6715
6716            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6717                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6718                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6719                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6720
6721            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null);
6722        }
6723    }
6724
6725    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6726        if (perm.modeFlags == 0) {
6727            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6728                    perm.targetUid);
6729            if (perms != null) {
6730                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6731                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6732
6733                perms.remove(perm.uri);
6734                if (perms.isEmpty()) {
6735                    mGrantedUriPermissions.remove(perm.targetUid);
6736                }
6737            }
6738        }
6739    }
6740
6741    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6742        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6743
6744        final IPackageManager pm = AppGlobals.getPackageManager();
6745        final String authority = grantUri.uri.getAuthority();
6746        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6747        if (pi == null) {
6748            Slog.w(TAG, "No content provider found for permission revoke: "
6749                    + grantUri.toSafeString());
6750            return;
6751        }
6752
6753        // Does the caller have this permission on the URI?
6754        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6755            // Right now, if you are not the original owner of the permission,
6756            // you are not allowed to revoke it.
6757            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6758                throw new SecurityException("Uid " + callingUid
6759                        + " does not have permission to uri " + grantUri);
6760            //}
6761        }
6762
6763        boolean persistChanged = false;
6764
6765        // Go through all of the permissions and remove any that match.
6766        int N = mGrantedUriPermissions.size();
6767        for (int i = 0; i < N; i++) {
6768            final int targetUid = mGrantedUriPermissions.keyAt(i);
6769            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6770
6771            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6772                final UriPermission perm = it.next();
6773                if (perm.uri.sourceUserId == grantUri.sourceUserId
6774                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6775                    if (DEBUG_URI_PERMISSION)
6776                        Slog.v(TAG,
6777                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6778                    persistChanged |= perm.revokeModes(
6779                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6780                    if (perm.modeFlags == 0) {
6781                        it.remove();
6782                    }
6783                }
6784            }
6785
6786            if (perms.isEmpty()) {
6787                mGrantedUriPermissions.remove(targetUid);
6788                N--;
6789                i--;
6790            }
6791        }
6792
6793        if (persistChanged) {
6794            schedulePersistUriGrants();
6795        }
6796    }
6797
6798    @Override
6799    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6800            int userId) {
6801        enforceNotIsolatedCaller("revokeUriPermission");
6802        synchronized(this) {
6803            final ProcessRecord r = getRecordForAppLocked(caller);
6804            if (r == null) {
6805                throw new SecurityException("Unable to find app for caller "
6806                        + caller
6807                        + " when revoking permission to uri " + uri);
6808            }
6809            if (uri == null) {
6810                Slog.w(TAG, "revokeUriPermission: null uri");
6811                return;
6812            }
6813
6814            if (!Intent.isAccessUriMode(modeFlags)) {
6815                return;
6816            }
6817
6818            final IPackageManager pm = AppGlobals.getPackageManager();
6819            final String authority = uri.getAuthority();
6820            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6821            if (pi == null) {
6822                Slog.w(TAG, "No content provider found for permission revoke: "
6823                        + uri.toSafeString());
6824                return;
6825            }
6826
6827            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6828        }
6829    }
6830
6831    /**
6832     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6833     * given package.
6834     *
6835     * @param packageName Package name to match, or {@code null} to apply to all
6836     *            packages.
6837     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6838     *            to all users.
6839     * @param persistable If persistable grants should be removed.
6840     */
6841    private void removeUriPermissionsForPackageLocked(
6842            String packageName, int userHandle, boolean persistable) {
6843        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6844            throw new IllegalArgumentException("Must narrow by either package or user");
6845        }
6846
6847        boolean persistChanged = false;
6848
6849        int N = mGrantedUriPermissions.size();
6850        for (int i = 0; i < N; i++) {
6851            final int targetUid = mGrantedUriPermissions.keyAt(i);
6852            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6853
6854            // Only inspect grants matching user
6855            if (userHandle == UserHandle.USER_ALL
6856                    || userHandle == UserHandle.getUserId(targetUid)) {
6857                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6858                    final UriPermission perm = it.next();
6859
6860                    // Only inspect grants matching package
6861                    if (packageName == null || perm.sourcePkg.equals(packageName)
6862                            || perm.targetPkg.equals(packageName)) {
6863                        persistChanged |= perm.revokeModes(
6864                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6865
6866                        // Only remove when no modes remain; any persisted grants
6867                        // will keep this alive.
6868                        if (perm.modeFlags == 0) {
6869                            it.remove();
6870                        }
6871                    }
6872                }
6873
6874                if (perms.isEmpty()) {
6875                    mGrantedUriPermissions.remove(targetUid);
6876                    N--;
6877                    i--;
6878                }
6879            }
6880        }
6881
6882        if (persistChanged) {
6883            schedulePersistUriGrants();
6884        }
6885    }
6886
6887    @Override
6888    public IBinder newUriPermissionOwner(String name) {
6889        enforceNotIsolatedCaller("newUriPermissionOwner");
6890        synchronized(this) {
6891            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6892            return owner.getExternalTokenLocked();
6893        }
6894    }
6895
6896    @Override
6897    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6898            final int modeFlags, int userId) {
6899        synchronized(this) {
6900            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6901            if (owner == null) {
6902                throw new IllegalArgumentException("Unknown owner: " + token);
6903            }
6904            if (fromUid != Binder.getCallingUid()) {
6905                if (Binder.getCallingUid() != Process.myUid()) {
6906                    // Only system code can grant URI permissions on behalf
6907                    // of other users.
6908                    throw new SecurityException("nice try");
6909                }
6910            }
6911            if (targetPkg == null) {
6912                throw new IllegalArgumentException("null target");
6913            }
6914            if (uri == null) {
6915                throw new IllegalArgumentException("null uri");
6916            }
6917
6918            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false),
6919                    modeFlags, owner);
6920        }
6921    }
6922
6923    @Override
6924    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6925        synchronized(this) {
6926            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6927            if (owner == null) {
6928                throw new IllegalArgumentException("Unknown owner: " + token);
6929            }
6930
6931            if (uri == null) {
6932                owner.removeUriPermissionsLocked(mode);
6933            } else {
6934                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6935            }
6936        }
6937    }
6938
6939    private void schedulePersistUriGrants() {
6940        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6941            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6942                    10 * DateUtils.SECOND_IN_MILLIS);
6943        }
6944    }
6945
6946    private void writeGrantedUriPermissions() {
6947        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6948
6949        // Snapshot permissions so we can persist without lock
6950        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6951        synchronized (this) {
6952            final int size = mGrantedUriPermissions.size();
6953            for (int i = 0; i < size; i++) {
6954                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6955                for (UriPermission perm : perms.values()) {
6956                    if (perm.persistedModeFlags != 0) {
6957                        persist.add(perm.snapshot());
6958                    }
6959                }
6960            }
6961        }
6962
6963        FileOutputStream fos = null;
6964        try {
6965            fos = mGrantFile.startWrite();
6966
6967            XmlSerializer out = new FastXmlSerializer();
6968            out.setOutput(fos, "utf-8");
6969            out.startDocument(null, true);
6970            out.startTag(null, TAG_URI_GRANTS);
6971            for (UriPermission.Snapshot perm : persist) {
6972                out.startTag(null, TAG_URI_GRANT);
6973                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6974                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6975                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6976                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6977                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6978                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6979                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6980                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6981                out.endTag(null, TAG_URI_GRANT);
6982            }
6983            out.endTag(null, TAG_URI_GRANTS);
6984            out.endDocument();
6985
6986            mGrantFile.finishWrite(fos);
6987        } catch (IOException e) {
6988            if (fos != null) {
6989                mGrantFile.failWrite(fos);
6990            }
6991        }
6992    }
6993
6994    private void readGrantedUriPermissionsLocked() {
6995        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6996
6997        final long now = System.currentTimeMillis();
6998
6999        FileInputStream fis = null;
7000        try {
7001            fis = mGrantFile.openRead();
7002            final XmlPullParser in = Xml.newPullParser();
7003            in.setInput(fis, null);
7004
7005            int type;
7006            while ((type = in.next()) != END_DOCUMENT) {
7007                final String tag = in.getName();
7008                if (type == START_TAG) {
7009                    if (TAG_URI_GRANT.equals(tag)) {
7010                        final int sourceUserId;
7011                        final int targetUserId;
7012                        final int userHandle = readIntAttribute(in,
7013                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7014                        if (userHandle != UserHandle.USER_NULL) {
7015                            // For backwards compatibility.
7016                            sourceUserId = userHandle;
7017                            targetUserId = userHandle;
7018                        } else {
7019                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7020                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7021                        }
7022                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7023                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7024                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7025                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7026                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7027                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7028
7029                        // Sanity check that provider still belongs to source package
7030                        final ProviderInfo pi = getProviderInfoLocked(
7031                                uri.getAuthority(), sourceUserId);
7032                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7033                            int targetUid = -1;
7034                            try {
7035                                targetUid = AppGlobals.getPackageManager()
7036                                        .getPackageUid(targetPkg, targetUserId);
7037                            } catch (RemoteException e) {
7038                            }
7039                            if (targetUid != -1) {
7040                                final UriPermission perm = findOrCreateUriPermissionLocked(
7041                                        sourcePkg, targetPkg, targetUid,
7042                                        new GrantUri(sourceUserId, uri, prefix));
7043                                perm.initPersistedModes(modeFlags, createdTime);
7044                            }
7045                        } else {
7046                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7047                                    + " but instead found " + pi);
7048                        }
7049                    }
7050                }
7051            }
7052        } catch (FileNotFoundException e) {
7053            // Missing grants is okay
7054        } catch (IOException e) {
7055            Log.wtf(TAG, "Failed reading Uri grants", e);
7056        } catch (XmlPullParserException e) {
7057            Log.wtf(TAG, "Failed reading Uri grants", e);
7058        } finally {
7059            IoUtils.closeQuietly(fis);
7060        }
7061    }
7062
7063    @Override
7064    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7065        enforceNotIsolatedCaller("takePersistableUriPermission");
7066
7067        Preconditions.checkFlagsArgument(modeFlags,
7068                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7069
7070        synchronized (this) {
7071            final int callingUid = Binder.getCallingUid();
7072            boolean persistChanged = false;
7073            GrantUri grantUri = new GrantUri(userId, uri, false);
7074
7075            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7076                    new GrantUri(userId, uri, false));
7077            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7078                    new GrantUri(userId, uri, true));
7079
7080            final boolean exactValid = (exactPerm != null)
7081                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7082            final boolean prefixValid = (prefixPerm != null)
7083                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7084
7085            if (!(exactValid || prefixValid)) {
7086                throw new SecurityException("No persistable permission grants found for UID "
7087                        + callingUid + " and Uri " + grantUri.toSafeString());
7088            }
7089
7090            if (exactValid) {
7091                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7092            }
7093            if (prefixValid) {
7094                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7095            }
7096
7097            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7098
7099            if (persistChanged) {
7100                schedulePersistUriGrants();
7101            }
7102        }
7103    }
7104
7105    @Override
7106    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7107        enforceNotIsolatedCaller("releasePersistableUriPermission");
7108
7109        Preconditions.checkFlagsArgument(modeFlags,
7110                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7111
7112        synchronized (this) {
7113            final int callingUid = Binder.getCallingUid();
7114            boolean persistChanged = false;
7115
7116            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7117                    new GrantUri(userId, uri, false));
7118            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7119                    new GrantUri(userId, uri, true));
7120            if (exactPerm == null && prefixPerm == null) {
7121                throw new SecurityException("No permission grants found for UID " + callingUid
7122                        + " and Uri " + uri.toSafeString());
7123            }
7124
7125            if (exactPerm != null) {
7126                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7127                removeUriPermissionIfNeededLocked(exactPerm);
7128            }
7129            if (prefixPerm != null) {
7130                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7131                removeUriPermissionIfNeededLocked(prefixPerm);
7132            }
7133
7134            if (persistChanged) {
7135                schedulePersistUriGrants();
7136            }
7137        }
7138    }
7139
7140    /**
7141     * Prune any older {@link UriPermission} for the given UID until outstanding
7142     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7143     *
7144     * @return if any mutations occured that require persisting.
7145     */
7146    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7147        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7148        if (perms == null) return false;
7149        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7150
7151        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7152        for (UriPermission perm : perms.values()) {
7153            if (perm.persistedModeFlags != 0) {
7154                persisted.add(perm);
7155            }
7156        }
7157
7158        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7159        if (trimCount <= 0) return false;
7160
7161        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7162        for (int i = 0; i < trimCount; i++) {
7163            final UriPermission perm = persisted.get(i);
7164
7165            if (DEBUG_URI_PERMISSION) {
7166                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7167            }
7168
7169            perm.releasePersistableModes(~0);
7170            removeUriPermissionIfNeededLocked(perm);
7171        }
7172
7173        return true;
7174    }
7175
7176    @Override
7177    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7178            String packageName, boolean incoming) {
7179        enforceNotIsolatedCaller("getPersistedUriPermissions");
7180        Preconditions.checkNotNull(packageName, "packageName");
7181
7182        final int callingUid = Binder.getCallingUid();
7183        final IPackageManager pm = AppGlobals.getPackageManager();
7184        try {
7185            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7186            if (packageUid != callingUid) {
7187                throw new SecurityException(
7188                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7189            }
7190        } catch (RemoteException e) {
7191            throw new SecurityException("Failed to verify package name ownership");
7192        }
7193
7194        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7195        synchronized (this) {
7196            if (incoming) {
7197                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7198                        callingUid);
7199                if (perms == null) {
7200                    Slog.w(TAG, "No permission grants found for " + packageName);
7201                } else {
7202                    for (UriPermission perm : perms.values()) {
7203                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7204                            result.add(perm.buildPersistedPublicApiObject());
7205                        }
7206                    }
7207                }
7208            } else {
7209                final int size = mGrantedUriPermissions.size();
7210                for (int i = 0; i < size; i++) {
7211                    final ArrayMap<GrantUri, UriPermission> perms =
7212                            mGrantedUriPermissions.valueAt(i);
7213                    for (UriPermission perm : perms.values()) {
7214                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7215                            result.add(perm.buildPersistedPublicApiObject());
7216                        }
7217                    }
7218                }
7219            }
7220        }
7221        return new ParceledListSlice<android.content.UriPermission>(result);
7222    }
7223
7224    @Override
7225    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7226        synchronized (this) {
7227            ProcessRecord app =
7228                who != null ? getRecordForAppLocked(who) : null;
7229            if (app == null) return;
7230
7231            Message msg = Message.obtain();
7232            msg.what = WAIT_FOR_DEBUGGER_MSG;
7233            msg.obj = app;
7234            msg.arg1 = waiting ? 1 : 0;
7235            mHandler.sendMessage(msg);
7236        }
7237    }
7238
7239    @Override
7240    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7241        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7242        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7243        outInfo.availMem = Process.getFreeMemory();
7244        outInfo.totalMem = Process.getTotalMemory();
7245        outInfo.threshold = homeAppMem;
7246        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7247        outInfo.hiddenAppThreshold = cachedAppMem;
7248        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7249                ProcessList.SERVICE_ADJ);
7250        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7251                ProcessList.VISIBLE_APP_ADJ);
7252        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7253                ProcessList.FOREGROUND_APP_ADJ);
7254    }
7255
7256    // =========================================================
7257    // TASK MANAGEMENT
7258    // =========================================================
7259
7260    @Override
7261    public List<IAppTask> getAppTasks() {
7262        final PackageManager pm = mContext.getPackageManager();
7263        int callingUid = Binder.getCallingUid();
7264        long ident = Binder.clearCallingIdentity();
7265
7266        // Compose the list of packages for this id to test against
7267        HashSet<String> packages = new HashSet<String>();
7268        String[] uidPackages = pm.getPackagesForUid(callingUid);
7269        for (int i = 0; i < uidPackages.length; i++) {
7270            packages.add(uidPackages[i]);
7271        }
7272
7273        synchronized(this) {
7274            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7275            try {
7276                if (localLOGV) Slog.v(TAG, "getAppTasks");
7277
7278                final int N = mRecentTasks.size();
7279                for (int i = 0; i < N; i++) {
7280                    TaskRecord tr = mRecentTasks.get(i);
7281                    // Skip tasks that are not created by the caller
7282                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
7283                        ActivityManager.RecentTaskInfo taskInfo =
7284                                createRecentTaskInfoFromTaskRecord(tr);
7285                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7286                        list.add(taskImpl);
7287                    }
7288                }
7289            } finally {
7290                Binder.restoreCallingIdentity(ident);
7291            }
7292            return list;
7293        }
7294    }
7295
7296    @Override
7297    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7298        final int callingUid = Binder.getCallingUid();
7299        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7300
7301        synchronized(this) {
7302            if (localLOGV) Slog.v(
7303                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7304
7305            final boolean allowed = checkCallingPermission(
7306                    android.Manifest.permission.GET_TASKS)
7307                    == PackageManager.PERMISSION_GRANTED;
7308            if (!allowed) {
7309                Slog.w(TAG, "getTasks: caller " + callingUid
7310                        + " does not hold GET_TASKS; limiting output");
7311            }
7312
7313            // TODO: Improve with MRU list from all ActivityStacks.
7314            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7315        }
7316
7317        return list;
7318    }
7319
7320    TaskRecord getMostRecentTask() {
7321        return mRecentTasks.get(0);
7322    }
7323
7324    /**
7325     * Creates a new RecentTaskInfo from a TaskRecord.
7326     */
7327    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7328        // Update the task description to reflect any changes in the task stack
7329        tr.updateTaskDescription();
7330
7331        // Compose the recent task info
7332        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7333        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7334        rti.persistentId = tr.taskId;
7335        rti.baseIntent = new Intent(tr.getBaseIntent());
7336        rti.origActivity = tr.origActivity;
7337        rti.description = tr.lastDescription;
7338        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7339        rti.userId = tr.userId;
7340        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7341        rti.firstActiveTime = tr.firstActiveTime;
7342        rti.lastActiveTime = tr.lastActiveTime;
7343        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7344        return rti;
7345    }
7346
7347    @Override
7348    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7349        final int callingUid = Binder.getCallingUid();
7350        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7351                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7352
7353        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7354        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7355        synchronized (this) {
7356            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
7357                    == PackageManager.PERMISSION_GRANTED;
7358            if (!allowed) {
7359                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7360                        + " does not hold GET_TASKS; limiting output");
7361            }
7362            final boolean detailed = checkCallingPermission(
7363                    android.Manifest.permission.GET_DETAILED_TASKS)
7364                    == PackageManager.PERMISSION_GRANTED;
7365
7366            IPackageManager pm = AppGlobals.getPackageManager();
7367
7368            final int N = mRecentTasks.size();
7369            ArrayList<ActivityManager.RecentTaskInfo> res
7370                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7371                            maxNum < N ? maxNum : N);
7372
7373            final Set<Integer> includedUsers;
7374            if (includeProfiles) {
7375                includedUsers = getProfileIdsLocked(userId);
7376            } else {
7377                includedUsers = new HashSet<Integer>();
7378            }
7379            includedUsers.add(Integer.valueOf(userId));
7380
7381            // Regroup affiliated tasks together.
7382            for (int i = 0; i < N; ) {
7383                TaskRecord task = mRecentTasks.remove(i);
7384                if (mTmpRecents.contains(task)) {
7385                    continue;
7386                }
7387                int affiliatedTaskId = task.mAffiliatedTaskId;
7388                while (true) {
7389                    TaskRecord next = task.mNextAffiliate;
7390                    if (next == null) {
7391                        break;
7392                    }
7393                    if (next.mAffiliatedTaskId != affiliatedTaskId) {
7394                        Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
7395                                next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
7396                        task.setNextAffiliate(null);
7397                        if (next.mPrevAffiliate == task) {
7398                            next.setPrevAffiliate(null);
7399                        }
7400                        break;
7401                    }
7402                    if (next.mPrevAffiliate != task) {
7403                        Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
7404                                next.mPrevAffiliate + " task=" + task);
7405                        next.setPrevAffiliate(null);
7406                        break;
7407                    }
7408                    if (!mRecentTasks.contains(next)) {
7409                        Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
7410                        task.setNextAffiliate(null);
7411                        if (next.mPrevAffiliate == task) {
7412                            next.setPrevAffiliate(null);
7413                        }
7414                        break;
7415                    }
7416                    task = next;
7417                }
7418                // task is now the end of the list
7419                do {
7420                    mRecentTasks.remove(task);
7421                    mRecentTasks.add(i++, task);
7422                    mTmpRecents.add(task);
7423                } while ((task = task.mPrevAffiliate) != null);
7424            }
7425            mTmpRecents.clear();
7426            // mRecentTasks is now in sorted, affiliated order.
7427
7428            for (int i=0; i<N && maxNum > 0; i++) {
7429                TaskRecord tr = mRecentTasks.get(i);
7430                // Only add calling user or related users recent tasks
7431                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7432
7433                // Return the entry if desired by the caller.  We always return
7434                // the first entry, because callers always expect this to be the
7435                // foreground app.  We may filter others if the caller has
7436                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7437                // we should exclude the entry.
7438
7439                if (i == 0
7440                        || withExcluded
7441                        || (tr.intent == null)
7442                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7443                                == 0)) {
7444                    if (!allowed) {
7445                        // If the caller doesn't have the GET_TASKS permission, then only
7446                        // allow them to see a small subset of tasks -- their own and home.
7447                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7448                            continue;
7449                        }
7450                    }
7451                    if (tr.intent != null &&
7452                            (tr.intent.getFlags() & Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS)
7453                            != 0 && tr.getTopActivity() == null) {
7454                        // Don't include auto remove tasks that are finished or finishing.
7455                        continue;
7456                    }
7457
7458                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7459                    if (!detailed) {
7460                        rti.baseIntent.replaceExtras((Bundle)null);
7461                    }
7462
7463                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7464                        // Check whether this activity is currently available.
7465                        try {
7466                            if (rti.origActivity != null) {
7467                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7468                                        == null) {
7469                                    continue;
7470                                }
7471                            } else if (rti.baseIntent != null) {
7472                                if (pm.queryIntentActivities(rti.baseIntent,
7473                                        null, 0, userId) == null) {
7474                                    continue;
7475                                }
7476                            }
7477                        } catch (RemoteException e) {
7478                            // Will never happen.
7479                        }
7480                    }
7481
7482                    res.add(rti);
7483                    maxNum--;
7484                }
7485            }
7486            return res;
7487        }
7488    }
7489
7490    private TaskRecord recentTaskForIdLocked(int id) {
7491        final int N = mRecentTasks.size();
7492            for (int i=0; i<N; i++) {
7493                TaskRecord tr = mRecentTasks.get(i);
7494                if (tr.taskId == id) {
7495                    return tr;
7496                }
7497            }
7498            return null;
7499    }
7500
7501    @Override
7502    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7503        synchronized (this) {
7504            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7505                    "getTaskThumbnail()");
7506            TaskRecord tr = recentTaskForIdLocked(id);
7507            if (tr != null) {
7508                return tr.getTaskThumbnailLocked();
7509            }
7510        }
7511        return null;
7512    }
7513
7514    @Override
7515    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7516        synchronized (this) {
7517            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7518            if (r != null) {
7519                r.taskDescription = td;
7520                r.task.updateTaskDescription();
7521            }
7522        }
7523    }
7524
7525    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7526        if (!pr.killedByAm) {
7527            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7528            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7529                    pr.processName, pr.setAdj, reason);
7530            pr.killedByAm = true;
7531            Process.killProcessQuiet(pr.pid);
7532            Process.killProcessGroup(pr.info.uid, pr.pid);
7533        }
7534    }
7535
7536    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7537        tr.disposeThumbnail();
7538        mRecentTasks.remove(tr);
7539        tr.closeRecentsChain();
7540        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7541        Intent baseIntent = new Intent(
7542                tr.intent != null ? tr.intent : tr.affinityIntent);
7543        ComponentName component = baseIntent.getComponent();
7544        if (component == null) {
7545            Slog.w(TAG, "Now component for base intent of task: " + tr);
7546            return;
7547        }
7548
7549        // Find any running services associated with this app.
7550        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7551
7552        if (killProcesses) {
7553            // Find any running processes associated with this app.
7554            final String pkg = component.getPackageName();
7555            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7556            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7557            for (int i=0; i<pmap.size(); i++) {
7558                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7559                for (int j=0; j<uids.size(); j++) {
7560                    ProcessRecord proc = uids.valueAt(j);
7561                    if (proc.userId != tr.userId) {
7562                        continue;
7563                    }
7564                    if (!proc.pkgList.containsKey(pkg)) {
7565                        continue;
7566                    }
7567                    procs.add(proc);
7568                }
7569            }
7570
7571            // Kill the running processes.
7572            for (int i=0; i<procs.size(); i++) {
7573                ProcessRecord pr = procs.get(i);
7574                if (pr == mHomeProcess) {
7575                    // Don't kill the home process along with tasks from the same package.
7576                    continue;
7577                }
7578                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7579                    killUnneededProcessLocked(pr, "remove task");
7580                } else {
7581                    pr.waitingToKill = "remove task";
7582                }
7583            }
7584        }
7585    }
7586
7587    /**
7588     * Removes the task with the specified task id.
7589     *
7590     * @param taskId Identifier of the task to be removed.
7591     * @param flags Additional operational flags.  May be 0 or
7592     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7593     * @return Returns true if the given task was found and removed.
7594     */
7595    private boolean removeTaskByIdLocked(int taskId, int flags) {
7596        TaskRecord tr = recentTaskForIdLocked(taskId);
7597        if (tr != null) {
7598            tr.removeTaskActivitiesLocked();
7599            cleanUpRemovedTaskLocked(tr, flags);
7600            if (tr.isPersistable) {
7601                notifyTaskPersisterLocked(tr, true);
7602            }
7603            return true;
7604        }
7605        return false;
7606    }
7607
7608    @Override
7609    public boolean removeTask(int taskId, int flags) {
7610        synchronized (this) {
7611            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7612                    "removeTask()");
7613            long ident = Binder.clearCallingIdentity();
7614            try {
7615                return removeTaskByIdLocked(taskId, flags);
7616            } finally {
7617                Binder.restoreCallingIdentity(ident);
7618            }
7619        }
7620    }
7621
7622    /**
7623     * TODO: Add mController hook
7624     */
7625    @Override
7626    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7627        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7628                "moveTaskToFront()");
7629
7630        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7631        synchronized(this) {
7632            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7633                    Binder.getCallingUid(), "Task to front")) {
7634                ActivityOptions.abort(options);
7635                return;
7636            }
7637            final long origId = Binder.clearCallingIdentity();
7638            try {
7639                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7640                if (task == null) {
7641                    return;
7642                }
7643                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7644                    mStackSupervisor.showLockTaskToast();
7645                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7646                    return;
7647                }
7648                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7649                if (prev != null && prev.isRecentsActivity()) {
7650                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7651                }
7652                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7653            } finally {
7654                Binder.restoreCallingIdentity(origId);
7655            }
7656            ActivityOptions.abort(options);
7657        }
7658    }
7659
7660    @Override
7661    public void moveTaskToBack(int taskId) {
7662        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7663                "moveTaskToBack()");
7664
7665        synchronized(this) {
7666            TaskRecord tr = recentTaskForIdLocked(taskId);
7667            if (tr != null) {
7668                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7669                ActivityStack stack = tr.stack;
7670                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7671                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7672                            Binder.getCallingUid(), "Task to back")) {
7673                        return;
7674                    }
7675                }
7676                final long origId = Binder.clearCallingIdentity();
7677                try {
7678                    stack.moveTaskToBackLocked(taskId, null);
7679                } finally {
7680                    Binder.restoreCallingIdentity(origId);
7681                }
7682            }
7683        }
7684    }
7685
7686    /**
7687     * Moves an activity, and all of the other activities within the same task, to the bottom
7688     * of the history stack.  The activity's order within the task is unchanged.
7689     *
7690     * @param token A reference to the activity we wish to move
7691     * @param nonRoot If false then this only works if the activity is the root
7692     *                of a task; if true it will work for any activity in a task.
7693     * @return Returns true if the move completed, false if not.
7694     */
7695    @Override
7696    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7697        enforceNotIsolatedCaller("moveActivityTaskToBack");
7698        synchronized(this) {
7699            final long origId = Binder.clearCallingIdentity();
7700            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7701            if (taskId >= 0) {
7702                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7703            }
7704            Binder.restoreCallingIdentity(origId);
7705        }
7706        return false;
7707    }
7708
7709    @Override
7710    public void moveTaskBackwards(int task) {
7711        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7712                "moveTaskBackwards()");
7713
7714        synchronized(this) {
7715            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7716                    Binder.getCallingUid(), "Task backwards")) {
7717                return;
7718            }
7719            final long origId = Binder.clearCallingIdentity();
7720            moveTaskBackwardsLocked(task);
7721            Binder.restoreCallingIdentity(origId);
7722        }
7723    }
7724
7725    private final void moveTaskBackwardsLocked(int task) {
7726        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7727    }
7728
7729    @Override
7730    public IBinder getHomeActivityToken() throws RemoteException {
7731        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7732                "getHomeActivityToken()");
7733        synchronized (this) {
7734            return mStackSupervisor.getHomeActivityToken();
7735        }
7736    }
7737
7738    @Override
7739    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7740            IActivityContainerCallback callback) throws RemoteException {
7741        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7742                "createActivityContainer()");
7743        synchronized (this) {
7744            if (parentActivityToken == null) {
7745                throw new IllegalArgumentException("parent token must not be null");
7746            }
7747            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7748            if (r == null) {
7749                return null;
7750            }
7751            if (callback == null) {
7752                throw new IllegalArgumentException("callback must not be null");
7753            }
7754            return mStackSupervisor.createActivityContainer(r, callback);
7755        }
7756    }
7757
7758    @Override
7759    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7760        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7761                "deleteActivityContainer()");
7762        synchronized (this) {
7763            mStackSupervisor.deleteActivityContainer(container);
7764        }
7765    }
7766
7767    @Override
7768    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7769            throws RemoteException {
7770        synchronized (this) {
7771            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7772            if (stack != null) {
7773                return stack.mActivityContainer;
7774            }
7775            return null;
7776        }
7777    }
7778
7779    @Override
7780    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7781        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7782                "moveTaskToStack()");
7783        if (stackId == HOME_STACK_ID) {
7784            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7785                    new RuntimeException("here").fillInStackTrace());
7786        }
7787        synchronized (this) {
7788            long ident = Binder.clearCallingIdentity();
7789            try {
7790                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7791                        + stackId + " toTop=" + toTop);
7792                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7793            } finally {
7794                Binder.restoreCallingIdentity(ident);
7795            }
7796        }
7797    }
7798
7799    @Override
7800    public void resizeStack(int stackBoxId, Rect bounds) {
7801        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7802                "resizeStackBox()");
7803        long ident = Binder.clearCallingIdentity();
7804        try {
7805            mWindowManager.resizeStack(stackBoxId, bounds);
7806        } finally {
7807            Binder.restoreCallingIdentity(ident);
7808        }
7809    }
7810
7811    @Override
7812    public List<StackInfo> getAllStackInfos() {
7813        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7814                "getAllStackInfos()");
7815        long ident = Binder.clearCallingIdentity();
7816        try {
7817            synchronized (this) {
7818                return mStackSupervisor.getAllStackInfosLocked();
7819            }
7820        } finally {
7821            Binder.restoreCallingIdentity(ident);
7822        }
7823    }
7824
7825    @Override
7826    public StackInfo getStackInfo(int stackId) {
7827        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7828                "getStackInfo()");
7829        long ident = Binder.clearCallingIdentity();
7830        try {
7831            synchronized (this) {
7832                return mStackSupervisor.getStackInfoLocked(stackId);
7833            }
7834        } finally {
7835            Binder.restoreCallingIdentity(ident);
7836        }
7837    }
7838
7839    @Override
7840    public boolean isInHomeStack(int taskId) {
7841        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7842                "getStackInfo()");
7843        long ident = Binder.clearCallingIdentity();
7844        try {
7845            synchronized (this) {
7846                TaskRecord tr = recentTaskForIdLocked(taskId);
7847                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7848            }
7849        } finally {
7850            Binder.restoreCallingIdentity(ident);
7851        }
7852    }
7853
7854    @Override
7855    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7856        synchronized(this) {
7857            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7858        }
7859    }
7860
7861    private boolean isLockTaskAuthorized(String pkg) {
7862        final DevicePolicyManager dpm = (DevicePolicyManager)
7863                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7864        try {
7865            int uid = mContext.getPackageManager().getPackageUid(pkg,
7866                    Binder.getCallingUserHandle().getIdentifier());
7867            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7868        } catch (NameNotFoundException e) {
7869            return false;
7870        }
7871    }
7872
7873    void startLockTaskMode(TaskRecord task) {
7874        final String pkg;
7875        synchronized (this) {
7876            pkg = task.intent.getComponent().getPackageName();
7877        }
7878        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
7879        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
7880            final TaskRecord taskRecord = task;
7881            mHandler.post(new Runnable() {
7882                @Override
7883                public void run() {
7884                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
7885                }
7886            });
7887            return;
7888        }
7889        long ident = Binder.clearCallingIdentity();
7890        try {
7891            synchronized (this) {
7892                // Since we lost lock on task, make sure it is still there.
7893                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7894                if (task != null) {
7895                    if (!isSystemInitiated
7896                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
7897                        throw new IllegalArgumentException("Invalid task, not in foreground");
7898                    }
7899                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
7900                }
7901            }
7902        } finally {
7903            Binder.restoreCallingIdentity(ident);
7904        }
7905    }
7906
7907    @Override
7908    public void startLockTaskMode(int taskId) {
7909        final TaskRecord task;
7910        long ident = Binder.clearCallingIdentity();
7911        try {
7912            synchronized (this) {
7913                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7914            }
7915        } finally {
7916            Binder.restoreCallingIdentity(ident);
7917        }
7918        if (task != null) {
7919            startLockTaskMode(task);
7920        }
7921    }
7922
7923    @Override
7924    public void startLockTaskMode(IBinder token) {
7925        final TaskRecord task;
7926        long ident = Binder.clearCallingIdentity();
7927        try {
7928            synchronized (this) {
7929                final ActivityRecord r = ActivityRecord.forToken(token);
7930                if (r == null) {
7931                    return;
7932                }
7933                task = r.task;
7934            }
7935        } finally {
7936            Binder.restoreCallingIdentity(ident);
7937        }
7938        if (task != null) {
7939            startLockTaskMode(task);
7940        }
7941    }
7942
7943    @Override
7944    public void startLockTaskModeOnCurrent() throws RemoteException {
7945        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7946        ActivityRecord r = null;
7947        synchronized (this) {
7948            r = mStackSupervisor.topRunningActivityLocked();
7949        }
7950        startLockTaskMode(r.task);
7951    }
7952
7953    @Override
7954    public void stopLockTaskMode() {
7955        // Verify that the user matches the package of the intent for the TaskRecord
7956        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
7957        // and stopLockTaskMode.
7958        final int callingUid = Binder.getCallingUid();
7959        if (callingUid != Process.SYSTEM_UID) {
7960            try {
7961                String pkg =
7962                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
7963                int uid = mContext.getPackageManager().getPackageUid(pkg,
7964                        Binder.getCallingUserHandle().getIdentifier());
7965                if (uid != callingUid) {
7966                    throw new SecurityException("Invalid uid, expected " + uid);
7967                }
7968            } catch (NameNotFoundException e) {
7969                Log.d(TAG, "stopLockTaskMode " + e);
7970                return;
7971            }
7972        }
7973        long ident = Binder.clearCallingIdentity();
7974        try {
7975            Log.d(TAG, "stopLockTaskMode");
7976            // Stop lock task
7977            synchronized (this) {
7978                mStackSupervisor.setLockTaskModeLocked(null, false);
7979            }
7980        } finally {
7981            Binder.restoreCallingIdentity(ident);
7982        }
7983    }
7984
7985    @Override
7986    public void stopLockTaskModeOnCurrent() throws RemoteException {
7987        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7988        long ident = Binder.clearCallingIdentity();
7989        try {
7990            stopLockTaskMode();
7991        } finally {
7992            Binder.restoreCallingIdentity(ident);
7993        }
7994    }
7995
7996    @Override
7997    public boolean isInLockTaskMode() {
7998        synchronized (this) {
7999            return mStackSupervisor.isInLockTaskMode();
8000        }
8001    }
8002
8003    // =========================================================
8004    // CONTENT PROVIDERS
8005    // =========================================================
8006
8007    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8008        List<ProviderInfo> providers = null;
8009        try {
8010            providers = AppGlobals.getPackageManager().
8011                queryContentProviders(app.processName, app.uid,
8012                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8013        } catch (RemoteException ex) {
8014        }
8015        if (DEBUG_MU)
8016            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8017        int userId = app.userId;
8018        if (providers != null) {
8019            int N = providers.size();
8020            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8021            for (int i=0; i<N; i++) {
8022                ProviderInfo cpi =
8023                    (ProviderInfo)providers.get(i);
8024                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8025                        cpi.name, cpi.flags);
8026                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8027                    // This is a singleton provider, but a user besides the
8028                    // default user is asking to initialize a process it runs
8029                    // in...  well, no, it doesn't actually run in this process,
8030                    // it runs in the process of the default user.  Get rid of it.
8031                    providers.remove(i);
8032                    N--;
8033                    i--;
8034                    continue;
8035                }
8036
8037                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8038                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8039                if (cpr == null) {
8040                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8041                    mProviderMap.putProviderByClass(comp, cpr);
8042                }
8043                if (DEBUG_MU)
8044                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8045                app.pubProviders.put(cpi.name, cpr);
8046                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8047                    // Don't add this if it is a platform component that is marked
8048                    // to run in multiple processes, because this is actually
8049                    // part of the framework so doesn't make sense to track as a
8050                    // separate apk in the process.
8051                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8052                            mProcessStats);
8053                }
8054                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8055            }
8056        }
8057        return providers;
8058    }
8059
8060    /**
8061     * Check if {@link ProcessRecord} has a possible chance at accessing the
8062     * given {@link ProviderInfo}. Final permission checking is always done
8063     * in {@link ContentProvider}.
8064     */
8065    private final String checkContentProviderPermissionLocked(
8066            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8067        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8068        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8069        boolean checkedGrants = false;
8070        if (checkUser) {
8071            // Looking for cross-user grants before enforcing the typical cross-users permissions
8072            int tmpTargetUserId = unsafeConvertIncomingUser(UserHandle.getUserId(callingUid));
8073            if (tmpTargetUserId != userId) {
8074                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8075                    return null;
8076                }
8077                checkedGrants = true;
8078            }
8079            userId = handleIncomingUser(callingPid, callingUid, userId,
8080                    false, ALLOW_NON_FULL,
8081                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8082            if (userId != tmpTargetUserId) {
8083                // When we actually went to determine the final targer user ID, this ended
8084                // up different than our initial check for the authority.  This is because
8085                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8086                // SELF.  So we need to re-check the grants again.
8087                checkedGrants = false;
8088            }
8089        }
8090        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8091                cpi.applicationInfo.uid, cpi.exported)
8092                == PackageManager.PERMISSION_GRANTED) {
8093            return null;
8094        }
8095        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8096                cpi.applicationInfo.uid, cpi.exported)
8097                == PackageManager.PERMISSION_GRANTED) {
8098            return null;
8099        }
8100
8101        PathPermission[] pps = cpi.pathPermissions;
8102        if (pps != null) {
8103            int i = pps.length;
8104            while (i > 0) {
8105                i--;
8106                PathPermission pp = pps[i];
8107                String pprperm = pp.getReadPermission();
8108                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8109                        cpi.applicationInfo.uid, cpi.exported)
8110                        == PackageManager.PERMISSION_GRANTED) {
8111                    return null;
8112                }
8113                String ppwperm = pp.getWritePermission();
8114                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8115                        cpi.applicationInfo.uid, cpi.exported)
8116                        == PackageManager.PERMISSION_GRANTED) {
8117                    return null;
8118                }
8119            }
8120        }
8121        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8122            return null;
8123        }
8124
8125        String msg;
8126        if (!cpi.exported) {
8127            msg = "Permission Denial: opening provider " + cpi.name
8128                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8129                    + ", uid=" + callingUid + ") that is not exported from uid "
8130                    + cpi.applicationInfo.uid;
8131        } else {
8132            msg = "Permission Denial: opening provider " + cpi.name
8133                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8134                    + ", uid=" + callingUid + ") requires "
8135                    + cpi.readPermission + " or " + cpi.writePermission;
8136        }
8137        Slog.w(TAG, msg);
8138        return msg;
8139    }
8140
8141    /**
8142     * Returns if the ContentProvider has granted a uri to callingUid
8143     */
8144    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8145        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8146        if (perms != null) {
8147            for (int i=perms.size()-1; i>=0; i--) {
8148                GrantUri grantUri = perms.keyAt(i);
8149                if (grantUri.sourceUserId == userId || !checkUser) {
8150                    if (matchesProvider(grantUri.uri, cpi)) {
8151                        return true;
8152                    }
8153                }
8154            }
8155        }
8156        return false;
8157    }
8158
8159    /**
8160     * Returns true if the uri authority is one of the authorities specified in the provider.
8161     */
8162    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8163        String uriAuth = uri.getAuthority();
8164        String cpiAuth = cpi.authority;
8165        if (cpiAuth.indexOf(';') == -1) {
8166            return cpiAuth.equals(uriAuth);
8167        }
8168        String[] cpiAuths = cpiAuth.split(";");
8169        int length = cpiAuths.length;
8170        for (int i = 0; i < length; i++) {
8171            if (cpiAuths[i].equals(uriAuth)) return true;
8172        }
8173        return false;
8174    }
8175
8176    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8177            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8178        if (r != null) {
8179            for (int i=0; i<r.conProviders.size(); i++) {
8180                ContentProviderConnection conn = r.conProviders.get(i);
8181                if (conn.provider == cpr) {
8182                    if (DEBUG_PROVIDER) Slog.v(TAG,
8183                            "Adding provider requested by "
8184                            + r.processName + " from process "
8185                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8186                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8187                    if (stable) {
8188                        conn.stableCount++;
8189                        conn.numStableIncs++;
8190                    } else {
8191                        conn.unstableCount++;
8192                        conn.numUnstableIncs++;
8193                    }
8194                    return conn;
8195                }
8196            }
8197            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8198            if (stable) {
8199                conn.stableCount = 1;
8200                conn.numStableIncs = 1;
8201            } else {
8202                conn.unstableCount = 1;
8203                conn.numUnstableIncs = 1;
8204            }
8205            cpr.connections.add(conn);
8206            r.conProviders.add(conn);
8207            return conn;
8208        }
8209        cpr.addExternalProcessHandleLocked(externalProcessToken);
8210        return null;
8211    }
8212
8213    boolean decProviderCountLocked(ContentProviderConnection conn,
8214            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8215        if (conn != null) {
8216            cpr = conn.provider;
8217            if (DEBUG_PROVIDER) Slog.v(TAG,
8218                    "Removing provider requested by "
8219                    + conn.client.processName + " from process "
8220                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8221                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8222            if (stable) {
8223                conn.stableCount--;
8224            } else {
8225                conn.unstableCount--;
8226            }
8227            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8228                cpr.connections.remove(conn);
8229                conn.client.conProviders.remove(conn);
8230                return true;
8231            }
8232            return false;
8233        }
8234        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8235        return false;
8236    }
8237
8238    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8239            String name, IBinder token, boolean stable, int userId) {
8240        ContentProviderRecord cpr;
8241        ContentProviderConnection conn = null;
8242        ProviderInfo cpi = null;
8243
8244        synchronized(this) {
8245            ProcessRecord r = null;
8246            if (caller != null) {
8247                r = getRecordForAppLocked(caller);
8248                if (r == null) {
8249                    throw new SecurityException(
8250                            "Unable to find app for caller " + caller
8251                          + " (pid=" + Binder.getCallingPid()
8252                          + ") when getting content provider " + name);
8253                }
8254            }
8255
8256            boolean checkCrossUser = true;
8257
8258            // First check if this content provider has been published...
8259            cpr = mProviderMap.getProviderByName(name, userId);
8260            // If that didn't work, check if it exists for user 0 and then
8261            // verify that it's a singleton provider before using it.
8262            if (cpr == null && userId != UserHandle.USER_OWNER) {
8263                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8264                if (cpr != null) {
8265                    cpi = cpr.info;
8266                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8267                            cpi.name, cpi.flags)
8268                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8269                        userId = UserHandle.USER_OWNER;
8270                        checkCrossUser = false;
8271                    } else {
8272                        cpr = null;
8273                        cpi = null;
8274                    }
8275                }
8276            }
8277
8278            boolean providerRunning = cpr != null;
8279            if (providerRunning) {
8280                cpi = cpr.info;
8281                String msg;
8282                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8283                        != null) {
8284                    throw new SecurityException(msg);
8285                }
8286
8287                if (r != null && cpr.canRunHere(r)) {
8288                    // This provider has been published or is in the process
8289                    // of being published...  but it is also allowed to run
8290                    // in the caller's process, so don't make a connection
8291                    // and just let the caller instantiate its own instance.
8292                    ContentProviderHolder holder = cpr.newHolder(null);
8293                    // don't give caller the provider object, it needs
8294                    // to make its own.
8295                    holder.provider = null;
8296                    return holder;
8297                }
8298
8299                final long origId = Binder.clearCallingIdentity();
8300
8301                // In this case the provider instance already exists, so we can
8302                // return it right away.
8303                conn = incProviderCountLocked(r, cpr, token, stable);
8304                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8305                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8306                        // If this is a perceptible app accessing the provider,
8307                        // make sure to count it as being accessed and thus
8308                        // back up on the LRU list.  This is good because
8309                        // content providers are often expensive to start.
8310                        updateLruProcessLocked(cpr.proc, false, null);
8311                    }
8312                }
8313
8314                if (cpr.proc != null) {
8315                    if (false) {
8316                        if (cpr.name.flattenToShortString().equals(
8317                                "com.android.providers.calendar/.CalendarProvider2")) {
8318                            Slog.v(TAG, "****************** KILLING "
8319                                + cpr.name.flattenToShortString());
8320                            Process.killProcess(cpr.proc.pid);
8321                        }
8322                    }
8323                    boolean success = updateOomAdjLocked(cpr.proc);
8324                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8325                    // NOTE: there is still a race here where a signal could be
8326                    // pending on the process even though we managed to update its
8327                    // adj level.  Not sure what to do about this, but at least
8328                    // the race is now smaller.
8329                    if (!success) {
8330                        // Uh oh...  it looks like the provider's process
8331                        // has been killed on us.  We need to wait for a new
8332                        // process to be started, and make sure its death
8333                        // doesn't kill our process.
8334                        Slog.i(TAG,
8335                                "Existing provider " + cpr.name.flattenToShortString()
8336                                + " is crashing; detaching " + r);
8337                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8338                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8339                        if (!lastRef) {
8340                            // This wasn't the last ref our process had on
8341                            // the provider...  we have now been killed, bail.
8342                            return null;
8343                        }
8344                        providerRunning = false;
8345                        conn = null;
8346                    }
8347                }
8348
8349                Binder.restoreCallingIdentity(origId);
8350            }
8351
8352            boolean singleton;
8353            if (!providerRunning) {
8354                try {
8355                    cpi = AppGlobals.getPackageManager().
8356                        resolveContentProvider(name,
8357                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8358                } catch (RemoteException ex) {
8359                }
8360                if (cpi == null) {
8361                    return null;
8362                }
8363                // If the provider is a singleton AND
8364                // (it's a call within the same user || the provider is a
8365                // privileged app)
8366                // Then allow connecting to the singleton provider
8367                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8368                        cpi.name, cpi.flags)
8369                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8370                if (singleton) {
8371                    userId = UserHandle.USER_OWNER;
8372                }
8373                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8374
8375                String msg;
8376                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8377                        != null) {
8378                    throw new SecurityException(msg);
8379                }
8380
8381                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8382                        && !cpi.processName.equals("system")) {
8383                    // If this content provider does not run in the system
8384                    // process, and the system is not yet ready to run other
8385                    // processes, then fail fast instead of hanging.
8386                    throw new IllegalArgumentException(
8387                            "Attempt to launch content provider before system ready");
8388                }
8389
8390                // Make sure that the user who owns this provider is started.  If not,
8391                // we don't want to allow it to run.
8392                if (mStartedUsers.get(userId) == null) {
8393                    Slog.w(TAG, "Unable to launch app "
8394                            + cpi.applicationInfo.packageName + "/"
8395                            + cpi.applicationInfo.uid + " for provider "
8396                            + name + ": user " + userId + " is stopped");
8397                    return null;
8398                }
8399
8400                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8401                cpr = mProviderMap.getProviderByClass(comp, userId);
8402                final boolean firstClass = cpr == null;
8403                if (firstClass) {
8404                    try {
8405                        ApplicationInfo ai =
8406                            AppGlobals.getPackageManager().
8407                                getApplicationInfo(
8408                                        cpi.applicationInfo.packageName,
8409                                        STOCK_PM_FLAGS, userId);
8410                        if (ai == null) {
8411                            Slog.w(TAG, "No package info for content provider "
8412                                    + cpi.name);
8413                            return null;
8414                        }
8415                        ai = getAppInfoForUser(ai, userId);
8416                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8417                    } catch (RemoteException ex) {
8418                        // pm is in same process, this will never happen.
8419                    }
8420                }
8421
8422                if (r != null && cpr.canRunHere(r)) {
8423                    // If this is a multiprocess provider, then just return its
8424                    // info and allow the caller to instantiate it.  Only do
8425                    // this if the provider is the same user as the caller's
8426                    // process, or can run as root (so can be in any process).
8427                    return cpr.newHolder(null);
8428                }
8429
8430                if (DEBUG_PROVIDER) {
8431                    RuntimeException e = new RuntimeException("here");
8432                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8433                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8434                }
8435
8436                // This is single process, and our app is now connecting to it.
8437                // See if we are already in the process of launching this
8438                // provider.
8439                final int N = mLaunchingProviders.size();
8440                int i;
8441                for (i=0; i<N; i++) {
8442                    if (mLaunchingProviders.get(i) == cpr) {
8443                        break;
8444                    }
8445                }
8446
8447                // If the provider is not already being launched, then get it
8448                // started.
8449                if (i >= N) {
8450                    final long origId = Binder.clearCallingIdentity();
8451
8452                    try {
8453                        // Content provider is now in use, its package can't be stopped.
8454                        try {
8455                            AppGlobals.getPackageManager().setPackageStoppedState(
8456                                    cpr.appInfo.packageName, false, userId);
8457                        } catch (RemoteException e) {
8458                        } catch (IllegalArgumentException e) {
8459                            Slog.w(TAG, "Failed trying to unstop package "
8460                                    + cpr.appInfo.packageName + ": " + e);
8461                        }
8462
8463                        // Use existing process if already started
8464                        ProcessRecord proc = getProcessRecordLocked(
8465                                cpi.processName, cpr.appInfo.uid, false);
8466                        if (proc != null && proc.thread != null) {
8467                            if (DEBUG_PROVIDER) {
8468                                Slog.d(TAG, "Installing in existing process " + proc);
8469                            }
8470                            proc.pubProviders.put(cpi.name, cpr);
8471                            try {
8472                                proc.thread.scheduleInstallProvider(cpi);
8473                            } catch (RemoteException e) {
8474                            }
8475                        } else {
8476                            proc = startProcessLocked(cpi.processName,
8477                                    cpr.appInfo, false, 0, "content provider",
8478                                    new ComponentName(cpi.applicationInfo.packageName,
8479                                            cpi.name), false, false, false);
8480                            if (proc == null) {
8481                                Slog.w(TAG, "Unable to launch app "
8482                                        + cpi.applicationInfo.packageName + "/"
8483                                        + cpi.applicationInfo.uid + " for provider "
8484                                        + name + ": process is bad");
8485                                return null;
8486                            }
8487                        }
8488                        cpr.launchingApp = proc;
8489                        mLaunchingProviders.add(cpr);
8490                    } finally {
8491                        Binder.restoreCallingIdentity(origId);
8492                    }
8493                }
8494
8495                // Make sure the provider is published (the same provider class
8496                // may be published under multiple names).
8497                if (firstClass) {
8498                    mProviderMap.putProviderByClass(comp, cpr);
8499                }
8500
8501                mProviderMap.putProviderByName(name, cpr);
8502                conn = incProviderCountLocked(r, cpr, token, stable);
8503                if (conn != null) {
8504                    conn.waiting = true;
8505                }
8506            }
8507        }
8508
8509        // Wait for the provider to be published...
8510        synchronized (cpr) {
8511            while (cpr.provider == null) {
8512                if (cpr.launchingApp == null) {
8513                    Slog.w(TAG, "Unable to launch app "
8514                            + cpi.applicationInfo.packageName + "/"
8515                            + cpi.applicationInfo.uid + " for provider "
8516                            + name + ": launching app became null");
8517                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8518                            UserHandle.getUserId(cpi.applicationInfo.uid),
8519                            cpi.applicationInfo.packageName,
8520                            cpi.applicationInfo.uid, name);
8521                    return null;
8522                }
8523                try {
8524                    if (DEBUG_MU) {
8525                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8526                                + cpr.launchingApp);
8527                    }
8528                    if (conn != null) {
8529                        conn.waiting = true;
8530                    }
8531                    cpr.wait();
8532                } catch (InterruptedException ex) {
8533                } finally {
8534                    if (conn != null) {
8535                        conn.waiting = false;
8536                    }
8537                }
8538            }
8539        }
8540        return cpr != null ? cpr.newHolder(conn) : null;
8541    }
8542
8543    @Override
8544    public final ContentProviderHolder getContentProvider(
8545            IApplicationThread caller, String name, int userId, boolean stable) {
8546        enforceNotIsolatedCaller("getContentProvider");
8547        if (caller == null) {
8548            String msg = "null IApplicationThread when getting content provider "
8549                    + name;
8550            Slog.w(TAG, msg);
8551            throw new SecurityException(msg);
8552        }
8553        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8554        // with cross-user grant.
8555        return getContentProviderImpl(caller, name, null, stable, userId);
8556    }
8557
8558    public ContentProviderHolder getContentProviderExternal(
8559            String name, int userId, IBinder token) {
8560        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8561            "Do not have permission in call getContentProviderExternal()");
8562        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8563                false, ALLOW_FULL_ONLY, "getContentProvider", null);
8564        return getContentProviderExternalUnchecked(name, token, userId);
8565    }
8566
8567    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8568            IBinder token, int userId) {
8569        return getContentProviderImpl(null, name, token, true, userId);
8570    }
8571
8572    /**
8573     * Drop a content provider from a ProcessRecord's bookkeeping
8574     */
8575    public void removeContentProvider(IBinder connection, boolean stable) {
8576        enforceNotIsolatedCaller("removeContentProvider");
8577        long ident = Binder.clearCallingIdentity();
8578        try {
8579            synchronized (this) {
8580                ContentProviderConnection conn;
8581                try {
8582                    conn = (ContentProviderConnection)connection;
8583                } catch (ClassCastException e) {
8584                    String msg ="removeContentProvider: " + connection
8585                            + " not a ContentProviderConnection";
8586                    Slog.w(TAG, msg);
8587                    throw new IllegalArgumentException(msg);
8588                }
8589                if (conn == null) {
8590                    throw new NullPointerException("connection is null");
8591                }
8592                if (decProviderCountLocked(conn, null, null, stable)) {
8593                    updateOomAdjLocked();
8594                }
8595            }
8596        } finally {
8597            Binder.restoreCallingIdentity(ident);
8598        }
8599    }
8600
8601    public void removeContentProviderExternal(String name, IBinder token) {
8602        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8603            "Do not have permission in call removeContentProviderExternal()");
8604        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8605    }
8606
8607    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8608        synchronized (this) {
8609            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8610            if(cpr == null) {
8611                //remove from mProvidersByClass
8612                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8613                return;
8614            }
8615
8616            //update content provider record entry info
8617            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8618            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8619            if (localCpr.hasExternalProcessHandles()) {
8620                if (localCpr.removeExternalProcessHandleLocked(token)) {
8621                    updateOomAdjLocked();
8622                } else {
8623                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8624                            + " with no external reference for token: "
8625                            + token + ".");
8626                }
8627            } else {
8628                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8629                        + " with no external references.");
8630            }
8631        }
8632    }
8633
8634    public final void publishContentProviders(IApplicationThread caller,
8635            List<ContentProviderHolder> providers) {
8636        if (providers == null) {
8637            return;
8638        }
8639
8640        enforceNotIsolatedCaller("publishContentProviders");
8641        synchronized (this) {
8642            final ProcessRecord r = getRecordForAppLocked(caller);
8643            if (DEBUG_MU)
8644                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8645            if (r == null) {
8646                throw new SecurityException(
8647                        "Unable to find app for caller " + caller
8648                      + " (pid=" + Binder.getCallingPid()
8649                      + ") when publishing content providers");
8650            }
8651
8652            final long origId = Binder.clearCallingIdentity();
8653
8654            final int N = providers.size();
8655            for (int i=0; i<N; i++) {
8656                ContentProviderHolder src = providers.get(i);
8657                if (src == null || src.info == null || src.provider == null) {
8658                    continue;
8659                }
8660                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8661                if (DEBUG_MU)
8662                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8663                if (dst != null) {
8664                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8665                    mProviderMap.putProviderByClass(comp, dst);
8666                    String names[] = dst.info.authority.split(";");
8667                    for (int j = 0; j < names.length; j++) {
8668                        mProviderMap.putProviderByName(names[j], dst);
8669                    }
8670
8671                    int NL = mLaunchingProviders.size();
8672                    int j;
8673                    for (j=0; j<NL; j++) {
8674                        if (mLaunchingProviders.get(j) == dst) {
8675                            mLaunchingProviders.remove(j);
8676                            j--;
8677                            NL--;
8678                        }
8679                    }
8680                    synchronized (dst) {
8681                        dst.provider = src.provider;
8682                        dst.proc = r;
8683                        dst.notifyAll();
8684                    }
8685                    updateOomAdjLocked(r);
8686                }
8687            }
8688
8689            Binder.restoreCallingIdentity(origId);
8690        }
8691    }
8692
8693    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8694        ContentProviderConnection conn;
8695        try {
8696            conn = (ContentProviderConnection)connection;
8697        } catch (ClassCastException e) {
8698            String msg ="refContentProvider: " + connection
8699                    + " not a ContentProviderConnection";
8700            Slog.w(TAG, msg);
8701            throw new IllegalArgumentException(msg);
8702        }
8703        if (conn == null) {
8704            throw new NullPointerException("connection is null");
8705        }
8706
8707        synchronized (this) {
8708            if (stable > 0) {
8709                conn.numStableIncs += stable;
8710            }
8711            stable = conn.stableCount + stable;
8712            if (stable < 0) {
8713                throw new IllegalStateException("stableCount < 0: " + stable);
8714            }
8715
8716            if (unstable > 0) {
8717                conn.numUnstableIncs += unstable;
8718            }
8719            unstable = conn.unstableCount + unstable;
8720            if (unstable < 0) {
8721                throw new IllegalStateException("unstableCount < 0: " + unstable);
8722            }
8723
8724            if ((stable+unstable) <= 0) {
8725                throw new IllegalStateException("ref counts can't go to zero here: stable="
8726                        + stable + " unstable=" + unstable);
8727            }
8728            conn.stableCount = stable;
8729            conn.unstableCount = unstable;
8730            return !conn.dead;
8731        }
8732    }
8733
8734    public void unstableProviderDied(IBinder connection) {
8735        ContentProviderConnection conn;
8736        try {
8737            conn = (ContentProviderConnection)connection;
8738        } catch (ClassCastException e) {
8739            String msg ="refContentProvider: " + connection
8740                    + " not a ContentProviderConnection";
8741            Slog.w(TAG, msg);
8742            throw new IllegalArgumentException(msg);
8743        }
8744        if (conn == null) {
8745            throw new NullPointerException("connection is null");
8746        }
8747
8748        // Safely retrieve the content provider associated with the connection.
8749        IContentProvider provider;
8750        synchronized (this) {
8751            provider = conn.provider.provider;
8752        }
8753
8754        if (provider == null) {
8755            // Um, yeah, we're way ahead of you.
8756            return;
8757        }
8758
8759        // Make sure the caller is being honest with us.
8760        if (provider.asBinder().pingBinder()) {
8761            // Er, no, still looks good to us.
8762            synchronized (this) {
8763                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8764                        + " says " + conn + " died, but we don't agree");
8765                return;
8766            }
8767        }
8768
8769        // Well look at that!  It's dead!
8770        synchronized (this) {
8771            if (conn.provider.provider != provider) {
8772                // But something changed...  good enough.
8773                return;
8774            }
8775
8776            ProcessRecord proc = conn.provider.proc;
8777            if (proc == null || proc.thread == null) {
8778                // Seems like the process is already cleaned up.
8779                return;
8780            }
8781
8782            // As far as we're concerned, this is just like receiving a
8783            // death notification...  just a bit prematurely.
8784            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8785                    + ") early provider death");
8786            final long ident = Binder.clearCallingIdentity();
8787            try {
8788                appDiedLocked(proc, proc.pid, proc.thread);
8789            } finally {
8790                Binder.restoreCallingIdentity(ident);
8791            }
8792        }
8793    }
8794
8795    @Override
8796    public void appNotRespondingViaProvider(IBinder connection) {
8797        enforceCallingPermission(
8798                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8799
8800        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8801        if (conn == null) {
8802            Slog.w(TAG, "ContentProviderConnection is null");
8803            return;
8804        }
8805
8806        final ProcessRecord host = conn.provider.proc;
8807        if (host == null) {
8808            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8809            return;
8810        }
8811
8812        final long token = Binder.clearCallingIdentity();
8813        try {
8814            appNotResponding(host, null, null, false, "ContentProvider not responding");
8815        } finally {
8816            Binder.restoreCallingIdentity(token);
8817        }
8818    }
8819
8820    public final void installSystemProviders() {
8821        List<ProviderInfo> providers;
8822        synchronized (this) {
8823            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8824            providers = generateApplicationProvidersLocked(app);
8825            if (providers != null) {
8826                for (int i=providers.size()-1; i>=0; i--) {
8827                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8828                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8829                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8830                                + ": not system .apk");
8831                        providers.remove(i);
8832                    }
8833                }
8834            }
8835        }
8836        if (providers != null) {
8837            mSystemThread.installSystemProviders(providers);
8838        }
8839
8840        mCoreSettingsObserver = new CoreSettingsObserver(this);
8841
8842        mUsageStatsService.monitorPackages();
8843    }
8844
8845    /**
8846     * Allows app to retrieve the MIME type of a URI without having permission
8847     * to access its content provider.
8848     *
8849     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8850     *
8851     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8852     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8853     */
8854    public String getProviderMimeType(Uri uri, int userId) {
8855        enforceNotIsolatedCaller("getProviderMimeType");
8856        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8857                userId, false, ALLOW_NON_FULL_IN_PROFILE, "getProviderMimeType", null);
8858        final String name = uri.getAuthority();
8859        final long ident = Binder.clearCallingIdentity();
8860        ContentProviderHolder holder = null;
8861
8862        try {
8863            holder = getContentProviderExternalUnchecked(name, null, userId);
8864            if (holder != null) {
8865                return holder.provider.getType(uri);
8866            }
8867        } catch (RemoteException e) {
8868            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8869            return null;
8870        } finally {
8871            if (holder != null) {
8872                removeContentProviderExternalUnchecked(name, null, userId);
8873            }
8874            Binder.restoreCallingIdentity(ident);
8875        }
8876
8877        return null;
8878    }
8879
8880    // =========================================================
8881    // GLOBAL MANAGEMENT
8882    // =========================================================
8883
8884    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8885            boolean isolated) {
8886        String proc = customProcess != null ? customProcess : info.processName;
8887        BatteryStatsImpl.Uid.Proc ps = null;
8888        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8889        int uid = info.uid;
8890        if (isolated) {
8891            int userId = UserHandle.getUserId(uid);
8892            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8893            while (true) {
8894                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8895                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8896                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8897                }
8898                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8899                mNextIsolatedProcessUid++;
8900                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8901                    // No process for this uid, use it.
8902                    break;
8903                }
8904                stepsLeft--;
8905                if (stepsLeft <= 0) {
8906                    return null;
8907                }
8908            }
8909        }
8910        return new ProcessRecord(stats, info, proc, uid);
8911    }
8912
8913    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8914            String abiOverride) {
8915        ProcessRecord app;
8916        if (!isolated) {
8917            app = getProcessRecordLocked(info.processName, info.uid, true);
8918        } else {
8919            app = null;
8920        }
8921
8922        if (app == null) {
8923            app = newProcessRecordLocked(info, null, isolated);
8924            mProcessNames.put(info.processName, app.uid, app);
8925            if (isolated) {
8926                mIsolatedProcesses.put(app.uid, app);
8927            }
8928            updateLruProcessLocked(app, false, null);
8929            updateOomAdjLocked();
8930        }
8931
8932        // This package really, really can not be stopped.
8933        try {
8934            AppGlobals.getPackageManager().setPackageStoppedState(
8935                    info.packageName, false, UserHandle.getUserId(app.uid));
8936        } catch (RemoteException e) {
8937        } catch (IllegalArgumentException e) {
8938            Slog.w(TAG, "Failed trying to unstop package "
8939                    + info.packageName + ": " + e);
8940        }
8941
8942        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8943                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8944            app.persistent = true;
8945            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8946        }
8947        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8948            mPersistentStartingProcesses.add(app);
8949            startProcessLocked(app, "added application", app.processName,
8950                    abiOverride);
8951        }
8952
8953        return app;
8954    }
8955
8956    public void unhandledBack() {
8957        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8958                "unhandledBack()");
8959
8960        synchronized(this) {
8961            final long origId = Binder.clearCallingIdentity();
8962            try {
8963                getFocusedStack().unhandledBackLocked();
8964            } finally {
8965                Binder.restoreCallingIdentity(origId);
8966            }
8967        }
8968    }
8969
8970    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8971        enforceNotIsolatedCaller("openContentUri");
8972        final int userId = UserHandle.getCallingUserId();
8973        String name = uri.getAuthority();
8974        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8975        ParcelFileDescriptor pfd = null;
8976        if (cph != null) {
8977            // We record the binder invoker's uid in thread-local storage before
8978            // going to the content provider to open the file.  Later, in the code
8979            // that handles all permissions checks, we look for this uid and use
8980            // that rather than the Activity Manager's own uid.  The effect is that
8981            // we do the check against the caller's permissions even though it looks
8982            // to the content provider like the Activity Manager itself is making
8983            // the request.
8984            sCallerIdentity.set(new Identity(
8985                    Binder.getCallingPid(), Binder.getCallingUid()));
8986            try {
8987                pfd = cph.provider.openFile(null, uri, "r", null);
8988            } catch (FileNotFoundException e) {
8989                // do nothing; pfd will be returned null
8990            } finally {
8991                // Ensure that whatever happens, we clean up the identity state
8992                sCallerIdentity.remove();
8993            }
8994
8995            // We've got the fd now, so we're done with the provider.
8996            removeContentProviderExternalUnchecked(name, null, userId);
8997        } else {
8998            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8999        }
9000        return pfd;
9001    }
9002
9003    // Actually is sleeping or shutting down or whatever else in the future
9004    // is an inactive state.
9005    public boolean isSleepingOrShuttingDown() {
9006        return mSleeping || mShuttingDown;
9007    }
9008
9009    public boolean isSleeping() {
9010        return mSleeping;
9011    }
9012
9013    void goingToSleep() {
9014        synchronized(this) {
9015            mWentToSleep = true;
9016            updateEventDispatchingLocked();
9017            goToSleepIfNeededLocked();
9018        }
9019    }
9020
9021    void finishRunningVoiceLocked() {
9022        if (mRunningVoice) {
9023            mRunningVoice = false;
9024            goToSleepIfNeededLocked();
9025        }
9026    }
9027
9028    void goToSleepIfNeededLocked() {
9029        if (mWentToSleep && !mRunningVoice) {
9030            if (!mSleeping) {
9031                mSleeping = true;
9032                mStackSupervisor.goingToSleepLocked();
9033
9034                // Initialize the wake times of all processes.
9035                checkExcessivePowerUsageLocked(false);
9036                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9037                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9038                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9039            }
9040        }
9041    }
9042
9043    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9044        mTaskPersister.notify(task, flush);
9045    }
9046
9047    @Override
9048    public boolean shutdown(int timeout) {
9049        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9050                != PackageManager.PERMISSION_GRANTED) {
9051            throw new SecurityException("Requires permission "
9052                    + android.Manifest.permission.SHUTDOWN);
9053        }
9054
9055        boolean timedout = false;
9056
9057        synchronized(this) {
9058            mShuttingDown = true;
9059            updateEventDispatchingLocked();
9060            timedout = mStackSupervisor.shutdownLocked(timeout);
9061        }
9062
9063        mAppOpsService.shutdown();
9064        mUsageStatsService.shutdown();
9065        mBatteryStatsService.shutdown();
9066        synchronized (this) {
9067            mProcessStats.shutdownLocked();
9068        }
9069        notifyTaskPersisterLocked(null, true);
9070
9071        return timedout;
9072    }
9073
9074    public final void activitySlept(IBinder token) {
9075        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9076
9077        final long origId = Binder.clearCallingIdentity();
9078
9079        synchronized (this) {
9080            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9081            if (r != null) {
9082                mStackSupervisor.activitySleptLocked(r);
9083            }
9084        }
9085
9086        Binder.restoreCallingIdentity(origId);
9087    }
9088
9089    void logLockScreen(String msg) {
9090        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9091                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9092                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
9093                mStackSupervisor.mDismissKeyguardOnNextActivity);
9094    }
9095
9096    private void comeOutOfSleepIfNeededLocked() {
9097        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9098            if (mSleeping) {
9099                mSleeping = false;
9100                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9101            }
9102        }
9103    }
9104
9105    void wakingUp() {
9106        synchronized(this) {
9107            mWentToSleep = false;
9108            updateEventDispatchingLocked();
9109            comeOutOfSleepIfNeededLocked();
9110        }
9111    }
9112
9113    void startRunningVoiceLocked() {
9114        if (!mRunningVoice) {
9115            mRunningVoice = true;
9116            comeOutOfSleepIfNeededLocked();
9117        }
9118    }
9119
9120    private void updateEventDispatchingLocked() {
9121        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9122    }
9123
9124    public void setLockScreenShown(boolean shown) {
9125        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9126                != PackageManager.PERMISSION_GRANTED) {
9127            throw new SecurityException("Requires permission "
9128                    + android.Manifest.permission.DEVICE_POWER);
9129        }
9130
9131        synchronized(this) {
9132            long ident = Binder.clearCallingIdentity();
9133            try {
9134                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9135                mLockScreenShown = shown;
9136                comeOutOfSleepIfNeededLocked();
9137            } finally {
9138                Binder.restoreCallingIdentity(ident);
9139            }
9140        }
9141    }
9142
9143    public void stopAppSwitches() {
9144        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9145                != PackageManager.PERMISSION_GRANTED) {
9146            throw new SecurityException("Requires permission "
9147                    + android.Manifest.permission.STOP_APP_SWITCHES);
9148        }
9149
9150        synchronized(this) {
9151            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9152                    + APP_SWITCH_DELAY_TIME;
9153            mDidAppSwitch = false;
9154            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9155            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9156            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9157        }
9158    }
9159
9160    public void resumeAppSwitches() {
9161        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9162                != PackageManager.PERMISSION_GRANTED) {
9163            throw new SecurityException("Requires permission "
9164                    + android.Manifest.permission.STOP_APP_SWITCHES);
9165        }
9166
9167        synchronized(this) {
9168            // Note that we don't execute any pending app switches... we will
9169            // let those wait until either the timeout, or the next start
9170            // activity request.
9171            mAppSwitchesAllowedTime = 0;
9172        }
9173    }
9174
9175    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9176            String name) {
9177        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9178            return true;
9179        }
9180
9181        final int perm = checkComponentPermission(
9182                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9183                callingUid, -1, true);
9184        if (perm == PackageManager.PERMISSION_GRANTED) {
9185            return true;
9186        }
9187
9188        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9189        return false;
9190    }
9191
9192    public void setDebugApp(String packageName, boolean waitForDebugger,
9193            boolean persistent) {
9194        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9195                "setDebugApp()");
9196
9197        long ident = Binder.clearCallingIdentity();
9198        try {
9199            // Note that this is not really thread safe if there are multiple
9200            // callers into it at the same time, but that's not a situation we
9201            // care about.
9202            if (persistent) {
9203                final ContentResolver resolver = mContext.getContentResolver();
9204                Settings.Global.putString(
9205                    resolver, Settings.Global.DEBUG_APP,
9206                    packageName);
9207                Settings.Global.putInt(
9208                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9209                    waitForDebugger ? 1 : 0);
9210            }
9211
9212            synchronized (this) {
9213                if (!persistent) {
9214                    mOrigDebugApp = mDebugApp;
9215                    mOrigWaitForDebugger = mWaitForDebugger;
9216                }
9217                mDebugApp = packageName;
9218                mWaitForDebugger = waitForDebugger;
9219                mDebugTransient = !persistent;
9220                if (packageName != null) {
9221                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9222                            false, UserHandle.USER_ALL, "set debug app");
9223                }
9224            }
9225        } finally {
9226            Binder.restoreCallingIdentity(ident);
9227        }
9228    }
9229
9230    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9231        synchronized (this) {
9232            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9233            if (!isDebuggable) {
9234                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9235                    throw new SecurityException("Process not debuggable: " + app.packageName);
9236                }
9237            }
9238
9239            mOpenGlTraceApp = processName;
9240        }
9241    }
9242
9243    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9244            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9245        synchronized (this) {
9246            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9247            if (!isDebuggable) {
9248                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9249                    throw new SecurityException("Process not debuggable: " + app.packageName);
9250                }
9251            }
9252            mProfileApp = processName;
9253            mProfileFile = profileFile;
9254            if (mProfileFd != null) {
9255                try {
9256                    mProfileFd.close();
9257                } catch (IOException e) {
9258                }
9259                mProfileFd = null;
9260            }
9261            mProfileFd = profileFd;
9262            mProfileType = 0;
9263            mAutoStopProfiler = autoStopProfiler;
9264        }
9265    }
9266
9267    @Override
9268    public void setAlwaysFinish(boolean enabled) {
9269        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9270                "setAlwaysFinish()");
9271
9272        Settings.Global.putInt(
9273                mContext.getContentResolver(),
9274                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9275
9276        synchronized (this) {
9277            mAlwaysFinishActivities = enabled;
9278        }
9279    }
9280
9281    @Override
9282    public void setActivityController(IActivityController controller) {
9283        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9284                "setActivityController()");
9285        synchronized (this) {
9286            mController = controller;
9287            Watchdog.getInstance().setActivityController(controller);
9288        }
9289    }
9290
9291    @Override
9292    public void setUserIsMonkey(boolean userIsMonkey) {
9293        synchronized (this) {
9294            synchronized (mPidsSelfLocked) {
9295                final int callingPid = Binder.getCallingPid();
9296                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9297                if (precessRecord == null) {
9298                    throw new SecurityException("Unknown process: " + callingPid);
9299                }
9300                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9301                    throw new SecurityException("Only an instrumentation process "
9302                            + "with a UiAutomation can call setUserIsMonkey");
9303                }
9304            }
9305            mUserIsMonkey = userIsMonkey;
9306        }
9307    }
9308
9309    @Override
9310    public boolean isUserAMonkey() {
9311        synchronized (this) {
9312            // If there is a controller also implies the user is a monkey.
9313            return (mUserIsMonkey || mController != null);
9314        }
9315    }
9316
9317    public void requestBugReport() {
9318        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9319        SystemProperties.set("ctl.start", "bugreport");
9320    }
9321
9322    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9323        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9324    }
9325
9326    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9327        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9328            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9329        }
9330        return KEY_DISPATCHING_TIMEOUT;
9331    }
9332
9333    @Override
9334    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9335        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9336                != PackageManager.PERMISSION_GRANTED) {
9337            throw new SecurityException("Requires permission "
9338                    + android.Manifest.permission.FILTER_EVENTS);
9339        }
9340        ProcessRecord proc;
9341        long timeout;
9342        synchronized (this) {
9343            synchronized (mPidsSelfLocked) {
9344                proc = mPidsSelfLocked.get(pid);
9345            }
9346            timeout = getInputDispatchingTimeoutLocked(proc);
9347        }
9348
9349        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9350            return -1;
9351        }
9352
9353        return timeout;
9354    }
9355
9356    /**
9357     * Handle input dispatching timeouts.
9358     * Returns whether input dispatching should be aborted or not.
9359     */
9360    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9361            final ActivityRecord activity, final ActivityRecord parent,
9362            final boolean aboveSystem, String reason) {
9363        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9364                != PackageManager.PERMISSION_GRANTED) {
9365            throw new SecurityException("Requires permission "
9366                    + android.Manifest.permission.FILTER_EVENTS);
9367        }
9368
9369        final String annotation;
9370        if (reason == null) {
9371            annotation = "Input dispatching timed out";
9372        } else {
9373            annotation = "Input dispatching timed out (" + reason + ")";
9374        }
9375
9376        if (proc != null) {
9377            synchronized (this) {
9378                if (proc.debugging) {
9379                    return false;
9380                }
9381
9382                if (mDidDexOpt) {
9383                    // Give more time since we were dexopting.
9384                    mDidDexOpt = false;
9385                    return false;
9386                }
9387
9388                if (proc.instrumentationClass != null) {
9389                    Bundle info = new Bundle();
9390                    info.putString("shortMsg", "keyDispatchingTimedOut");
9391                    info.putString("longMsg", annotation);
9392                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9393                    return true;
9394                }
9395            }
9396            mHandler.post(new Runnable() {
9397                @Override
9398                public void run() {
9399                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9400                }
9401            });
9402        }
9403
9404        return true;
9405    }
9406
9407    public Bundle getAssistContextExtras(int requestType) {
9408        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9409                "getAssistContextExtras()");
9410        PendingAssistExtras pae;
9411        Bundle extras = new Bundle();
9412        synchronized (this) {
9413            ActivityRecord activity = getFocusedStack().mResumedActivity;
9414            if (activity == null) {
9415                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9416                return null;
9417            }
9418            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9419            if (activity.app == null || activity.app.thread == null) {
9420                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9421                return extras;
9422            }
9423            if (activity.app.pid == Binder.getCallingPid()) {
9424                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9425                return extras;
9426            }
9427            pae = new PendingAssistExtras(activity);
9428            try {
9429                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9430                        requestType);
9431                mPendingAssistExtras.add(pae);
9432                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9433            } catch (RemoteException e) {
9434                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9435                return extras;
9436            }
9437        }
9438        synchronized (pae) {
9439            while (!pae.haveResult) {
9440                try {
9441                    pae.wait();
9442                } catch (InterruptedException e) {
9443                }
9444            }
9445            if (pae.result != null) {
9446                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9447            }
9448        }
9449        synchronized (this) {
9450            mPendingAssistExtras.remove(pae);
9451            mHandler.removeCallbacks(pae);
9452        }
9453        return extras;
9454    }
9455
9456    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9457        PendingAssistExtras pae = (PendingAssistExtras)token;
9458        synchronized (pae) {
9459            pae.result = extras;
9460            pae.haveResult = true;
9461            pae.notifyAll();
9462        }
9463    }
9464
9465    public void registerProcessObserver(IProcessObserver observer) {
9466        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9467                "registerProcessObserver()");
9468        synchronized (this) {
9469            mProcessObservers.register(observer);
9470        }
9471    }
9472
9473    @Override
9474    public void unregisterProcessObserver(IProcessObserver observer) {
9475        synchronized (this) {
9476            mProcessObservers.unregister(observer);
9477        }
9478    }
9479
9480    @Override
9481    public boolean convertFromTranslucent(IBinder token) {
9482        final long origId = Binder.clearCallingIdentity();
9483        try {
9484            synchronized (this) {
9485                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9486                if (r == null) {
9487                    return false;
9488                }
9489                if (r.changeWindowTranslucency(true)) {
9490                    mWindowManager.setAppFullscreen(token, true);
9491                    r.task.stack.releaseMediaResources();
9492                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9493                    return true;
9494                }
9495                return false;
9496            }
9497        } finally {
9498            Binder.restoreCallingIdentity(origId);
9499        }
9500    }
9501
9502    @Override
9503    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9504        final long origId = Binder.clearCallingIdentity();
9505        try {
9506            synchronized (this) {
9507                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9508                if (r == null) {
9509                    return false;
9510                }
9511                if (r.changeWindowTranslucency(false)) {
9512                    r.task.stack.convertToTranslucent(r, options);
9513                    mWindowManager.setAppFullscreen(token, false);
9514                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9515                    return true;
9516                } else {
9517                    r.task.stack.mReturningActivityOptions = options;
9518                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9519                    return false;
9520                }
9521            }
9522        } finally {
9523            Binder.restoreCallingIdentity(origId);
9524        }
9525    }
9526
9527    @Override
9528    public boolean setMediaPlaying(IBinder token, boolean playing) {
9529        final long origId = Binder.clearCallingIdentity();
9530        try {
9531            synchronized (this) {
9532                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9533                if (r != null) {
9534                    return mStackSupervisor.setMediaPlayingLocked(r, playing);
9535                }
9536            }
9537            return false;
9538        } finally {
9539            Binder.restoreCallingIdentity(origId);
9540        }
9541    }
9542
9543    @Override
9544    public boolean isBackgroundMediaPlaying(IBinder token) {
9545        final long origId = Binder.clearCallingIdentity();
9546        try {
9547            synchronized (this) {
9548                final ActivityStack stack = ActivityRecord.getStackLocked(token);
9549                final boolean playing = stack == null ? false : stack.isMediaPlaying();
9550                if (ActivityStackSupervisor.DEBUG_MEDIA_VISIBILITY) Slog.d(TAG,
9551                        "isBackgroundMediaPlaying: stack=" + stack + " playing=" + playing);
9552                return playing;
9553            }
9554        } finally {
9555            Binder.restoreCallingIdentity(origId);
9556        }
9557    }
9558
9559    @Override
9560    public ActivityOptions getActivityOptions(IBinder token) {
9561        final long origId = Binder.clearCallingIdentity();
9562        try {
9563            synchronized (this) {
9564                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9565                if (r != null) {
9566                    final ActivityOptions activityOptions = r.pendingOptions;
9567                    r.pendingOptions = null;
9568                    return activityOptions;
9569                }
9570                return null;
9571            }
9572        } finally {
9573            Binder.restoreCallingIdentity(origId);
9574        }
9575    }
9576
9577    @Override
9578    public void setImmersive(IBinder token, boolean immersive) {
9579        synchronized(this) {
9580            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9581            if (r == null) {
9582                throw new IllegalArgumentException();
9583            }
9584            r.immersive = immersive;
9585
9586            // update associated state if we're frontmost
9587            if (r == mFocusedActivity) {
9588                if (DEBUG_IMMERSIVE) {
9589                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9590                }
9591                applyUpdateLockStateLocked(r);
9592            }
9593        }
9594    }
9595
9596    @Override
9597    public boolean isImmersive(IBinder token) {
9598        synchronized (this) {
9599            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9600            if (r == null) {
9601                throw new IllegalArgumentException();
9602            }
9603            return r.immersive;
9604        }
9605    }
9606
9607    public boolean isTopActivityImmersive() {
9608        enforceNotIsolatedCaller("startActivity");
9609        synchronized (this) {
9610            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9611            return (r != null) ? r.immersive : false;
9612        }
9613    }
9614
9615    @Override
9616    public boolean isTopOfTask(IBinder token) {
9617        synchronized (this) {
9618            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9619            if (r == null) {
9620                throw new IllegalArgumentException();
9621            }
9622            return r.task.getTopActivity() == r;
9623        }
9624    }
9625
9626    public final void enterSafeMode() {
9627        synchronized(this) {
9628            // It only makes sense to do this before the system is ready
9629            // and started launching other packages.
9630            if (!mSystemReady) {
9631                try {
9632                    AppGlobals.getPackageManager().enterSafeMode();
9633                } catch (RemoteException e) {
9634                }
9635            }
9636
9637            mSafeMode = true;
9638        }
9639    }
9640
9641    public final void showSafeModeOverlay() {
9642        View v = LayoutInflater.from(mContext).inflate(
9643                com.android.internal.R.layout.safe_mode, null);
9644        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9645        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9646        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9647        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9648        lp.gravity = Gravity.BOTTOM | Gravity.START;
9649        lp.format = v.getBackground().getOpacity();
9650        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9651                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9652        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9653        ((WindowManager)mContext.getSystemService(
9654                Context.WINDOW_SERVICE)).addView(v, lp);
9655    }
9656
9657    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9658        if (!(sender instanceof PendingIntentRecord)) {
9659            return;
9660        }
9661        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9662        synchronized (stats) {
9663            if (mBatteryStatsService.isOnBattery()) {
9664                mBatteryStatsService.enforceCallingPermission();
9665                PendingIntentRecord rec = (PendingIntentRecord)sender;
9666                int MY_UID = Binder.getCallingUid();
9667                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9668                BatteryStatsImpl.Uid.Pkg pkg =
9669                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9670                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9671                pkg.incWakeupsLocked();
9672            }
9673        }
9674    }
9675
9676    public boolean killPids(int[] pids, String pReason, boolean secure) {
9677        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9678            throw new SecurityException("killPids only available to the system");
9679        }
9680        String reason = (pReason == null) ? "Unknown" : pReason;
9681        // XXX Note: don't acquire main activity lock here, because the window
9682        // manager calls in with its locks held.
9683
9684        boolean killed = false;
9685        synchronized (mPidsSelfLocked) {
9686            int[] types = new int[pids.length];
9687            int worstType = 0;
9688            for (int i=0; i<pids.length; i++) {
9689                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9690                if (proc != null) {
9691                    int type = proc.setAdj;
9692                    types[i] = type;
9693                    if (type > worstType) {
9694                        worstType = type;
9695                    }
9696                }
9697            }
9698
9699            // If the worst oom_adj is somewhere in the cached proc LRU range,
9700            // then constrain it so we will kill all cached procs.
9701            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9702                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9703                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9704            }
9705
9706            // If this is not a secure call, don't let it kill processes that
9707            // are important.
9708            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9709                worstType = ProcessList.SERVICE_ADJ;
9710            }
9711
9712            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9713            for (int i=0; i<pids.length; i++) {
9714                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9715                if (proc == null) {
9716                    continue;
9717                }
9718                int adj = proc.setAdj;
9719                if (adj >= worstType && !proc.killedByAm) {
9720                    killUnneededProcessLocked(proc, reason);
9721                    killed = true;
9722                }
9723            }
9724        }
9725        return killed;
9726    }
9727
9728    @Override
9729    public void killUid(int uid, String reason) {
9730        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9731            throw new SecurityException("killUid only available to the system");
9732        }
9733        synchronized (this) {
9734            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9735                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9736                    reason != null ? reason : "kill uid");
9737        }
9738    }
9739
9740    @Override
9741    public boolean killProcessesBelowForeground(String reason) {
9742        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9743            throw new SecurityException("killProcessesBelowForeground() only available to system");
9744        }
9745
9746        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9747    }
9748
9749    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9750        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9751            throw new SecurityException("killProcessesBelowAdj() only available to system");
9752        }
9753
9754        boolean killed = false;
9755        synchronized (mPidsSelfLocked) {
9756            final int size = mPidsSelfLocked.size();
9757            for (int i = 0; i < size; i++) {
9758                final int pid = mPidsSelfLocked.keyAt(i);
9759                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9760                if (proc == null) continue;
9761
9762                final int adj = proc.setAdj;
9763                if (adj > belowAdj && !proc.killedByAm) {
9764                    killUnneededProcessLocked(proc, reason);
9765                    killed = true;
9766                }
9767            }
9768        }
9769        return killed;
9770    }
9771
9772    @Override
9773    public void hang(final IBinder who, boolean allowRestart) {
9774        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9775                != PackageManager.PERMISSION_GRANTED) {
9776            throw new SecurityException("Requires permission "
9777                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9778        }
9779
9780        final IBinder.DeathRecipient death = new DeathRecipient() {
9781            @Override
9782            public void binderDied() {
9783                synchronized (this) {
9784                    notifyAll();
9785                }
9786            }
9787        };
9788
9789        try {
9790            who.linkToDeath(death, 0);
9791        } catch (RemoteException e) {
9792            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9793            return;
9794        }
9795
9796        synchronized (this) {
9797            Watchdog.getInstance().setAllowRestart(allowRestart);
9798            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9799            synchronized (death) {
9800                while (who.isBinderAlive()) {
9801                    try {
9802                        death.wait();
9803                    } catch (InterruptedException e) {
9804                    }
9805                }
9806            }
9807            Watchdog.getInstance().setAllowRestart(true);
9808        }
9809    }
9810
9811    @Override
9812    public void restart() {
9813        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9814                != PackageManager.PERMISSION_GRANTED) {
9815            throw new SecurityException("Requires permission "
9816                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9817        }
9818
9819        Log.i(TAG, "Sending shutdown broadcast...");
9820
9821        BroadcastReceiver br = new BroadcastReceiver() {
9822            @Override public void onReceive(Context context, Intent intent) {
9823                // Now the broadcast is done, finish up the low-level shutdown.
9824                Log.i(TAG, "Shutting down activity manager...");
9825                shutdown(10000);
9826                Log.i(TAG, "Shutdown complete, restarting!");
9827                Process.killProcess(Process.myPid());
9828                System.exit(10);
9829            }
9830        };
9831
9832        // First send the high-level shut down broadcast.
9833        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9834        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9835        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9836        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9837        mContext.sendOrderedBroadcastAsUser(intent,
9838                UserHandle.ALL, null, br, mHandler, 0, null, null);
9839        */
9840        br.onReceive(mContext, intent);
9841    }
9842
9843    private long getLowRamTimeSinceIdle(long now) {
9844        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9845    }
9846
9847    @Override
9848    public void performIdleMaintenance() {
9849        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9850                != PackageManager.PERMISSION_GRANTED) {
9851            throw new SecurityException("Requires permission "
9852                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9853        }
9854
9855        synchronized (this) {
9856            final long now = SystemClock.uptimeMillis();
9857            final long timeSinceLastIdle = now - mLastIdleTime;
9858            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9859            mLastIdleTime = now;
9860            mLowRamTimeSinceLastIdle = 0;
9861            if (mLowRamStartTime != 0) {
9862                mLowRamStartTime = now;
9863            }
9864
9865            StringBuilder sb = new StringBuilder(128);
9866            sb.append("Idle maintenance over ");
9867            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9868            sb.append(" low RAM for ");
9869            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9870            Slog.i(TAG, sb.toString());
9871
9872            // If at least 1/3 of our time since the last idle period has been spent
9873            // with RAM low, then we want to kill processes.
9874            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9875
9876            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9877                ProcessRecord proc = mLruProcesses.get(i);
9878                if (proc.notCachedSinceIdle) {
9879                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9880                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9881                        if (doKilling && proc.initialIdlePss != 0
9882                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9883                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9884                                    + " from " + proc.initialIdlePss + ")");
9885                        }
9886                    }
9887                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9888                    proc.notCachedSinceIdle = true;
9889                    proc.initialIdlePss = 0;
9890                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9891                            isSleeping(), now);
9892                }
9893            }
9894
9895            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9896            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9897        }
9898    }
9899
9900    private void retrieveSettings() {
9901        final ContentResolver resolver = mContext.getContentResolver();
9902        String debugApp = Settings.Global.getString(
9903            resolver, Settings.Global.DEBUG_APP);
9904        boolean waitForDebugger = Settings.Global.getInt(
9905            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9906        boolean alwaysFinishActivities = Settings.Global.getInt(
9907            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9908        boolean forceRtl = Settings.Global.getInt(
9909                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9910        // Transfer any global setting for forcing RTL layout, into a System Property
9911        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9912
9913        Configuration configuration = new Configuration();
9914        Settings.System.getConfiguration(resolver, configuration);
9915        if (forceRtl) {
9916            // This will take care of setting the correct layout direction flags
9917            configuration.setLayoutDirection(configuration.locale);
9918        }
9919
9920        synchronized (this) {
9921            mDebugApp = mOrigDebugApp = debugApp;
9922            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9923            mAlwaysFinishActivities = alwaysFinishActivities;
9924            // This happens before any activities are started, so we can
9925            // change mConfiguration in-place.
9926            updateConfigurationLocked(configuration, null, false, true);
9927            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9928        }
9929    }
9930
9931    public boolean testIsSystemReady() {
9932        // no need to synchronize(this) just to read & return the value
9933        return mSystemReady;
9934    }
9935
9936    private static File getCalledPreBootReceiversFile() {
9937        File dataDir = Environment.getDataDirectory();
9938        File systemDir = new File(dataDir, "system");
9939        File fname = new File(systemDir, "called_pre_boots.dat");
9940        return fname;
9941    }
9942
9943    static final int LAST_DONE_VERSION = 10000;
9944
9945    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9946        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9947        File file = getCalledPreBootReceiversFile();
9948        FileInputStream fis = null;
9949        try {
9950            fis = new FileInputStream(file);
9951            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9952            int fvers = dis.readInt();
9953            if (fvers == LAST_DONE_VERSION) {
9954                String vers = dis.readUTF();
9955                String codename = dis.readUTF();
9956                String build = dis.readUTF();
9957                if (android.os.Build.VERSION.RELEASE.equals(vers)
9958                        && android.os.Build.VERSION.CODENAME.equals(codename)
9959                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9960                    int num = dis.readInt();
9961                    while (num > 0) {
9962                        num--;
9963                        String pkg = dis.readUTF();
9964                        String cls = dis.readUTF();
9965                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9966                    }
9967                }
9968            }
9969        } catch (FileNotFoundException e) {
9970        } catch (IOException e) {
9971            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9972        } finally {
9973            if (fis != null) {
9974                try {
9975                    fis.close();
9976                } catch (IOException e) {
9977                }
9978            }
9979        }
9980        return lastDoneReceivers;
9981    }
9982
9983    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9984        File file = getCalledPreBootReceiversFile();
9985        FileOutputStream fos = null;
9986        DataOutputStream dos = null;
9987        try {
9988            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9989            fos = new FileOutputStream(file);
9990            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9991            dos.writeInt(LAST_DONE_VERSION);
9992            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9993            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9994            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9995            dos.writeInt(list.size());
9996            for (int i=0; i<list.size(); i++) {
9997                dos.writeUTF(list.get(i).getPackageName());
9998                dos.writeUTF(list.get(i).getClassName());
9999            }
10000        } catch (IOException e) {
10001            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10002            file.delete();
10003        } finally {
10004            FileUtils.sync(fos);
10005            if (dos != null) {
10006                try {
10007                    dos.close();
10008                } catch (IOException e) {
10009                    // TODO Auto-generated catch block
10010                    e.printStackTrace();
10011                }
10012            }
10013        }
10014    }
10015
10016    public void systemReady(final Runnable goingCallback) {
10017        synchronized(this) {
10018            if (mSystemReady) {
10019                if (goingCallback != null) goingCallback.run();
10020                return;
10021            }
10022
10023            // Make sure we have the current profile info, since it is needed for
10024            // security checks.
10025            updateCurrentProfileIdsLocked();
10026
10027            if (mRecentTasks == null) {
10028                mRecentTasks = mTaskPersister.restoreTasksLocked();
10029                if (!mRecentTasks.isEmpty()) {
10030                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10031                }
10032                mTaskPersister.startPersisting();
10033            }
10034
10035            // Check to see if there are any update receivers to run.
10036            if (!mDidUpdate) {
10037                if (mWaitingUpdate) {
10038                    return;
10039                }
10040                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10041                List<ResolveInfo> ris = null;
10042                try {
10043                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
10044                            intent, null, 0, 0);
10045                } catch (RemoteException e) {
10046                }
10047                if (ris != null) {
10048                    for (int i=ris.size()-1; i>=0; i--) {
10049                        if ((ris.get(i).activityInfo.applicationInfo.flags
10050                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
10051                            ris.remove(i);
10052                        }
10053                    }
10054                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10055
10056                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10057
10058                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10059                    for (int i=0; i<ris.size(); i++) {
10060                        ActivityInfo ai = ris.get(i).activityInfo;
10061                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
10062                        if (lastDoneReceivers.contains(comp)) {
10063                            // We already did the pre boot receiver for this app with the current
10064                            // platform version, so don't do it again...
10065                            ris.remove(i);
10066                            i--;
10067                            // ...however, do keep it as one that has been done, so we don't
10068                            // forget about it when rewriting the file of last done receivers.
10069                            doneReceivers.add(comp);
10070                        }
10071                    }
10072
10073                    final int[] users = getUsersLocked();
10074                    for (int i=0; i<ris.size(); i++) {
10075                        ActivityInfo ai = ris.get(i).activityInfo;
10076                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
10077                        doneReceivers.add(comp);
10078                        intent.setComponent(comp);
10079                        for (int j=0; j<users.length; j++) {
10080                            IIntentReceiver finisher = null;
10081                            if (i == ris.size()-1 && j == users.length-1) {
10082                                finisher = new IIntentReceiver.Stub() {
10083                                    public void performReceive(Intent intent, int resultCode,
10084                                            String data, Bundle extras, boolean ordered,
10085                                            boolean sticky, int sendingUser) {
10086                                        // The raw IIntentReceiver interface is called
10087                                        // with the AM lock held, so redispatch to
10088                                        // execute our code without the lock.
10089                                        mHandler.post(new Runnable() {
10090                                            public void run() {
10091                                                synchronized (ActivityManagerService.this) {
10092                                                    mDidUpdate = true;
10093                                                }
10094                                                writeLastDonePreBootReceivers(doneReceivers);
10095                                                showBootMessage(mContext.getText(
10096                                                        R.string.android_upgrading_complete),
10097                                                        false);
10098                                                systemReady(goingCallback);
10099                                            }
10100                                        });
10101                                    }
10102                                };
10103                            }
10104                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
10105                                    + " for user " + users[j]);
10106                            broadcastIntentLocked(null, null, intent, null, finisher,
10107                                    0, null, null, null, AppOpsManager.OP_NONE,
10108                                    true, false, MY_PID, Process.SYSTEM_UID,
10109                                    users[j]);
10110                            if (finisher != null) {
10111                                mWaitingUpdate = true;
10112                            }
10113                        }
10114                    }
10115                }
10116                if (mWaitingUpdate) {
10117                    return;
10118                }
10119                mDidUpdate = true;
10120            }
10121
10122            mAppOpsService.systemReady();
10123            mUsageStatsService.systemReady();
10124            mSystemReady = true;
10125        }
10126
10127        ArrayList<ProcessRecord> procsToKill = null;
10128        synchronized(mPidsSelfLocked) {
10129            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10130                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10131                if (!isAllowedWhileBooting(proc.info)){
10132                    if (procsToKill == null) {
10133                        procsToKill = new ArrayList<ProcessRecord>();
10134                    }
10135                    procsToKill.add(proc);
10136                }
10137            }
10138        }
10139
10140        synchronized(this) {
10141            if (procsToKill != null) {
10142                for (int i=procsToKill.size()-1; i>=0; i--) {
10143                    ProcessRecord proc = procsToKill.get(i);
10144                    Slog.i(TAG, "Removing system update proc: " + proc);
10145                    removeProcessLocked(proc, true, false, "system update done");
10146                }
10147            }
10148
10149            // Now that we have cleaned up any update processes, we
10150            // are ready to start launching real processes and know that
10151            // we won't trample on them any more.
10152            mProcessesReady = true;
10153        }
10154
10155        Slog.i(TAG, "System now ready");
10156        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10157            SystemClock.uptimeMillis());
10158
10159        synchronized(this) {
10160            // Make sure we have no pre-ready processes sitting around.
10161
10162            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10163                ResolveInfo ri = mContext.getPackageManager()
10164                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10165                                STOCK_PM_FLAGS);
10166                CharSequence errorMsg = null;
10167                if (ri != null) {
10168                    ActivityInfo ai = ri.activityInfo;
10169                    ApplicationInfo app = ai.applicationInfo;
10170                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10171                        mTopAction = Intent.ACTION_FACTORY_TEST;
10172                        mTopData = null;
10173                        mTopComponent = new ComponentName(app.packageName,
10174                                ai.name);
10175                    } else {
10176                        errorMsg = mContext.getResources().getText(
10177                                com.android.internal.R.string.factorytest_not_system);
10178                    }
10179                } else {
10180                    errorMsg = mContext.getResources().getText(
10181                            com.android.internal.R.string.factorytest_no_action);
10182                }
10183                if (errorMsg != null) {
10184                    mTopAction = null;
10185                    mTopData = null;
10186                    mTopComponent = null;
10187                    Message msg = Message.obtain();
10188                    msg.what = SHOW_FACTORY_ERROR_MSG;
10189                    msg.getData().putCharSequence("msg", errorMsg);
10190                    mHandler.sendMessage(msg);
10191                }
10192            }
10193        }
10194
10195        retrieveSettings();
10196
10197        synchronized (this) {
10198            readGrantedUriPermissionsLocked();
10199        }
10200
10201        if (goingCallback != null) goingCallback.run();
10202
10203        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10204                Integer.toString(mCurrentUserId), mCurrentUserId);
10205        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10206                Integer.toString(mCurrentUserId), mCurrentUserId);
10207        mSystemServiceManager.startUser(mCurrentUserId);
10208
10209        synchronized (this) {
10210            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10211                try {
10212                    List apps = AppGlobals.getPackageManager().
10213                        getPersistentApplications(STOCK_PM_FLAGS);
10214                    if (apps != null) {
10215                        int N = apps.size();
10216                        int i;
10217                        for (i=0; i<N; i++) {
10218                            ApplicationInfo info
10219                                = (ApplicationInfo)apps.get(i);
10220                            if (info != null &&
10221                                    !info.packageName.equals("android")) {
10222                                addAppLocked(info, false, null /* ABI override */);
10223                            }
10224                        }
10225                    }
10226                } catch (RemoteException ex) {
10227                    // pm is in same process, this will never happen.
10228                }
10229            }
10230
10231            // Start up initial activity.
10232            mBooting = true;
10233
10234            try {
10235                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10236                    Message msg = Message.obtain();
10237                    msg.what = SHOW_UID_ERROR_MSG;
10238                    mHandler.sendMessage(msg);
10239                }
10240            } catch (RemoteException e) {
10241            }
10242
10243            long ident = Binder.clearCallingIdentity();
10244            try {
10245                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10246                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10247                        | Intent.FLAG_RECEIVER_FOREGROUND);
10248                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10249                broadcastIntentLocked(null, null, intent,
10250                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10251                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10252                intent = new Intent(Intent.ACTION_USER_STARTING);
10253                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10254                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10255                broadcastIntentLocked(null, null, intent,
10256                        null, new IIntentReceiver.Stub() {
10257                            @Override
10258                            public void performReceive(Intent intent, int resultCode, String data,
10259                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10260                                    throws RemoteException {
10261                            }
10262                        }, 0, null, null,
10263                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10264                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10265            } catch (Throwable t) {
10266                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10267            } finally {
10268                Binder.restoreCallingIdentity(ident);
10269            }
10270            mStackSupervisor.resumeTopActivitiesLocked();
10271            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10272        }
10273    }
10274
10275    private boolean makeAppCrashingLocked(ProcessRecord app,
10276            String shortMsg, String longMsg, String stackTrace) {
10277        app.crashing = true;
10278        app.crashingReport = generateProcessError(app,
10279                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10280        startAppProblemLocked(app);
10281        app.stopFreezingAllLocked();
10282        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10283    }
10284
10285    private void makeAppNotRespondingLocked(ProcessRecord app,
10286            String activity, String shortMsg, String longMsg) {
10287        app.notResponding = true;
10288        app.notRespondingReport = generateProcessError(app,
10289                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10290                activity, shortMsg, longMsg, null);
10291        startAppProblemLocked(app);
10292        app.stopFreezingAllLocked();
10293    }
10294
10295    /**
10296     * Generate a process error record, suitable for attachment to a ProcessRecord.
10297     *
10298     * @param app The ProcessRecord in which the error occurred.
10299     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10300     *                      ActivityManager.AppErrorStateInfo
10301     * @param activity The activity associated with the crash, if known.
10302     * @param shortMsg Short message describing the crash.
10303     * @param longMsg Long message describing the crash.
10304     * @param stackTrace Full crash stack trace, may be null.
10305     *
10306     * @return Returns a fully-formed AppErrorStateInfo record.
10307     */
10308    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10309            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10310        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10311
10312        report.condition = condition;
10313        report.processName = app.processName;
10314        report.pid = app.pid;
10315        report.uid = app.info.uid;
10316        report.tag = activity;
10317        report.shortMsg = shortMsg;
10318        report.longMsg = longMsg;
10319        report.stackTrace = stackTrace;
10320
10321        return report;
10322    }
10323
10324    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10325        synchronized (this) {
10326            app.crashing = false;
10327            app.crashingReport = null;
10328            app.notResponding = false;
10329            app.notRespondingReport = null;
10330            if (app.anrDialog == fromDialog) {
10331                app.anrDialog = null;
10332            }
10333            if (app.waitDialog == fromDialog) {
10334                app.waitDialog = null;
10335            }
10336            if (app.pid > 0 && app.pid != MY_PID) {
10337                handleAppCrashLocked(app, null, null, null);
10338                killUnneededProcessLocked(app, "user request after error");
10339            }
10340        }
10341    }
10342
10343    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10344            String stackTrace) {
10345        long now = SystemClock.uptimeMillis();
10346
10347        Long crashTime;
10348        if (!app.isolated) {
10349            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10350        } else {
10351            crashTime = null;
10352        }
10353        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10354            // This process loses!
10355            Slog.w(TAG, "Process " + app.info.processName
10356                    + " has crashed too many times: killing!");
10357            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10358                    app.userId, app.info.processName, app.uid);
10359            mStackSupervisor.handleAppCrashLocked(app);
10360            if (!app.persistent) {
10361                // We don't want to start this process again until the user
10362                // explicitly does so...  but for persistent process, we really
10363                // need to keep it running.  If a persistent process is actually
10364                // repeatedly crashing, then badness for everyone.
10365                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10366                        app.info.processName);
10367                if (!app.isolated) {
10368                    // XXX We don't have a way to mark isolated processes
10369                    // as bad, since they don't have a peristent identity.
10370                    mBadProcesses.put(app.info.processName, app.uid,
10371                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10372                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10373                }
10374                app.bad = true;
10375                app.removed = true;
10376                // Don't let services in this process be restarted and potentially
10377                // annoy the user repeatedly.  Unless it is persistent, since those
10378                // processes run critical code.
10379                removeProcessLocked(app, false, false, "crash");
10380                mStackSupervisor.resumeTopActivitiesLocked();
10381                return false;
10382            }
10383            mStackSupervisor.resumeTopActivitiesLocked();
10384        } else {
10385            mStackSupervisor.finishTopRunningActivityLocked(app);
10386        }
10387
10388        // Bump up the crash count of any services currently running in the proc.
10389        for (int i=app.services.size()-1; i>=0; i--) {
10390            // Any services running in the application need to be placed
10391            // back in the pending list.
10392            ServiceRecord sr = app.services.valueAt(i);
10393            sr.crashCount++;
10394        }
10395
10396        // If the crashing process is what we consider to be the "home process" and it has been
10397        // replaced by a third-party app, clear the package preferred activities from packages
10398        // with a home activity running in the process to prevent a repeatedly crashing app
10399        // from blocking the user to manually clear the list.
10400        final ArrayList<ActivityRecord> activities = app.activities;
10401        if (app == mHomeProcess && activities.size() > 0
10402                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10403            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10404                final ActivityRecord r = activities.get(activityNdx);
10405                if (r.isHomeActivity()) {
10406                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10407                    try {
10408                        ActivityThread.getPackageManager()
10409                                .clearPackagePreferredActivities(r.packageName);
10410                    } catch (RemoteException c) {
10411                        // pm is in same process, this will never happen.
10412                    }
10413                }
10414            }
10415        }
10416
10417        if (!app.isolated) {
10418            // XXX Can't keep track of crash times for isolated processes,
10419            // because they don't have a perisistent identity.
10420            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10421        }
10422
10423        return true;
10424    }
10425
10426    void startAppProblemLocked(ProcessRecord app) {
10427        if (app.userId == mCurrentUserId) {
10428            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10429                    mContext, app.info.packageName, app.info.flags);
10430        } else {
10431            // If this app is not running under the current user, then we
10432            // can't give it a report button because that would require
10433            // launching the report UI under a different user.
10434            app.errorReportReceiver = null;
10435        }
10436        skipCurrentReceiverLocked(app);
10437    }
10438
10439    void skipCurrentReceiverLocked(ProcessRecord app) {
10440        for (BroadcastQueue queue : mBroadcastQueues) {
10441            queue.skipCurrentReceiverLocked(app);
10442        }
10443    }
10444
10445    /**
10446     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10447     * The application process will exit immediately after this call returns.
10448     * @param app object of the crashing app, null for the system server
10449     * @param crashInfo describing the exception
10450     */
10451    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10452        ProcessRecord r = findAppProcess(app, "Crash");
10453        final String processName = app == null ? "system_server"
10454                : (r == null ? "unknown" : r.processName);
10455
10456        handleApplicationCrashInner("crash", r, processName, crashInfo);
10457    }
10458
10459    /* Native crash reporting uses this inner version because it needs to be somewhat
10460     * decoupled from the AM-managed cleanup lifecycle
10461     */
10462    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10463            ApplicationErrorReport.CrashInfo crashInfo) {
10464        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10465                UserHandle.getUserId(Binder.getCallingUid()), processName,
10466                r == null ? -1 : r.info.flags,
10467                crashInfo.exceptionClassName,
10468                crashInfo.exceptionMessage,
10469                crashInfo.throwFileName,
10470                crashInfo.throwLineNumber);
10471
10472        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10473
10474        crashApplication(r, crashInfo);
10475    }
10476
10477    public void handleApplicationStrictModeViolation(
10478            IBinder app,
10479            int violationMask,
10480            StrictMode.ViolationInfo info) {
10481        ProcessRecord r = findAppProcess(app, "StrictMode");
10482        if (r == null) {
10483            return;
10484        }
10485
10486        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10487            Integer stackFingerprint = info.hashCode();
10488            boolean logIt = true;
10489            synchronized (mAlreadyLoggedViolatedStacks) {
10490                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10491                    logIt = false;
10492                    // TODO: sub-sample into EventLog for these, with
10493                    // the info.durationMillis?  Then we'd get
10494                    // the relative pain numbers, without logging all
10495                    // the stack traces repeatedly.  We'd want to do
10496                    // likewise in the client code, which also does
10497                    // dup suppression, before the Binder call.
10498                } else {
10499                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10500                        mAlreadyLoggedViolatedStacks.clear();
10501                    }
10502                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10503                }
10504            }
10505            if (logIt) {
10506                logStrictModeViolationToDropBox(r, info);
10507            }
10508        }
10509
10510        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10511            AppErrorResult result = new AppErrorResult();
10512            synchronized (this) {
10513                final long origId = Binder.clearCallingIdentity();
10514
10515                Message msg = Message.obtain();
10516                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10517                HashMap<String, Object> data = new HashMap<String, Object>();
10518                data.put("result", result);
10519                data.put("app", r);
10520                data.put("violationMask", violationMask);
10521                data.put("info", info);
10522                msg.obj = data;
10523                mHandler.sendMessage(msg);
10524
10525                Binder.restoreCallingIdentity(origId);
10526            }
10527            int res = result.get();
10528            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10529        }
10530    }
10531
10532    // Depending on the policy in effect, there could be a bunch of
10533    // these in quick succession so we try to batch these together to
10534    // minimize disk writes, number of dropbox entries, and maximize
10535    // compression, by having more fewer, larger records.
10536    private void logStrictModeViolationToDropBox(
10537            ProcessRecord process,
10538            StrictMode.ViolationInfo info) {
10539        if (info == null) {
10540            return;
10541        }
10542        final boolean isSystemApp = process == null ||
10543                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10544                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10545        final String processName = process == null ? "unknown" : process.processName;
10546        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10547        final DropBoxManager dbox = (DropBoxManager)
10548                mContext.getSystemService(Context.DROPBOX_SERVICE);
10549
10550        // Exit early if the dropbox isn't configured to accept this report type.
10551        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10552
10553        boolean bufferWasEmpty;
10554        boolean needsFlush;
10555        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10556        synchronized (sb) {
10557            bufferWasEmpty = sb.length() == 0;
10558            appendDropBoxProcessHeaders(process, processName, sb);
10559            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10560            sb.append("System-App: ").append(isSystemApp).append("\n");
10561            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10562            if (info.violationNumThisLoop != 0) {
10563                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10564            }
10565            if (info.numAnimationsRunning != 0) {
10566                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10567            }
10568            if (info.broadcastIntentAction != null) {
10569                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10570            }
10571            if (info.durationMillis != -1) {
10572                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10573            }
10574            if (info.numInstances != -1) {
10575                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10576            }
10577            if (info.tags != null) {
10578                for (String tag : info.tags) {
10579                    sb.append("Span-Tag: ").append(tag).append("\n");
10580                }
10581            }
10582            sb.append("\n");
10583            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10584                sb.append(info.crashInfo.stackTrace);
10585            }
10586            sb.append("\n");
10587
10588            // Only buffer up to ~64k.  Various logging bits truncate
10589            // things at 128k.
10590            needsFlush = (sb.length() > 64 * 1024);
10591        }
10592
10593        // Flush immediately if the buffer's grown too large, or this
10594        // is a non-system app.  Non-system apps are isolated with a
10595        // different tag & policy and not batched.
10596        //
10597        // Batching is useful during internal testing with
10598        // StrictMode settings turned up high.  Without batching,
10599        // thousands of separate files could be created on boot.
10600        if (!isSystemApp || needsFlush) {
10601            new Thread("Error dump: " + dropboxTag) {
10602                @Override
10603                public void run() {
10604                    String report;
10605                    synchronized (sb) {
10606                        report = sb.toString();
10607                        sb.delete(0, sb.length());
10608                        sb.trimToSize();
10609                    }
10610                    if (report.length() != 0) {
10611                        dbox.addText(dropboxTag, report);
10612                    }
10613                }
10614            }.start();
10615            return;
10616        }
10617
10618        // System app batching:
10619        if (!bufferWasEmpty) {
10620            // An existing dropbox-writing thread is outstanding, so
10621            // we don't need to start it up.  The existing thread will
10622            // catch the buffer appends we just did.
10623            return;
10624        }
10625
10626        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10627        // (After this point, we shouldn't access AMS internal data structures.)
10628        new Thread("Error dump: " + dropboxTag) {
10629            @Override
10630            public void run() {
10631                // 5 second sleep to let stacks arrive and be batched together
10632                try {
10633                    Thread.sleep(5000);  // 5 seconds
10634                } catch (InterruptedException e) {}
10635
10636                String errorReport;
10637                synchronized (mStrictModeBuffer) {
10638                    errorReport = mStrictModeBuffer.toString();
10639                    if (errorReport.length() == 0) {
10640                        return;
10641                    }
10642                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10643                    mStrictModeBuffer.trimToSize();
10644                }
10645                dbox.addText(dropboxTag, errorReport);
10646            }
10647        }.start();
10648    }
10649
10650    /**
10651     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10652     * @param app object of the crashing app, null for the system server
10653     * @param tag reported by the caller
10654     * @param crashInfo describing the context of the error
10655     * @return true if the process should exit immediately (WTF is fatal)
10656     */
10657    public boolean handleApplicationWtf(IBinder app, String tag,
10658            ApplicationErrorReport.CrashInfo crashInfo) {
10659        ProcessRecord r = findAppProcess(app, "WTF");
10660        final String processName = app == null ? "system_server"
10661                : (r == null ? "unknown" : r.processName);
10662
10663        EventLog.writeEvent(EventLogTags.AM_WTF,
10664                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10665                processName,
10666                r == null ? -1 : r.info.flags,
10667                tag, crashInfo.exceptionMessage);
10668
10669        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10670
10671        if (r != null && r.pid != Process.myPid() &&
10672                Settings.Global.getInt(mContext.getContentResolver(),
10673                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10674            crashApplication(r, crashInfo);
10675            return true;
10676        } else {
10677            return false;
10678        }
10679    }
10680
10681    /**
10682     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10683     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10684     */
10685    private ProcessRecord findAppProcess(IBinder app, String reason) {
10686        if (app == null) {
10687            return null;
10688        }
10689
10690        synchronized (this) {
10691            final int NP = mProcessNames.getMap().size();
10692            for (int ip=0; ip<NP; ip++) {
10693                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10694                final int NA = apps.size();
10695                for (int ia=0; ia<NA; ia++) {
10696                    ProcessRecord p = apps.valueAt(ia);
10697                    if (p.thread != null && p.thread.asBinder() == app) {
10698                        return p;
10699                    }
10700                }
10701            }
10702
10703            Slog.w(TAG, "Can't find mystery application for " + reason
10704                    + " from pid=" + Binder.getCallingPid()
10705                    + " uid=" + Binder.getCallingUid() + ": " + app);
10706            return null;
10707        }
10708    }
10709
10710    /**
10711     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10712     * to append various headers to the dropbox log text.
10713     */
10714    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10715            StringBuilder sb) {
10716        // Watchdog thread ends up invoking this function (with
10717        // a null ProcessRecord) to add the stack file to dropbox.
10718        // Do not acquire a lock on this (am) in such cases, as it
10719        // could cause a potential deadlock, if and when watchdog
10720        // is invoked due to unavailability of lock on am and it
10721        // would prevent watchdog from killing system_server.
10722        if (process == null) {
10723            sb.append("Process: ").append(processName).append("\n");
10724            return;
10725        }
10726        // Note: ProcessRecord 'process' is guarded by the service
10727        // instance.  (notably process.pkgList, which could otherwise change
10728        // concurrently during execution of this method)
10729        synchronized (this) {
10730            sb.append("Process: ").append(processName).append("\n");
10731            int flags = process.info.flags;
10732            IPackageManager pm = AppGlobals.getPackageManager();
10733            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10734            for (int ip=0; ip<process.pkgList.size(); ip++) {
10735                String pkg = process.pkgList.keyAt(ip);
10736                sb.append("Package: ").append(pkg);
10737                try {
10738                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10739                    if (pi != null) {
10740                        sb.append(" v").append(pi.versionCode);
10741                        if (pi.versionName != null) {
10742                            sb.append(" (").append(pi.versionName).append(")");
10743                        }
10744                    }
10745                } catch (RemoteException e) {
10746                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10747                }
10748                sb.append("\n");
10749            }
10750        }
10751    }
10752
10753    private static String processClass(ProcessRecord process) {
10754        if (process == null || process.pid == MY_PID) {
10755            return "system_server";
10756        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10757            return "system_app";
10758        } else {
10759            return "data_app";
10760        }
10761    }
10762
10763    /**
10764     * Write a description of an error (crash, WTF, ANR) to the drop box.
10765     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10766     * @param process which caused the error, null means the system server
10767     * @param activity which triggered the error, null if unknown
10768     * @param parent activity related to the error, null if unknown
10769     * @param subject line related to the error, null if absent
10770     * @param report in long form describing the error, null if absent
10771     * @param logFile to include in the report, null if none
10772     * @param crashInfo giving an application stack trace, null if absent
10773     */
10774    public void addErrorToDropBox(String eventType,
10775            ProcessRecord process, String processName, ActivityRecord activity,
10776            ActivityRecord parent, String subject,
10777            final String report, final File logFile,
10778            final ApplicationErrorReport.CrashInfo crashInfo) {
10779        // NOTE -- this must never acquire the ActivityManagerService lock,
10780        // otherwise the watchdog may be prevented from resetting the system.
10781
10782        final String dropboxTag = processClass(process) + "_" + eventType;
10783        final DropBoxManager dbox = (DropBoxManager)
10784                mContext.getSystemService(Context.DROPBOX_SERVICE);
10785
10786        // Exit early if the dropbox isn't configured to accept this report type.
10787        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10788
10789        final StringBuilder sb = new StringBuilder(1024);
10790        appendDropBoxProcessHeaders(process, processName, sb);
10791        if (activity != null) {
10792            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10793        }
10794        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10795            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10796        }
10797        if (parent != null && parent != activity) {
10798            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10799        }
10800        if (subject != null) {
10801            sb.append("Subject: ").append(subject).append("\n");
10802        }
10803        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10804        if (Debug.isDebuggerConnected()) {
10805            sb.append("Debugger: Connected\n");
10806        }
10807        sb.append("\n");
10808
10809        // Do the rest in a worker thread to avoid blocking the caller on I/O
10810        // (After this point, we shouldn't access AMS internal data structures.)
10811        Thread worker = new Thread("Error dump: " + dropboxTag) {
10812            @Override
10813            public void run() {
10814                if (report != null) {
10815                    sb.append(report);
10816                }
10817                if (logFile != null) {
10818                    try {
10819                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10820                                    "\n\n[[TRUNCATED]]"));
10821                    } catch (IOException e) {
10822                        Slog.e(TAG, "Error reading " + logFile, e);
10823                    }
10824                }
10825                if (crashInfo != null && crashInfo.stackTrace != null) {
10826                    sb.append(crashInfo.stackTrace);
10827                }
10828
10829                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10830                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10831                if (lines > 0) {
10832                    sb.append("\n");
10833
10834                    // Merge several logcat streams, and take the last N lines
10835                    InputStreamReader input = null;
10836                    try {
10837                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10838                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10839                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10840
10841                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10842                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10843                        input = new InputStreamReader(logcat.getInputStream());
10844
10845                        int num;
10846                        char[] buf = new char[8192];
10847                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10848                    } catch (IOException e) {
10849                        Slog.e(TAG, "Error running logcat", e);
10850                    } finally {
10851                        if (input != null) try { input.close(); } catch (IOException e) {}
10852                    }
10853                }
10854
10855                dbox.addText(dropboxTag, sb.toString());
10856            }
10857        };
10858
10859        if (process == null) {
10860            // If process is null, we are being called from some internal code
10861            // and may be about to die -- run this synchronously.
10862            worker.run();
10863        } else {
10864            worker.start();
10865        }
10866    }
10867
10868    /**
10869     * Bring up the "unexpected error" dialog box for a crashing app.
10870     * Deal with edge cases (intercepts from instrumented applications,
10871     * ActivityController, error intent receivers, that sort of thing).
10872     * @param r the application crashing
10873     * @param crashInfo describing the failure
10874     */
10875    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10876        long timeMillis = System.currentTimeMillis();
10877        String shortMsg = crashInfo.exceptionClassName;
10878        String longMsg = crashInfo.exceptionMessage;
10879        String stackTrace = crashInfo.stackTrace;
10880        if (shortMsg != null && longMsg != null) {
10881            longMsg = shortMsg + ": " + longMsg;
10882        } else if (shortMsg != null) {
10883            longMsg = shortMsg;
10884        }
10885
10886        AppErrorResult result = new AppErrorResult();
10887        synchronized (this) {
10888            if (mController != null) {
10889                try {
10890                    String name = r != null ? r.processName : null;
10891                    int pid = r != null ? r.pid : Binder.getCallingPid();
10892                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
10893                    if (!mController.appCrashed(name, pid,
10894                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10895                        Slog.w(TAG, "Force-killing crashed app " + name
10896                                + " at watcher's request");
10897                        Process.killProcess(pid);
10898                        if (r != null) {
10899                            Process.killProcessGroup(uid, pid);
10900                        }
10901                        return;
10902                    }
10903                } catch (RemoteException e) {
10904                    mController = null;
10905                    Watchdog.getInstance().setActivityController(null);
10906                }
10907            }
10908
10909            final long origId = Binder.clearCallingIdentity();
10910
10911            // If this process is running instrumentation, finish it.
10912            if (r != null && r.instrumentationClass != null) {
10913                Slog.w(TAG, "Error in app " + r.processName
10914                      + " running instrumentation " + r.instrumentationClass + ":");
10915                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10916                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10917                Bundle info = new Bundle();
10918                info.putString("shortMsg", shortMsg);
10919                info.putString("longMsg", longMsg);
10920                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10921                Binder.restoreCallingIdentity(origId);
10922                return;
10923            }
10924
10925            // If we can't identify the process or it's already exceeded its crash quota,
10926            // quit right away without showing a crash dialog.
10927            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10928                Binder.restoreCallingIdentity(origId);
10929                return;
10930            }
10931
10932            Message msg = Message.obtain();
10933            msg.what = SHOW_ERROR_MSG;
10934            HashMap data = new HashMap();
10935            data.put("result", result);
10936            data.put("app", r);
10937            msg.obj = data;
10938            mHandler.sendMessage(msg);
10939
10940            Binder.restoreCallingIdentity(origId);
10941        }
10942
10943        int res = result.get();
10944
10945        Intent appErrorIntent = null;
10946        synchronized (this) {
10947            if (r != null && !r.isolated) {
10948                // XXX Can't keep track of crash time for isolated processes,
10949                // since they don't have a persistent identity.
10950                mProcessCrashTimes.put(r.info.processName, r.uid,
10951                        SystemClock.uptimeMillis());
10952            }
10953            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10954                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10955            }
10956        }
10957
10958        if (appErrorIntent != null) {
10959            try {
10960                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10961            } catch (ActivityNotFoundException e) {
10962                Slog.w(TAG, "bug report receiver dissappeared", e);
10963            }
10964        }
10965    }
10966
10967    Intent createAppErrorIntentLocked(ProcessRecord r,
10968            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10969        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10970        if (report == null) {
10971            return null;
10972        }
10973        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10974        result.setComponent(r.errorReportReceiver);
10975        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10976        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10977        return result;
10978    }
10979
10980    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10981            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10982        if (r.errorReportReceiver == null) {
10983            return null;
10984        }
10985
10986        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10987            return null;
10988        }
10989
10990        ApplicationErrorReport report = new ApplicationErrorReport();
10991        report.packageName = r.info.packageName;
10992        report.installerPackageName = r.errorReportReceiver.getPackageName();
10993        report.processName = r.processName;
10994        report.time = timeMillis;
10995        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10996
10997        if (r.crashing || r.forceCrashReport) {
10998            report.type = ApplicationErrorReport.TYPE_CRASH;
10999            report.crashInfo = crashInfo;
11000        } else if (r.notResponding) {
11001            report.type = ApplicationErrorReport.TYPE_ANR;
11002            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11003
11004            report.anrInfo.activity = r.notRespondingReport.tag;
11005            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11006            report.anrInfo.info = r.notRespondingReport.longMsg;
11007        }
11008
11009        return report;
11010    }
11011
11012    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11013        enforceNotIsolatedCaller("getProcessesInErrorState");
11014        // assume our apps are happy - lazy create the list
11015        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11016
11017        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11018                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11019        int userId = UserHandle.getUserId(Binder.getCallingUid());
11020
11021        synchronized (this) {
11022
11023            // iterate across all processes
11024            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11025                ProcessRecord app = mLruProcesses.get(i);
11026                if (!allUsers && app.userId != userId) {
11027                    continue;
11028                }
11029                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11030                    // This one's in trouble, so we'll generate a report for it
11031                    // crashes are higher priority (in case there's a crash *and* an anr)
11032                    ActivityManager.ProcessErrorStateInfo report = null;
11033                    if (app.crashing) {
11034                        report = app.crashingReport;
11035                    } else if (app.notResponding) {
11036                        report = app.notRespondingReport;
11037                    }
11038
11039                    if (report != null) {
11040                        if (errList == null) {
11041                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11042                        }
11043                        errList.add(report);
11044                    } else {
11045                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11046                                " crashing = " + app.crashing +
11047                                " notResponding = " + app.notResponding);
11048                    }
11049                }
11050            }
11051        }
11052
11053        return errList;
11054    }
11055
11056    static int procStateToImportance(int procState, int memAdj,
11057            ActivityManager.RunningAppProcessInfo currApp) {
11058        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11059        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11060            currApp.lru = memAdj;
11061        } else {
11062            currApp.lru = 0;
11063        }
11064        return imp;
11065    }
11066
11067    private void fillInProcMemInfo(ProcessRecord app,
11068            ActivityManager.RunningAppProcessInfo outInfo) {
11069        outInfo.pid = app.pid;
11070        outInfo.uid = app.info.uid;
11071        if (mHeavyWeightProcess == app) {
11072            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11073        }
11074        if (app.persistent) {
11075            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11076        }
11077        if (app.activities.size() > 0) {
11078            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11079        }
11080        outInfo.lastTrimLevel = app.trimMemoryLevel;
11081        int adj = app.curAdj;
11082        int procState = app.curProcState;
11083        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11084        outInfo.importanceReasonCode = app.adjTypeCode;
11085        outInfo.processState = app.curProcState;
11086    }
11087
11088    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11089        enforceNotIsolatedCaller("getRunningAppProcesses");
11090        // Lazy instantiation of list
11091        List<ActivityManager.RunningAppProcessInfo> runList = null;
11092        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11093                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11094        int userId = UserHandle.getUserId(Binder.getCallingUid());
11095        synchronized (this) {
11096            // Iterate across all processes
11097            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11098                ProcessRecord app = mLruProcesses.get(i);
11099                if (!allUsers && app.userId != userId) {
11100                    continue;
11101                }
11102                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11103                    // Generate process state info for running application
11104                    ActivityManager.RunningAppProcessInfo currApp =
11105                        new ActivityManager.RunningAppProcessInfo(app.processName,
11106                                app.pid, app.getPackageList());
11107                    fillInProcMemInfo(app, currApp);
11108                    if (app.adjSource instanceof ProcessRecord) {
11109                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11110                        currApp.importanceReasonImportance =
11111                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11112                                        app.adjSourceProcState);
11113                    } else if (app.adjSource instanceof ActivityRecord) {
11114                        ActivityRecord r = (ActivityRecord)app.adjSource;
11115                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11116                    }
11117                    if (app.adjTarget instanceof ComponentName) {
11118                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11119                    }
11120                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11121                    //        + " lru=" + currApp.lru);
11122                    if (runList == null) {
11123                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11124                    }
11125                    runList.add(currApp);
11126                }
11127            }
11128        }
11129        return runList;
11130    }
11131
11132    public List<ApplicationInfo> getRunningExternalApplications() {
11133        enforceNotIsolatedCaller("getRunningExternalApplications");
11134        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11135        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11136        if (runningApps != null && runningApps.size() > 0) {
11137            Set<String> extList = new HashSet<String>();
11138            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11139                if (app.pkgList != null) {
11140                    for (String pkg : app.pkgList) {
11141                        extList.add(pkg);
11142                    }
11143                }
11144            }
11145            IPackageManager pm = AppGlobals.getPackageManager();
11146            for (String pkg : extList) {
11147                try {
11148                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11149                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11150                        retList.add(info);
11151                    }
11152                } catch (RemoteException e) {
11153                }
11154            }
11155        }
11156        return retList;
11157    }
11158
11159    @Override
11160    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11161        enforceNotIsolatedCaller("getMyMemoryState");
11162        synchronized (this) {
11163            ProcessRecord proc;
11164            synchronized (mPidsSelfLocked) {
11165                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11166            }
11167            fillInProcMemInfo(proc, outInfo);
11168        }
11169    }
11170
11171    @Override
11172    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11173        if (checkCallingPermission(android.Manifest.permission.DUMP)
11174                != PackageManager.PERMISSION_GRANTED) {
11175            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11176                    + Binder.getCallingPid()
11177                    + ", uid=" + Binder.getCallingUid()
11178                    + " without permission "
11179                    + android.Manifest.permission.DUMP);
11180            return;
11181        }
11182
11183        boolean dumpAll = false;
11184        boolean dumpClient = false;
11185        String dumpPackage = null;
11186
11187        int opti = 0;
11188        while (opti < args.length) {
11189            String opt = args[opti];
11190            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11191                break;
11192            }
11193            opti++;
11194            if ("-a".equals(opt)) {
11195                dumpAll = true;
11196            } else if ("-c".equals(opt)) {
11197                dumpClient = true;
11198            } else if ("-h".equals(opt)) {
11199                pw.println("Activity manager dump options:");
11200                pw.println("  [-a] [-c] [-h] [cmd] ...");
11201                pw.println("  cmd may be one of:");
11202                pw.println("    a[ctivities]: activity stack state");
11203                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11204                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11205                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11206                pw.println("    o[om]: out of memory management");
11207                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11208                pw.println("    provider [COMP_SPEC]: provider client-side state");
11209                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11210                pw.println("    service [COMP_SPEC]: service client-side state");
11211                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11212                pw.println("    all: dump all activities");
11213                pw.println("    top: dump the top activity");
11214                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11215                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11216                pw.println("    a partial substring in a component name, a");
11217                pw.println("    hex object identifier.");
11218                pw.println("  -a: include all available server state.");
11219                pw.println("  -c: include client state.");
11220                return;
11221            } else {
11222                pw.println("Unknown argument: " + opt + "; use -h for help");
11223            }
11224        }
11225
11226        long origId = Binder.clearCallingIdentity();
11227        boolean more = false;
11228        // Is the caller requesting to dump a particular piece of data?
11229        if (opti < args.length) {
11230            String cmd = args[opti];
11231            opti++;
11232            if ("activities".equals(cmd) || "a".equals(cmd)) {
11233                synchronized (this) {
11234                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11235                }
11236            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11237                String[] newArgs;
11238                String name;
11239                if (opti >= args.length) {
11240                    name = null;
11241                    newArgs = EMPTY_STRING_ARRAY;
11242                } else {
11243                    name = args[opti];
11244                    opti++;
11245                    newArgs = new String[args.length - opti];
11246                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11247                            args.length - opti);
11248                }
11249                synchronized (this) {
11250                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11251                }
11252            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11253                String[] newArgs;
11254                String name;
11255                if (opti >= args.length) {
11256                    name = null;
11257                    newArgs = EMPTY_STRING_ARRAY;
11258                } else {
11259                    name = args[opti];
11260                    opti++;
11261                    newArgs = new String[args.length - opti];
11262                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11263                            args.length - opti);
11264                }
11265                synchronized (this) {
11266                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11267                }
11268            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11269                String[] newArgs;
11270                String name;
11271                if (opti >= args.length) {
11272                    name = null;
11273                    newArgs = EMPTY_STRING_ARRAY;
11274                } else {
11275                    name = args[opti];
11276                    opti++;
11277                    newArgs = new String[args.length - opti];
11278                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11279                            args.length - opti);
11280                }
11281                synchronized (this) {
11282                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11283                }
11284            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11285                synchronized (this) {
11286                    dumpOomLocked(fd, pw, args, opti, true);
11287                }
11288            } else if ("provider".equals(cmd)) {
11289                String[] newArgs;
11290                String name;
11291                if (opti >= args.length) {
11292                    name = null;
11293                    newArgs = EMPTY_STRING_ARRAY;
11294                } else {
11295                    name = args[opti];
11296                    opti++;
11297                    newArgs = new String[args.length - opti];
11298                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11299                }
11300                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11301                    pw.println("No providers match: " + name);
11302                    pw.println("Use -h for help.");
11303                }
11304            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11305                synchronized (this) {
11306                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11307                }
11308            } else if ("service".equals(cmd)) {
11309                String[] newArgs;
11310                String name;
11311                if (opti >= args.length) {
11312                    name = null;
11313                    newArgs = EMPTY_STRING_ARRAY;
11314                } else {
11315                    name = args[opti];
11316                    opti++;
11317                    newArgs = new String[args.length - opti];
11318                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11319                            args.length - opti);
11320                }
11321                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11322                    pw.println("No services match: " + name);
11323                    pw.println("Use -h for help.");
11324                }
11325            } else if ("package".equals(cmd)) {
11326                String[] newArgs;
11327                if (opti >= args.length) {
11328                    pw.println("package: no package name specified");
11329                    pw.println("Use -h for help.");
11330                } else {
11331                    dumpPackage = args[opti];
11332                    opti++;
11333                    newArgs = new String[args.length - opti];
11334                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11335                            args.length - opti);
11336                    args = newArgs;
11337                    opti = 0;
11338                    more = true;
11339                }
11340            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11341                synchronized (this) {
11342                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11343                }
11344            } else {
11345                // Dumping a single activity?
11346                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11347                    pw.println("Bad activity command, or no activities match: " + cmd);
11348                    pw.println("Use -h for help.");
11349                }
11350            }
11351            if (!more) {
11352                Binder.restoreCallingIdentity(origId);
11353                return;
11354            }
11355        }
11356
11357        // No piece of data specified, dump everything.
11358        synchronized (this) {
11359            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11360            pw.println();
11361            if (dumpAll) {
11362                pw.println("-------------------------------------------------------------------------------");
11363            }
11364            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11365            pw.println();
11366            if (dumpAll) {
11367                pw.println("-------------------------------------------------------------------------------");
11368            }
11369            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11370            pw.println();
11371            if (dumpAll) {
11372                pw.println("-------------------------------------------------------------------------------");
11373            }
11374            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11375            pw.println();
11376            if (dumpAll) {
11377                pw.println("-------------------------------------------------------------------------------");
11378            }
11379            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11380            pw.println();
11381            if (dumpAll) {
11382                pw.println("-------------------------------------------------------------------------------");
11383            }
11384            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11385        }
11386        Binder.restoreCallingIdentity(origId);
11387    }
11388
11389    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11390            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11391        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11392
11393        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11394                dumpPackage);
11395        boolean needSep = printedAnything;
11396
11397        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11398                dumpPackage, needSep, "  mFocusedActivity: ");
11399        if (printed) {
11400            printedAnything = true;
11401            needSep = false;
11402        }
11403
11404        if (dumpPackage == null) {
11405            if (needSep) {
11406                pw.println();
11407            }
11408            needSep = true;
11409            printedAnything = true;
11410            mStackSupervisor.dump(pw, "  ");
11411        }
11412
11413        if (mRecentTasks.size() > 0) {
11414            boolean printedHeader = false;
11415
11416            final int N = mRecentTasks.size();
11417            for (int i=0; i<N; i++) {
11418                TaskRecord tr = mRecentTasks.get(i);
11419                if (dumpPackage != null) {
11420                    if (tr.realActivity == null ||
11421                            !dumpPackage.equals(tr.realActivity)) {
11422                        continue;
11423                    }
11424                }
11425                if (!printedHeader) {
11426                    if (needSep) {
11427                        pw.println();
11428                    }
11429                    pw.println("  Recent tasks:");
11430                    printedHeader = true;
11431                    printedAnything = true;
11432                }
11433                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11434                        pw.println(tr);
11435                if (dumpAll) {
11436                    mRecentTasks.get(i).dump(pw, "    ");
11437                }
11438            }
11439        }
11440
11441        if (!printedAnything) {
11442            pw.println("  (nothing)");
11443        }
11444    }
11445
11446    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11447            int opti, boolean dumpAll, String dumpPackage) {
11448        boolean needSep = false;
11449        boolean printedAnything = false;
11450        int numPers = 0;
11451
11452        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11453
11454        if (dumpAll) {
11455            final int NP = mProcessNames.getMap().size();
11456            for (int ip=0; ip<NP; ip++) {
11457                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11458                final int NA = procs.size();
11459                for (int ia=0; ia<NA; ia++) {
11460                    ProcessRecord r = procs.valueAt(ia);
11461                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11462                        continue;
11463                    }
11464                    if (!needSep) {
11465                        pw.println("  All known processes:");
11466                        needSep = true;
11467                        printedAnything = true;
11468                    }
11469                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11470                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11471                        pw.print(" "); pw.println(r);
11472                    r.dump(pw, "    ");
11473                    if (r.persistent) {
11474                        numPers++;
11475                    }
11476                }
11477            }
11478        }
11479
11480        if (mIsolatedProcesses.size() > 0) {
11481            boolean printed = false;
11482            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11483                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11484                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11485                    continue;
11486                }
11487                if (!printed) {
11488                    if (needSep) {
11489                        pw.println();
11490                    }
11491                    pw.println("  Isolated process list (sorted by uid):");
11492                    printedAnything = true;
11493                    printed = true;
11494                    needSep = true;
11495                }
11496                pw.println(String.format("%sIsolated #%2d: %s",
11497                        "    ", i, r.toString()));
11498            }
11499        }
11500
11501        if (mLruProcesses.size() > 0) {
11502            if (needSep) {
11503                pw.println();
11504            }
11505            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11506                    pw.print(" total, non-act at ");
11507                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11508                    pw.print(", non-svc at ");
11509                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11510                    pw.println("):");
11511            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11512            needSep = true;
11513            printedAnything = true;
11514        }
11515
11516        if (dumpAll || dumpPackage != null) {
11517            synchronized (mPidsSelfLocked) {
11518                boolean printed = false;
11519                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11520                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11521                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11522                        continue;
11523                    }
11524                    if (!printed) {
11525                        if (needSep) pw.println();
11526                        needSep = true;
11527                        pw.println("  PID mappings:");
11528                        printed = true;
11529                        printedAnything = true;
11530                    }
11531                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11532                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11533                }
11534            }
11535        }
11536
11537        if (mForegroundProcesses.size() > 0) {
11538            synchronized (mPidsSelfLocked) {
11539                boolean printed = false;
11540                for (int i=0; i<mForegroundProcesses.size(); i++) {
11541                    ProcessRecord r = mPidsSelfLocked.get(
11542                            mForegroundProcesses.valueAt(i).pid);
11543                    if (dumpPackage != null && (r == null
11544                            || !r.pkgList.containsKey(dumpPackage))) {
11545                        continue;
11546                    }
11547                    if (!printed) {
11548                        if (needSep) pw.println();
11549                        needSep = true;
11550                        pw.println("  Foreground Processes:");
11551                        printed = true;
11552                        printedAnything = true;
11553                    }
11554                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11555                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11556                }
11557            }
11558        }
11559
11560        if (mPersistentStartingProcesses.size() > 0) {
11561            if (needSep) pw.println();
11562            needSep = true;
11563            printedAnything = true;
11564            pw.println("  Persisent processes that are starting:");
11565            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11566                    "Starting Norm", "Restarting PERS", dumpPackage);
11567        }
11568
11569        if (mRemovedProcesses.size() > 0) {
11570            if (needSep) pw.println();
11571            needSep = true;
11572            printedAnything = true;
11573            pw.println("  Processes that are being removed:");
11574            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11575                    "Removed Norm", "Removed PERS", dumpPackage);
11576        }
11577
11578        if (mProcessesOnHold.size() > 0) {
11579            if (needSep) pw.println();
11580            needSep = true;
11581            printedAnything = true;
11582            pw.println("  Processes that are on old until the system is ready:");
11583            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11584                    "OnHold Norm", "OnHold PERS", dumpPackage);
11585        }
11586
11587        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11588
11589        if (mProcessCrashTimes.getMap().size() > 0) {
11590            boolean printed = false;
11591            long now = SystemClock.uptimeMillis();
11592            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11593            final int NP = pmap.size();
11594            for (int ip=0; ip<NP; ip++) {
11595                String pname = pmap.keyAt(ip);
11596                SparseArray<Long> uids = pmap.valueAt(ip);
11597                final int N = uids.size();
11598                for (int i=0; i<N; i++) {
11599                    int puid = uids.keyAt(i);
11600                    ProcessRecord r = mProcessNames.get(pname, puid);
11601                    if (dumpPackage != null && (r == null
11602                            || !r.pkgList.containsKey(dumpPackage))) {
11603                        continue;
11604                    }
11605                    if (!printed) {
11606                        if (needSep) pw.println();
11607                        needSep = true;
11608                        pw.println("  Time since processes crashed:");
11609                        printed = true;
11610                        printedAnything = true;
11611                    }
11612                    pw.print("    Process "); pw.print(pname);
11613                            pw.print(" uid "); pw.print(puid);
11614                            pw.print(": last crashed ");
11615                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11616                            pw.println(" ago");
11617                }
11618            }
11619        }
11620
11621        if (mBadProcesses.getMap().size() > 0) {
11622            boolean printed = false;
11623            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11624            final int NP = pmap.size();
11625            for (int ip=0; ip<NP; ip++) {
11626                String pname = pmap.keyAt(ip);
11627                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11628                final int N = uids.size();
11629                for (int i=0; i<N; i++) {
11630                    int puid = uids.keyAt(i);
11631                    ProcessRecord r = mProcessNames.get(pname, puid);
11632                    if (dumpPackage != null && (r == null
11633                            || !r.pkgList.containsKey(dumpPackage))) {
11634                        continue;
11635                    }
11636                    if (!printed) {
11637                        if (needSep) pw.println();
11638                        needSep = true;
11639                        pw.println("  Bad processes:");
11640                        printedAnything = true;
11641                    }
11642                    BadProcessInfo info = uids.valueAt(i);
11643                    pw.print("    Bad process "); pw.print(pname);
11644                            pw.print(" uid "); pw.print(puid);
11645                            pw.print(": crashed at time "); pw.println(info.time);
11646                    if (info.shortMsg != null) {
11647                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11648                    }
11649                    if (info.longMsg != null) {
11650                        pw.print("      Long msg: "); pw.println(info.longMsg);
11651                    }
11652                    if (info.stack != null) {
11653                        pw.println("      Stack:");
11654                        int lastPos = 0;
11655                        for (int pos=0; pos<info.stack.length(); pos++) {
11656                            if (info.stack.charAt(pos) == '\n') {
11657                                pw.print("        ");
11658                                pw.write(info.stack, lastPos, pos-lastPos);
11659                                pw.println();
11660                                lastPos = pos+1;
11661                            }
11662                        }
11663                        if (lastPos < info.stack.length()) {
11664                            pw.print("        ");
11665                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11666                            pw.println();
11667                        }
11668                    }
11669                }
11670            }
11671        }
11672
11673        if (dumpPackage == null) {
11674            pw.println();
11675            needSep = false;
11676            pw.println("  mStartedUsers:");
11677            for (int i=0; i<mStartedUsers.size(); i++) {
11678                UserStartedState uss = mStartedUsers.valueAt(i);
11679                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11680                        pw.print(": "); uss.dump("", pw);
11681            }
11682            pw.print("  mStartedUserArray: [");
11683            for (int i=0; i<mStartedUserArray.length; i++) {
11684                if (i > 0) pw.print(", ");
11685                pw.print(mStartedUserArray[i]);
11686            }
11687            pw.println("]");
11688            pw.print("  mUserLru: [");
11689            for (int i=0; i<mUserLru.size(); i++) {
11690                if (i > 0) pw.print(", ");
11691                pw.print(mUserLru.get(i));
11692            }
11693            pw.println("]");
11694            if (dumpAll) {
11695                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11696            }
11697            synchronized (mUserProfileGroupIdsSelfLocked) {
11698                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
11699                    pw.println("  mUserProfileGroupIds:");
11700                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
11701                        pw.print("    User #");
11702                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
11703                        pw.print(" -> profile #");
11704                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
11705                    }
11706                }
11707            }
11708        }
11709        if (mHomeProcess != null && (dumpPackage == null
11710                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11711            if (needSep) {
11712                pw.println();
11713                needSep = false;
11714            }
11715            pw.println("  mHomeProcess: " + mHomeProcess);
11716        }
11717        if (mPreviousProcess != null && (dumpPackage == null
11718                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11719            if (needSep) {
11720                pw.println();
11721                needSep = false;
11722            }
11723            pw.println("  mPreviousProcess: " + mPreviousProcess);
11724        }
11725        if (dumpAll) {
11726            StringBuilder sb = new StringBuilder(128);
11727            sb.append("  mPreviousProcessVisibleTime: ");
11728            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11729            pw.println(sb);
11730        }
11731        if (mHeavyWeightProcess != null && (dumpPackage == null
11732                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11733            if (needSep) {
11734                pw.println();
11735                needSep = false;
11736            }
11737            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11738        }
11739        if (dumpPackage == null) {
11740            pw.println("  mConfiguration: " + mConfiguration);
11741        }
11742        if (dumpAll) {
11743            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11744            if (mCompatModePackages.getPackages().size() > 0) {
11745                boolean printed = false;
11746                for (Map.Entry<String, Integer> entry
11747                        : mCompatModePackages.getPackages().entrySet()) {
11748                    String pkg = entry.getKey();
11749                    int mode = entry.getValue();
11750                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11751                        continue;
11752                    }
11753                    if (!printed) {
11754                        pw.println("  mScreenCompatPackages:");
11755                        printed = true;
11756                    }
11757                    pw.print("    "); pw.print(pkg); pw.print(": ");
11758                            pw.print(mode); pw.println();
11759                }
11760            }
11761        }
11762        if (dumpPackage == null) {
11763            if (mSleeping || mWentToSleep || mLockScreenShown) {
11764                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11765                        + " mLockScreenShown " + mLockScreenShown);
11766            }
11767            if (mShuttingDown || mRunningVoice) {
11768                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11769            }
11770        }
11771        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11772                || mOrigWaitForDebugger) {
11773            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11774                    || dumpPackage.equals(mOrigDebugApp)) {
11775                if (needSep) {
11776                    pw.println();
11777                    needSep = false;
11778                }
11779                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11780                        + " mDebugTransient=" + mDebugTransient
11781                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11782            }
11783        }
11784        if (mOpenGlTraceApp != null) {
11785            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11786                if (needSep) {
11787                    pw.println();
11788                    needSep = false;
11789                }
11790                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11791            }
11792        }
11793        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11794                || mProfileFd != null) {
11795            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11796                if (needSep) {
11797                    pw.println();
11798                    needSep = false;
11799                }
11800                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11801                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11802                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11803                        + mAutoStopProfiler);
11804            }
11805        }
11806        if (dumpPackage == null) {
11807            if (mAlwaysFinishActivities || mController != null) {
11808                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11809                        + " mController=" + mController);
11810            }
11811            if (dumpAll) {
11812                pw.println("  Total persistent processes: " + numPers);
11813                pw.println("  mProcessesReady=" + mProcessesReady
11814                        + " mSystemReady=" + mSystemReady);
11815                pw.println("  mBooting=" + mBooting
11816                        + " mBooted=" + mBooted
11817                        + " mFactoryTest=" + mFactoryTest);
11818                pw.print("  mLastPowerCheckRealtime=");
11819                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11820                        pw.println("");
11821                pw.print("  mLastPowerCheckUptime=");
11822                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11823                        pw.println("");
11824                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11825                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11826                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11827                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11828                        + " (" + mLruProcesses.size() + " total)"
11829                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11830                        + " mNumServiceProcs=" + mNumServiceProcs
11831                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11832                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11833                        + " mLastMemoryLevel" + mLastMemoryLevel
11834                        + " mLastNumProcesses" + mLastNumProcesses);
11835                long now = SystemClock.uptimeMillis();
11836                pw.print("  mLastIdleTime=");
11837                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11838                        pw.print(" mLowRamSinceLastIdle=");
11839                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11840                        pw.println();
11841            }
11842        }
11843
11844        if (!printedAnything) {
11845            pw.println("  (nothing)");
11846        }
11847    }
11848
11849    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11850            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11851        if (mProcessesToGc.size() > 0) {
11852            boolean printed = false;
11853            long now = SystemClock.uptimeMillis();
11854            for (int i=0; i<mProcessesToGc.size(); i++) {
11855                ProcessRecord proc = mProcessesToGc.get(i);
11856                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11857                    continue;
11858                }
11859                if (!printed) {
11860                    if (needSep) pw.println();
11861                    needSep = true;
11862                    pw.println("  Processes that are waiting to GC:");
11863                    printed = true;
11864                }
11865                pw.print("    Process "); pw.println(proc);
11866                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11867                        pw.print(", last gced=");
11868                        pw.print(now-proc.lastRequestedGc);
11869                        pw.print(" ms ago, last lowMem=");
11870                        pw.print(now-proc.lastLowMemory);
11871                        pw.println(" ms ago");
11872
11873            }
11874        }
11875        return needSep;
11876    }
11877
11878    void printOomLevel(PrintWriter pw, String name, int adj) {
11879        pw.print("    ");
11880        if (adj >= 0) {
11881            pw.print(' ');
11882            if (adj < 10) pw.print(' ');
11883        } else {
11884            if (adj > -10) pw.print(' ');
11885        }
11886        pw.print(adj);
11887        pw.print(": ");
11888        pw.print(name);
11889        pw.print(" (");
11890        pw.print(mProcessList.getMemLevel(adj)/1024);
11891        pw.println(" kB)");
11892    }
11893
11894    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11895            int opti, boolean dumpAll) {
11896        boolean needSep = false;
11897
11898        if (mLruProcesses.size() > 0) {
11899            if (needSep) pw.println();
11900            needSep = true;
11901            pw.println("  OOM levels:");
11902            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11903            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11904            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11905            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11906            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11907            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11908            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11909            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11910            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11911            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11912            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11913            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11914            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11915
11916            if (needSep) pw.println();
11917            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11918                    pw.print(" total, non-act at ");
11919                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11920                    pw.print(", non-svc at ");
11921                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11922                    pw.println("):");
11923            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11924            needSep = true;
11925        }
11926
11927        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11928
11929        pw.println();
11930        pw.println("  mHomeProcess: " + mHomeProcess);
11931        pw.println("  mPreviousProcess: " + mPreviousProcess);
11932        if (mHeavyWeightProcess != null) {
11933            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11934        }
11935
11936        return true;
11937    }
11938
11939    /**
11940     * There are three ways to call this:
11941     *  - no provider specified: dump all the providers
11942     *  - a flattened component name that matched an existing provider was specified as the
11943     *    first arg: dump that one provider
11944     *  - the first arg isn't the flattened component name of an existing provider:
11945     *    dump all providers whose component contains the first arg as a substring
11946     */
11947    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11948            int opti, boolean dumpAll) {
11949        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11950    }
11951
11952    static class ItemMatcher {
11953        ArrayList<ComponentName> components;
11954        ArrayList<String> strings;
11955        ArrayList<Integer> objects;
11956        boolean all;
11957
11958        ItemMatcher() {
11959            all = true;
11960        }
11961
11962        void build(String name) {
11963            ComponentName componentName = ComponentName.unflattenFromString(name);
11964            if (componentName != null) {
11965                if (components == null) {
11966                    components = new ArrayList<ComponentName>();
11967                }
11968                components.add(componentName);
11969                all = false;
11970            } else {
11971                int objectId = 0;
11972                // Not a '/' separated full component name; maybe an object ID?
11973                try {
11974                    objectId = Integer.parseInt(name, 16);
11975                    if (objects == null) {
11976                        objects = new ArrayList<Integer>();
11977                    }
11978                    objects.add(objectId);
11979                    all = false;
11980                } catch (RuntimeException e) {
11981                    // Not an integer; just do string match.
11982                    if (strings == null) {
11983                        strings = new ArrayList<String>();
11984                    }
11985                    strings.add(name);
11986                    all = false;
11987                }
11988            }
11989        }
11990
11991        int build(String[] args, int opti) {
11992            for (; opti<args.length; opti++) {
11993                String name = args[opti];
11994                if ("--".equals(name)) {
11995                    return opti+1;
11996                }
11997                build(name);
11998            }
11999            return opti;
12000        }
12001
12002        boolean match(Object object, ComponentName comp) {
12003            if (all) {
12004                return true;
12005            }
12006            if (components != null) {
12007                for (int i=0; i<components.size(); i++) {
12008                    if (components.get(i).equals(comp)) {
12009                        return true;
12010                    }
12011                }
12012            }
12013            if (objects != null) {
12014                for (int i=0; i<objects.size(); i++) {
12015                    if (System.identityHashCode(object) == objects.get(i)) {
12016                        return true;
12017                    }
12018                }
12019            }
12020            if (strings != null) {
12021                String flat = comp.flattenToString();
12022                for (int i=0; i<strings.size(); i++) {
12023                    if (flat.contains(strings.get(i))) {
12024                        return true;
12025                    }
12026                }
12027            }
12028            return false;
12029        }
12030    }
12031
12032    /**
12033     * There are three things that cmd can be:
12034     *  - a flattened component name that matches an existing activity
12035     *  - the cmd arg isn't the flattened component name of an existing activity:
12036     *    dump all activity whose component contains the cmd as a substring
12037     *  - A hex number of the ActivityRecord object instance.
12038     */
12039    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12040            int opti, boolean dumpAll) {
12041        ArrayList<ActivityRecord> activities;
12042
12043        synchronized (this) {
12044            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12045        }
12046
12047        if (activities.size() <= 0) {
12048            return false;
12049        }
12050
12051        String[] newArgs = new String[args.length - opti];
12052        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12053
12054        TaskRecord lastTask = null;
12055        boolean needSep = false;
12056        for (int i=activities.size()-1; i>=0; i--) {
12057            ActivityRecord r = activities.get(i);
12058            if (needSep) {
12059                pw.println();
12060            }
12061            needSep = true;
12062            synchronized (this) {
12063                if (lastTask != r.task) {
12064                    lastTask = r.task;
12065                    pw.print("TASK "); pw.print(lastTask.affinity);
12066                            pw.print(" id="); pw.println(lastTask.taskId);
12067                    if (dumpAll) {
12068                        lastTask.dump(pw, "  ");
12069                    }
12070                }
12071            }
12072            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12073        }
12074        return true;
12075    }
12076
12077    /**
12078     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12079     * there is a thread associated with the activity.
12080     */
12081    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12082            final ActivityRecord r, String[] args, boolean dumpAll) {
12083        String innerPrefix = prefix + "  ";
12084        synchronized (this) {
12085            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12086                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12087                    pw.print(" pid=");
12088                    if (r.app != null) pw.println(r.app.pid);
12089                    else pw.println("(not running)");
12090            if (dumpAll) {
12091                r.dump(pw, innerPrefix);
12092            }
12093        }
12094        if (r.app != null && r.app.thread != null) {
12095            // flush anything that is already in the PrintWriter since the thread is going
12096            // to write to the file descriptor directly
12097            pw.flush();
12098            try {
12099                TransferPipe tp = new TransferPipe();
12100                try {
12101                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12102                            r.appToken, innerPrefix, args);
12103                    tp.go(fd);
12104                } finally {
12105                    tp.kill();
12106                }
12107            } catch (IOException e) {
12108                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12109            } catch (RemoteException e) {
12110                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12111            }
12112        }
12113    }
12114
12115    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12116            int opti, boolean dumpAll, String dumpPackage) {
12117        boolean needSep = false;
12118        boolean onlyHistory = false;
12119        boolean printedAnything = false;
12120
12121        if ("history".equals(dumpPackage)) {
12122            if (opti < args.length && "-s".equals(args[opti])) {
12123                dumpAll = false;
12124            }
12125            onlyHistory = true;
12126            dumpPackage = null;
12127        }
12128
12129        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12130        if (!onlyHistory && dumpAll) {
12131            if (mRegisteredReceivers.size() > 0) {
12132                boolean printed = false;
12133                Iterator it = mRegisteredReceivers.values().iterator();
12134                while (it.hasNext()) {
12135                    ReceiverList r = (ReceiverList)it.next();
12136                    if (dumpPackage != null && (r.app == null ||
12137                            !dumpPackage.equals(r.app.info.packageName))) {
12138                        continue;
12139                    }
12140                    if (!printed) {
12141                        pw.println("  Registered Receivers:");
12142                        needSep = true;
12143                        printed = true;
12144                        printedAnything = true;
12145                    }
12146                    pw.print("  * "); pw.println(r);
12147                    r.dump(pw, "    ");
12148                }
12149            }
12150
12151            if (mReceiverResolver.dump(pw, needSep ?
12152                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12153                    "    ", dumpPackage, false)) {
12154                needSep = true;
12155                printedAnything = true;
12156            }
12157        }
12158
12159        for (BroadcastQueue q : mBroadcastQueues) {
12160            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12161            printedAnything |= needSep;
12162        }
12163
12164        needSep = true;
12165
12166        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12167            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12168                if (needSep) {
12169                    pw.println();
12170                }
12171                needSep = true;
12172                printedAnything = true;
12173                pw.print("  Sticky broadcasts for user ");
12174                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12175                StringBuilder sb = new StringBuilder(128);
12176                for (Map.Entry<String, ArrayList<Intent>> ent
12177                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12178                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12179                    if (dumpAll) {
12180                        pw.println(":");
12181                        ArrayList<Intent> intents = ent.getValue();
12182                        final int N = intents.size();
12183                        for (int i=0; i<N; i++) {
12184                            sb.setLength(0);
12185                            sb.append("    Intent: ");
12186                            intents.get(i).toShortString(sb, false, true, false, false);
12187                            pw.println(sb.toString());
12188                            Bundle bundle = intents.get(i).getExtras();
12189                            if (bundle != null) {
12190                                pw.print("      ");
12191                                pw.println(bundle.toString());
12192                            }
12193                        }
12194                    } else {
12195                        pw.println("");
12196                    }
12197                }
12198            }
12199        }
12200
12201        if (!onlyHistory && dumpAll) {
12202            pw.println();
12203            for (BroadcastQueue queue : mBroadcastQueues) {
12204                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12205                        + queue.mBroadcastsScheduled);
12206            }
12207            pw.println("  mHandler:");
12208            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12209            needSep = true;
12210            printedAnything = true;
12211        }
12212
12213        if (!printedAnything) {
12214            pw.println("  (nothing)");
12215        }
12216    }
12217
12218    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12219            int opti, boolean dumpAll, String dumpPackage) {
12220        boolean needSep;
12221        boolean printedAnything = false;
12222
12223        ItemMatcher matcher = new ItemMatcher();
12224        matcher.build(args, opti);
12225
12226        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12227
12228        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12229        printedAnything |= needSep;
12230
12231        if (mLaunchingProviders.size() > 0) {
12232            boolean printed = false;
12233            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12234                ContentProviderRecord r = mLaunchingProviders.get(i);
12235                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12236                    continue;
12237                }
12238                if (!printed) {
12239                    if (needSep) pw.println();
12240                    needSep = true;
12241                    pw.println("  Launching content providers:");
12242                    printed = true;
12243                    printedAnything = true;
12244                }
12245                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12246                        pw.println(r);
12247            }
12248        }
12249
12250        if (mGrantedUriPermissions.size() > 0) {
12251            boolean printed = false;
12252            int dumpUid = -2;
12253            if (dumpPackage != null) {
12254                try {
12255                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12256                } catch (NameNotFoundException e) {
12257                    dumpUid = -1;
12258                }
12259            }
12260            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12261                int uid = mGrantedUriPermissions.keyAt(i);
12262                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12263                    continue;
12264                }
12265                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12266                if (!printed) {
12267                    if (needSep) pw.println();
12268                    needSep = true;
12269                    pw.println("  Granted Uri Permissions:");
12270                    printed = true;
12271                    printedAnything = true;
12272                }
12273                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12274                for (UriPermission perm : perms.values()) {
12275                    pw.print("    "); pw.println(perm);
12276                    if (dumpAll) {
12277                        perm.dump(pw, "      ");
12278                    }
12279                }
12280            }
12281        }
12282
12283        if (!printedAnything) {
12284            pw.println("  (nothing)");
12285        }
12286    }
12287
12288    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12289            int opti, boolean dumpAll, String dumpPackage) {
12290        boolean printed = false;
12291
12292        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12293
12294        if (mIntentSenderRecords.size() > 0) {
12295            Iterator<WeakReference<PendingIntentRecord>> it
12296                    = mIntentSenderRecords.values().iterator();
12297            while (it.hasNext()) {
12298                WeakReference<PendingIntentRecord> ref = it.next();
12299                PendingIntentRecord rec = ref != null ? ref.get(): null;
12300                if (dumpPackage != null && (rec == null
12301                        || !dumpPackage.equals(rec.key.packageName))) {
12302                    continue;
12303                }
12304                printed = true;
12305                if (rec != null) {
12306                    pw.print("  * "); pw.println(rec);
12307                    if (dumpAll) {
12308                        rec.dump(pw, "    ");
12309                    }
12310                } else {
12311                    pw.print("  * "); pw.println(ref);
12312                }
12313            }
12314        }
12315
12316        if (!printed) {
12317            pw.println("  (nothing)");
12318        }
12319    }
12320
12321    private static final int dumpProcessList(PrintWriter pw,
12322            ActivityManagerService service, List list,
12323            String prefix, String normalLabel, String persistentLabel,
12324            String dumpPackage) {
12325        int numPers = 0;
12326        final int N = list.size()-1;
12327        for (int i=N; i>=0; i--) {
12328            ProcessRecord r = (ProcessRecord)list.get(i);
12329            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12330                continue;
12331            }
12332            pw.println(String.format("%s%s #%2d: %s",
12333                    prefix, (r.persistent ? persistentLabel : normalLabel),
12334                    i, r.toString()));
12335            if (r.persistent) {
12336                numPers++;
12337            }
12338        }
12339        return numPers;
12340    }
12341
12342    private static final boolean dumpProcessOomList(PrintWriter pw,
12343            ActivityManagerService service, List<ProcessRecord> origList,
12344            String prefix, String normalLabel, String persistentLabel,
12345            boolean inclDetails, String dumpPackage) {
12346
12347        ArrayList<Pair<ProcessRecord, Integer>> list
12348                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12349        for (int i=0; i<origList.size(); i++) {
12350            ProcessRecord r = origList.get(i);
12351            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12352                continue;
12353            }
12354            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12355        }
12356
12357        if (list.size() <= 0) {
12358            return false;
12359        }
12360
12361        Comparator<Pair<ProcessRecord, Integer>> comparator
12362                = new Comparator<Pair<ProcessRecord, Integer>>() {
12363            @Override
12364            public int compare(Pair<ProcessRecord, Integer> object1,
12365                    Pair<ProcessRecord, Integer> object2) {
12366                if (object1.first.setAdj != object2.first.setAdj) {
12367                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12368                }
12369                if (object1.second.intValue() != object2.second.intValue()) {
12370                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12371                }
12372                return 0;
12373            }
12374        };
12375
12376        Collections.sort(list, comparator);
12377
12378        final long curRealtime = SystemClock.elapsedRealtime();
12379        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12380        final long curUptime = SystemClock.uptimeMillis();
12381        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12382
12383        for (int i=list.size()-1; i>=0; i--) {
12384            ProcessRecord r = list.get(i).first;
12385            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12386            char schedGroup;
12387            switch (r.setSchedGroup) {
12388                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12389                    schedGroup = 'B';
12390                    break;
12391                case Process.THREAD_GROUP_DEFAULT:
12392                    schedGroup = 'F';
12393                    break;
12394                default:
12395                    schedGroup = '?';
12396                    break;
12397            }
12398            char foreground;
12399            if (r.foregroundActivities) {
12400                foreground = 'A';
12401            } else if (r.foregroundServices) {
12402                foreground = 'S';
12403            } else {
12404                foreground = ' ';
12405            }
12406            String procState = ProcessList.makeProcStateString(r.curProcState);
12407            pw.print(prefix);
12408            pw.print(r.persistent ? persistentLabel : normalLabel);
12409            pw.print(" #");
12410            int num = (origList.size()-1)-list.get(i).second;
12411            if (num < 10) pw.print(' ');
12412            pw.print(num);
12413            pw.print(": ");
12414            pw.print(oomAdj);
12415            pw.print(' ');
12416            pw.print(schedGroup);
12417            pw.print('/');
12418            pw.print(foreground);
12419            pw.print('/');
12420            pw.print(procState);
12421            pw.print(" trm:");
12422            if (r.trimMemoryLevel < 10) pw.print(' ');
12423            pw.print(r.trimMemoryLevel);
12424            pw.print(' ');
12425            pw.print(r.toShortString());
12426            pw.print(" (");
12427            pw.print(r.adjType);
12428            pw.println(')');
12429            if (r.adjSource != null || r.adjTarget != null) {
12430                pw.print(prefix);
12431                pw.print("    ");
12432                if (r.adjTarget instanceof ComponentName) {
12433                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12434                } else if (r.adjTarget != null) {
12435                    pw.print(r.adjTarget.toString());
12436                } else {
12437                    pw.print("{null}");
12438                }
12439                pw.print("<=");
12440                if (r.adjSource instanceof ProcessRecord) {
12441                    pw.print("Proc{");
12442                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12443                    pw.println("}");
12444                } else if (r.adjSource != null) {
12445                    pw.println(r.adjSource.toString());
12446                } else {
12447                    pw.println("{null}");
12448                }
12449            }
12450            if (inclDetails) {
12451                pw.print(prefix);
12452                pw.print("    ");
12453                pw.print("oom: max="); pw.print(r.maxAdj);
12454                pw.print(" curRaw="); pw.print(r.curRawAdj);
12455                pw.print(" setRaw="); pw.print(r.setRawAdj);
12456                pw.print(" cur="); pw.print(r.curAdj);
12457                pw.print(" set="); pw.println(r.setAdj);
12458                pw.print(prefix);
12459                pw.print("    ");
12460                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12461                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12462                pw.print(" lastPss="); pw.print(r.lastPss);
12463                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12464                pw.print(prefix);
12465                pw.print("    ");
12466                pw.print("cached="); pw.print(r.cached);
12467                pw.print(" empty="); pw.print(r.empty);
12468                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12469
12470                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
12471                    if (r.lastWakeTime != 0) {
12472                        long wtime;
12473                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12474                        synchronized (stats) {
12475                            wtime = stats.getProcessWakeTime(r.info.uid,
12476                                    r.pid, curRealtime);
12477                        }
12478                        long timeUsed = wtime - r.lastWakeTime;
12479                        pw.print(prefix);
12480                        pw.print("    ");
12481                        pw.print("keep awake over ");
12482                        TimeUtils.formatDuration(realtimeSince, pw);
12483                        pw.print(" used ");
12484                        TimeUtils.formatDuration(timeUsed, pw);
12485                        pw.print(" (");
12486                        pw.print((timeUsed*100)/realtimeSince);
12487                        pw.println("%)");
12488                    }
12489                    if (r.lastCpuTime != 0) {
12490                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12491                        pw.print(prefix);
12492                        pw.print("    ");
12493                        pw.print("run cpu over ");
12494                        TimeUtils.formatDuration(uptimeSince, pw);
12495                        pw.print(" used ");
12496                        TimeUtils.formatDuration(timeUsed, pw);
12497                        pw.print(" (");
12498                        pw.print((timeUsed*100)/uptimeSince);
12499                        pw.println("%)");
12500                    }
12501                }
12502            }
12503        }
12504        return true;
12505    }
12506
12507    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12508        ArrayList<ProcessRecord> procs;
12509        synchronized (this) {
12510            if (args != null && args.length > start
12511                    && args[start].charAt(0) != '-') {
12512                procs = new ArrayList<ProcessRecord>();
12513                int pid = -1;
12514                try {
12515                    pid = Integer.parseInt(args[start]);
12516                } catch (NumberFormatException e) {
12517                }
12518                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12519                    ProcessRecord proc = mLruProcesses.get(i);
12520                    if (proc.pid == pid) {
12521                        procs.add(proc);
12522                    } else if (proc.processName.equals(args[start])) {
12523                        procs.add(proc);
12524                    }
12525                }
12526                if (procs.size() <= 0) {
12527                    return null;
12528                }
12529            } else {
12530                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12531            }
12532        }
12533        return procs;
12534    }
12535
12536    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12537            PrintWriter pw, String[] args) {
12538        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12539        if (procs == null) {
12540            pw.println("No process found for: " + args[0]);
12541            return;
12542        }
12543
12544        long uptime = SystemClock.uptimeMillis();
12545        long realtime = SystemClock.elapsedRealtime();
12546        pw.println("Applications Graphics Acceleration Info:");
12547        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12548
12549        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12550            ProcessRecord r = procs.get(i);
12551            if (r.thread != null) {
12552                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12553                pw.flush();
12554                try {
12555                    TransferPipe tp = new TransferPipe();
12556                    try {
12557                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12558                        tp.go(fd);
12559                    } finally {
12560                        tp.kill();
12561                    }
12562                } catch (IOException e) {
12563                    pw.println("Failure while dumping the app: " + r);
12564                    pw.flush();
12565                } catch (RemoteException e) {
12566                    pw.println("Got a RemoteException while dumping the app " + r);
12567                    pw.flush();
12568                }
12569            }
12570        }
12571    }
12572
12573    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12574        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12575        if (procs == null) {
12576            pw.println("No process found for: " + args[0]);
12577            return;
12578        }
12579
12580        pw.println("Applications Database Info:");
12581
12582        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12583            ProcessRecord r = procs.get(i);
12584            if (r.thread != null) {
12585                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12586                pw.flush();
12587                try {
12588                    TransferPipe tp = new TransferPipe();
12589                    try {
12590                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12591                        tp.go(fd);
12592                    } finally {
12593                        tp.kill();
12594                    }
12595                } catch (IOException e) {
12596                    pw.println("Failure while dumping the app: " + r);
12597                    pw.flush();
12598                } catch (RemoteException e) {
12599                    pw.println("Got a RemoteException while dumping the app " + r);
12600                    pw.flush();
12601                }
12602            }
12603        }
12604    }
12605
12606    final static class MemItem {
12607        final boolean isProc;
12608        final String label;
12609        final String shortLabel;
12610        final long pss;
12611        final int id;
12612        final boolean hasActivities;
12613        ArrayList<MemItem> subitems;
12614
12615        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12616                boolean _hasActivities) {
12617            isProc = true;
12618            label = _label;
12619            shortLabel = _shortLabel;
12620            pss = _pss;
12621            id = _id;
12622            hasActivities = _hasActivities;
12623        }
12624
12625        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12626            isProc = false;
12627            label = _label;
12628            shortLabel = _shortLabel;
12629            pss = _pss;
12630            id = _id;
12631            hasActivities = false;
12632        }
12633    }
12634
12635    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12636            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12637        if (sort && !isCompact) {
12638            Collections.sort(items, new Comparator<MemItem>() {
12639                @Override
12640                public int compare(MemItem lhs, MemItem rhs) {
12641                    if (lhs.pss < rhs.pss) {
12642                        return 1;
12643                    } else if (lhs.pss > rhs.pss) {
12644                        return -1;
12645                    }
12646                    return 0;
12647                }
12648            });
12649        }
12650
12651        for (int i=0; i<items.size(); i++) {
12652            MemItem mi = items.get(i);
12653            if (!isCompact) {
12654                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12655            } else if (mi.isProc) {
12656                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12657                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12658                pw.println(mi.hasActivities ? ",a" : ",e");
12659            } else {
12660                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12661                pw.println(mi.pss);
12662            }
12663            if (mi.subitems != null) {
12664                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12665                        true, isCompact);
12666            }
12667        }
12668    }
12669
12670    // These are in KB.
12671    static final long[] DUMP_MEM_BUCKETS = new long[] {
12672        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12673        120*1024, 160*1024, 200*1024,
12674        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12675        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12676    };
12677
12678    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12679            boolean stackLike) {
12680        int start = label.lastIndexOf('.');
12681        if (start >= 0) start++;
12682        else start = 0;
12683        int end = label.length();
12684        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12685            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12686                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12687                out.append(bucket);
12688                out.append(stackLike ? "MB." : "MB ");
12689                out.append(label, start, end);
12690                return;
12691            }
12692        }
12693        out.append(memKB/1024);
12694        out.append(stackLike ? "MB." : "MB ");
12695        out.append(label, start, end);
12696    }
12697
12698    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12699            ProcessList.NATIVE_ADJ,
12700            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12701            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12702            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12703            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12704            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12705    };
12706    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12707            "Native",
12708            "System", "Persistent", "Foreground",
12709            "Visible", "Perceptible",
12710            "Heavy Weight", "Backup",
12711            "A Services", "Home",
12712            "Previous", "B Services", "Cached"
12713    };
12714    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12715            "native",
12716            "sys", "pers", "fore",
12717            "vis", "percept",
12718            "heavy", "backup",
12719            "servicea", "home",
12720            "prev", "serviceb", "cached"
12721    };
12722
12723    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12724            long realtime, boolean isCheckinRequest, boolean isCompact) {
12725        if (isCheckinRequest || isCompact) {
12726            // short checkin version
12727            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12728        } else {
12729            pw.println("Applications Memory Usage (kB):");
12730            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12731        }
12732    }
12733
12734    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12735            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12736        boolean dumpDetails = false;
12737        boolean dumpFullDetails = false;
12738        boolean dumpDalvik = false;
12739        boolean oomOnly = false;
12740        boolean isCompact = false;
12741        boolean localOnly = false;
12742
12743        int opti = 0;
12744        while (opti < args.length) {
12745            String opt = args[opti];
12746            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12747                break;
12748            }
12749            opti++;
12750            if ("-a".equals(opt)) {
12751                dumpDetails = true;
12752                dumpFullDetails = true;
12753                dumpDalvik = true;
12754            } else if ("-d".equals(opt)) {
12755                dumpDalvik = true;
12756            } else if ("-c".equals(opt)) {
12757                isCompact = true;
12758            } else if ("--oom".equals(opt)) {
12759                oomOnly = true;
12760            } else if ("--local".equals(opt)) {
12761                localOnly = true;
12762            } else if ("-h".equals(opt)) {
12763                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12764                pw.println("  -a: include all available information for each process.");
12765                pw.println("  -d: include dalvik details when dumping process details.");
12766                pw.println("  -c: dump in a compact machine-parseable representation.");
12767                pw.println("  --oom: only show processes organized by oom adj.");
12768                pw.println("  --local: only collect details locally, don't call process.");
12769                pw.println("If [process] is specified it can be the name or ");
12770                pw.println("pid of a specific process to dump.");
12771                return;
12772            } else {
12773                pw.println("Unknown argument: " + opt + "; use -h for help");
12774            }
12775        }
12776
12777        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12778        long uptime = SystemClock.uptimeMillis();
12779        long realtime = SystemClock.elapsedRealtime();
12780        final long[] tmpLong = new long[1];
12781
12782        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12783        if (procs == null) {
12784            // No Java processes.  Maybe they want to print a native process.
12785            if (args != null && args.length > opti
12786                    && args[opti].charAt(0) != '-') {
12787                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12788                        = new ArrayList<ProcessCpuTracker.Stats>();
12789                updateCpuStatsNow();
12790                int findPid = -1;
12791                try {
12792                    findPid = Integer.parseInt(args[opti]);
12793                } catch (NumberFormatException e) {
12794                }
12795                synchronized (mProcessCpuThread) {
12796                    final int N = mProcessCpuTracker.countStats();
12797                    for (int i=0; i<N; i++) {
12798                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12799                        if (st.pid == findPid || (st.baseName != null
12800                                && st.baseName.equals(args[opti]))) {
12801                            nativeProcs.add(st);
12802                        }
12803                    }
12804                }
12805                if (nativeProcs.size() > 0) {
12806                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12807                            isCompact);
12808                    Debug.MemoryInfo mi = null;
12809                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12810                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12811                        final int pid = r.pid;
12812                        if (!isCheckinRequest && dumpDetails) {
12813                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12814                        }
12815                        if (mi == null) {
12816                            mi = new Debug.MemoryInfo();
12817                        }
12818                        if (dumpDetails || (!brief && !oomOnly)) {
12819                            Debug.getMemoryInfo(pid, mi);
12820                        } else {
12821                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12822                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12823                        }
12824                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12825                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12826                        if (isCheckinRequest) {
12827                            pw.println();
12828                        }
12829                    }
12830                    return;
12831                }
12832            }
12833            pw.println("No process found for: " + args[opti]);
12834            return;
12835        }
12836
12837        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12838            dumpDetails = true;
12839        }
12840
12841        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12842
12843        String[] innerArgs = new String[args.length-opti];
12844        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12845
12846        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12847        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12848        long nativePss=0, dalvikPss=0, otherPss=0;
12849        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12850
12851        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12852        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12853                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12854
12855        long totalPss = 0;
12856        long cachedPss = 0;
12857
12858        Debug.MemoryInfo mi = null;
12859        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12860            final ProcessRecord r = procs.get(i);
12861            final IApplicationThread thread;
12862            final int pid;
12863            final int oomAdj;
12864            final boolean hasActivities;
12865            synchronized (this) {
12866                thread = r.thread;
12867                pid = r.pid;
12868                oomAdj = r.getSetAdjWithServices();
12869                hasActivities = r.activities.size() > 0;
12870            }
12871            if (thread != null) {
12872                if (!isCheckinRequest && dumpDetails) {
12873                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12874                }
12875                if (mi == null) {
12876                    mi = new Debug.MemoryInfo();
12877                }
12878                if (dumpDetails || (!brief && !oomOnly)) {
12879                    Debug.getMemoryInfo(pid, mi);
12880                } else {
12881                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12882                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12883                }
12884                if (dumpDetails) {
12885                    if (localOnly) {
12886                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12887                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12888                        if (isCheckinRequest) {
12889                            pw.println();
12890                        }
12891                    } else {
12892                        try {
12893                            pw.flush();
12894                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12895                                    dumpDalvik, innerArgs);
12896                        } catch (RemoteException e) {
12897                            if (!isCheckinRequest) {
12898                                pw.println("Got RemoteException!");
12899                                pw.flush();
12900                            }
12901                        }
12902                    }
12903                }
12904
12905                final long myTotalPss = mi.getTotalPss();
12906                final long myTotalUss = mi.getTotalUss();
12907
12908                synchronized (this) {
12909                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12910                        // Record this for posterity if the process has been stable.
12911                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12912                    }
12913                }
12914
12915                if (!isCheckinRequest && mi != null) {
12916                    totalPss += myTotalPss;
12917                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12918                            (hasActivities ? " / activities)" : ")"),
12919                            r.processName, myTotalPss, pid, hasActivities);
12920                    procMems.add(pssItem);
12921                    procMemsMap.put(pid, pssItem);
12922
12923                    nativePss += mi.nativePss;
12924                    dalvikPss += mi.dalvikPss;
12925                    otherPss += mi.otherPss;
12926                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12927                        long mem = mi.getOtherPss(j);
12928                        miscPss[j] += mem;
12929                        otherPss -= mem;
12930                    }
12931
12932                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12933                        cachedPss += myTotalPss;
12934                    }
12935
12936                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12937                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12938                                || oomIndex == (oomPss.length-1)) {
12939                            oomPss[oomIndex] += myTotalPss;
12940                            if (oomProcs[oomIndex] == null) {
12941                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12942                            }
12943                            oomProcs[oomIndex].add(pssItem);
12944                            break;
12945                        }
12946                    }
12947                }
12948            }
12949        }
12950
12951        long nativeProcTotalPss = 0;
12952
12953        if (!isCheckinRequest && procs.size() > 1) {
12954            // If we are showing aggregations, also look for native processes to
12955            // include so that our aggregations are more accurate.
12956            updateCpuStatsNow();
12957            synchronized (mProcessCpuThread) {
12958                final int N = mProcessCpuTracker.countStats();
12959                for (int i=0; i<N; i++) {
12960                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12961                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12962                        if (mi == null) {
12963                            mi = new Debug.MemoryInfo();
12964                        }
12965                        if (!brief && !oomOnly) {
12966                            Debug.getMemoryInfo(st.pid, mi);
12967                        } else {
12968                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12969                            mi.nativePrivateDirty = (int)tmpLong[0];
12970                        }
12971
12972                        final long myTotalPss = mi.getTotalPss();
12973                        totalPss += myTotalPss;
12974                        nativeProcTotalPss += myTotalPss;
12975
12976                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12977                                st.name, myTotalPss, st.pid, false);
12978                        procMems.add(pssItem);
12979
12980                        nativePss += mi.nativePss;
12981                        dalvikPss += mi.dalvikPss;
12982                        otherPss += mi.otherPss;
12983                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12984                            long mem = mi.getOtherPss(j);
12985                            miscPss[j] += mem;
12986                            otherPss -= mem;
12987                        }
12988                        oomPss[0] += myTotalPss;
12989                        if (oomProcs[0] == null) {
12990                            oomProcs[0] = new ArrayList<MemItem>();
12991                        }
12992                        oomProcs[0].add(pssItem);
12993                    }
12994                }
12995            }
12996
12997            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12998
12999            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13000            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13001            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13002            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13003                String label = Debug.MemoryInfo.getOtherLabel(j);
13004                catMems.add(new MemItem(label, label, miscPss[j], j));
13005            }
13006
13007            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13008            for (int j=0; j<oomPss.length; j++) {
13009                if (oomPss[j] != 0) {
13010                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13011                            : DUMP_MEM_OOM_LABEL[j];
13012                    MemItem item = new MemItem(label, label, oomPss[j],
13013                            DUMP_MEM_OOM_ADJ[j]);
13014                    item.subitems = oomProcs[j];
13015                    oomMems.add(item);
13016                }
13017            }
13018
13019            if (!brief && !oomOnly && !isCompact) {
13020                pw.println();
13021                pw.println("Total PSS by process:");
13022                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13023                pw.println();
13024            }
13025            if (!isCompact) {
13026                pw.println("Total PSS by OOM adjustment:");
13027            }
13028            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13029            if (!brief && !oomOnly) {
13030                PrintWriter out = categoryPw != null ? categoryPw : pw;
13031                if (!isCompact) {
13032                    out.println();
13033                    out.println("Total PSS by category:");
13034                }
13035                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13036            }
13037            if (!isCompact) {
13038                pw.println();
13039            }
13040            MemInfoReader memInfo = new MemInfoReader();
13041            memInfo.readMemInfo();
13042            if (nativeProcTotalPss > 0) {
13043                synchronized (this) {
13044                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13045                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13046                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13047                            nativeProcTotalPss);
13048                }
13049            }
13050            if (!brief) {
13051                if (!isCompact) {
13052                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13053                    pw.print(" kB (status ");
13054                    switch (mLastMemoryLevel) {
13055                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13056                            pw.println("normal)");
13057                            break;
13058                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13059                            pw.println("moderate)");
13060                            break;
13061                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13062                            pw.println("low)");
13063                            break;
13064                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13065                            pw.println("critical)");
13066                            break;
13067                        default:
13068                            pw.print(mLastMemoryLevel);
13069                            pw.println(")");
13070                            break;
13071                    }
13072                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13073                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13074                            pw.print(cachedPss); pw.print(" cached pss + ");
13075                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13076                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13077                } else {
13078                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13079                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13080                            + memInfo.getFreeSizeKb()); pw.print(",");
13081                    pw.println(totalPss - cachedPss);
13082                }
13083            }
13084            if (!isCompact) {
13085                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13086                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13087                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13088                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13089                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13090                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13091                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13092                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13093                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13094                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13095                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13096            }
13097            if (!brief) {
13098                if (memInfo.getZramTotalSizeKb() != 0) {
13099                    if (!isCompact) {
13100                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13101                                pw.print(" kB physical used for ");
13102                                pw.print(memInfo.getSwapTotalSizeKb()
13103                                        - memInfo.getSwapFreeSizeKb());
13104                                pw.print(" kB in swap (");
13105                                pw.print(memInfo.getSwapTotalSizeKb());
13106                                pw.println(" kB total swap)");
13107                    } else {
13108                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13109                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13110                                pw.println(memInfo.getSwapFreeSizeKb());
13111                    }
13112                }
13113                final int[] SINGLE_LONG_FORMAT = new int[] {
13114                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13115                };
13116                long[] longOut = new long[1];
13117                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13118                        SINGLE_LONG_FORMAT, null, longOut, null);
13119                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13120                longOut[0] = 0;
13121                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13122                        SINGLE_LONG_FORMAT, null, longOut, null);
13123                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13124                longOut[0] = 0;
13125                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13126                        SINGLE_LONG_FORMAT, null, longOut, null);
13127                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13128                longOut[0] = 0;
13129                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13130                        SINGLE_LONG_FORMAT, null, longOut, null);
13131                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13132                if (!isCompact) {
13133                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13134                        pw.print("      KSM: "); pw.print(sharing);
13135                                pw.print(" kB saved from shared ");
13136                                pw.print(shared); pw.println(" kB");
13137                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13138                                pw.print(voltile); pw.println(" kB volatile");
13139                    }
13140                    pw.print("   Tuning: ");
13141                    pw.print(ActivityManager.staticGetMemoryClass());
13142                    pw.print(" (large ");
13143                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13144                    pw.print("), oom ");
13145                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13146                    pw.print(" kB");
13147                    pw.print(", restore limit ");
13148                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13149                    pw.print(" kB");
13150                    if (ActivityManager.isLowRamDeviceStatic()) {
13151                        pw.print(" (low-ram)");
13152                    }
13153                    if (ActivityManager.isHighEndGfx()) {
13154                        pw.print(" (high-end-gfx)");
13155                    }
13156                    pw.println();
13157                } else {
13158                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13159                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13160                    pw.println(voltile);
13161                    pw.print("tuning,");
13162                    pw.print(ActivityManager.staticGetMemoryClass());
13163                    pw.print(',');
13164                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13165                    pw.print(',');
13166                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13167                    if (ActivityManager.isLowRamDeviceStatic()) {
13168                        pw.print(",low-ram");
13169                    }
13170                    if (ActivityManager.isHighEndGfx()) {
13171                        pw.print(",high-end-gfx");
13172                    }
13173                    pw.println();
13174                }
13175            }
13176        }
13177    }
13178
13179    /**
13180     * Searches array of arguments for the specified string
13181     * @param args array of argument strings
13182     * @param value value to search for
13183     * @return true if the value is contained in the array
13184     */
13185    private static boolean scanArgs(String[] args, String value) {
13186        if (args != null) {
13187            for (String arg : args) {
13188                if (value.equals(arg)) {
13189                    return true;
13190                }
13191            }
13192        }
13193        return false;
13194    }
13195
13196    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13197            ContentProviderRecord cpr, boolean always) {
13198        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13199
13200        if (!inLaunching || always) {
13201            synchronized (cpr) {
13202                cpr.launchingApp = null;
13203                cpr.notifyAll();
13204            }
13205            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13206            String names[] = cpr.info.authority.split(";");
13207            for (int j = 0; j < names.length; j++) {
13208                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13209            }
13210        }
13211
13212        for (int i=0; i<cpr.connections.size(); i++) {
13213            ContentProviderConnection conn = cpr.connections.get(i);
13214            if (conn.waiting) {
13215                // If this connection is waiting for the provider, then we don't
13216                // need to mess with its process unless we are always removing
13217                // or for some reason the provider is not currently launching.
13218                if (inLaunching && !always) {
13219                    continue;
13220                }
13221            }
13222            ProcessRecord capp = conn.client;
13223            conn.dead = true;
13224            if (conn.stableCount > 0) {
13225                if (!capp.persistent && capp.thread != null
13226                        && capp.pid != 0
13227                        && capp.pid != MY_PID) {
13228                    killUnneededProcessLocked(capp, "depends on provider "
13229                            + cpr.name.flattenToShortString()
13230                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13231                }
13232            } else if (capp.thread != null && conn.provider.provider != null) {
13233                try {
13234                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13235                } catch (RemoteException e) {
13236                }
13237                // In the protocol here, we don't expect the client to correctly
13238                // clean up this connection, we'll just remove it.
13239                cpr.connections.remove(i);
13240                conn.client.conProviders.remove(conn);
13241            }
13242        }
13243
13244        if (inLaunching && always) {
13245            mLaunchingProviders.remove(cpr);
13246        }
13247        return inLaunching;
13248    }
13249
13250    /**
13251     * Main code for cleaning up a process when it has gone away.  This is
13252     * called both as a result of the process dying, or directly when stopping
13253     * a process when running in single process mode.
13254     */
13255    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13256            boolean restarting, boolean allowRestart, int index) {
13257        if (index >= 0) {
13258            removeLruProcessLocked(app);
13259            ProcessList.remove(app.pid);
13260        }
13261
13262        mProcessesToGc.remove(app);
13263        mPendingPssProcesses.remove(app);
13264
13265        // Dismiss any open dialogs.
13266        if (app.crashDialog != null && !app.forceCrashReport) {
13267            app.crashDialog.dismiss();
13268            app.crashDialog = null;
13269        }
13270        if (app.anrDialog != null) {
13271            app.anrDialog.dismiss();
13272            app.anrDialog = null;
13273        }
13274        if (app.waitDialog != null) {
13275            app.waitDialog.dismiss();
13276            app.waitDialog = null;
13277        }
13278
13279        app.crashing = false;
13280        app.notResponding = false;
13281
13282        app.resetPackageList(mProcessStats);
13283        app.unlinkDeathRecipient();
13284        app.makeInactive(mProcessStats);
13285        app.waitingToKill = null;
13286        app.forcingToForeground = null;
13287        updateProcessForegroundLocked(app, false, false);
13288        app.foregroundActivities = false;
13289        app.hasShownUi = false;
13290        app.treatLikeActivity = false;
13291        app.hasAboveClient = false;
13292        app.hasClientActivities = false;
13293
13294        mServices.killServicesLocked(app, allowRestart);
13295
13296        boolean restart = false;
13297
13298        // Remove published content providers.
13299        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13300            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13301            final boolean always = app.bad || !allowRestart;
13302            if (removeDyingProviderLocked(app, cpr, always) || always) {
13303                // We left the provider in the launching list, need to
13304                // restart it.
13305                restart = true;
13306            }
13307
13308            cpr.provider = null;
13309            cpr.proc = null;
13310        }
13311        app.pubProviders.clear();
13312
13313        // Take care of any launching providers waiting for this process.
13314        if (checkAppInLaunchingProvidersLocked(app, false)) {
13315            restart = true;
13316        }
13317
13318        // Unregister from connected content providers.
13319        if (!app.conProviders.isEmpty()) {
13320            for (int i=0; i<app.conProviders.size(); i++) {
13321                ContentProviderConnection conn = app.conProviders.get(i);
13322                conn.provider.connections.remove(conn);
13323            }
13324            app.conProviders.clear();
13325        }
13326
13327        // At this point there may be remaining entries in mLaunchingProviders
13328        // where we were the only one waiting, so they are no longer of use.
13329        // Look for these and clean up if found.
13330        // XXX Commented out for now.  Trying to figure out a way to reproduce
13331        // the actual situation to identify what is actually going on.
13332        if (false) {
13333            for (int i=0; i<mLaunchingProviders.size(); i++) {
13334                ContentProviderRecord cpr = (ContentProviderRecord)
13335                        mLaunchingProviders.get(i);
13336                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13337                    synchronized (cpr) {
13338                        cpr.launchingApp = null;
13339                        cpr.notifyAll();
13340                    }
13341                }
13342            }
13343        }
13344
13345        skipCurrentReceiverLocked(app);
13346
13347        // Unregister any receivers.
13348        for (int i=app.receivers.size()-1; i>=0; i--) {
13349            removeReceiverLocked(app.receivers.valueAt(i));
13350        }
13351        app.receivers.clear();
13352
13353        // If the app is undergoing backup, tell the backup manager about it
13354        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13355            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13356                    + mBackupTarget.appInfo + " died during backup");
13357            try {
13358                IBackupManager bm = IBackupManager.Stub.asInterface(
13359                        ServiceManager.getService(Context.BACKUP_SERVICE));
13360                bm.agentDisconnected(app.info.packageName);
13361            } catch (RemoteException e) {
13362                // can't happen; backup manager is local
13363            }
13364        }
13365
13366        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13367            ProcessChangeItem item = mPendingProcessChanges.get(i);
13368            if (item.pid == app.pid) {
13369                mPendingProcessChanges.remove(i);
13370                mAvailProcessChanges.add(item);
13371            }
13372        }
13373        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13374
13375        // If the caller is restarting this app, then leave it in its
13376        // current lists and let the caller take care of it.
13377        if (restarting) {
13378            return;
13379        }
13380
13381        if (!app.persistent || app.isolated) {
13382            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13383                    "Removing non-persistent process during cleanup: " + app);
13384            mProcessNames.remove(app.processName, app.uid);
13385            mIsolatedProcesses.remove(app.uid);
13386            if (mHeavyWeightProcess == app) {
13387                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13388                        mHeavyWeightProcess.userId, 0));
13389                mHeavyWeightProcess = null;
13390            }
13391        } else if (!app.removed) {
13392            // This app is persistent, so we need to keep its record around.
13393            // If it is not already on the pending app list, add it there
13394            // and start a new process for it.
13395            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13396                mPersistentStartingProcesses.add(app);
13397                restart = true;
13398            }
13399        }
13400        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13401                "Clean-up removing on hold: " + app);
13402        mProcessesOnHold.remove(app);
13403
13404        if (app == mHomeProcess) {
13405            mHomeProcess = null;
13406        }
13407        if (app == mPreviousProcess) {
13408            mPreviousProcess = null;
13409        }
13410
13411        if (restart && !app.isolated) {
13412            // We have components that still need to be running in the
13413            // process, so re-launch it.
13414            mProcessNames.put(app.processName, app.uid, app);
13415            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13416        } else if (app.pid > 0 && app.pid != MY_PID) {
13417            // Goodbye!
13418            boolean removed;
13419            synchronized (mPidsSelfLocked) {
13420                mPidsSelfLocked.remove(app.pid);
13421                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13422            }
13423            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
13424            if (app.isolated) {
13425                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13426            }
13427            app.setPid(0);
13428        }
13429    }
13430
13431    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13432        // Look through the content providers we are waiting to have launched,
13433        // and if any run in this process then either schedule a restart of
13434        // the process or kill the client waiting for it if this process has
13435        // gone bad.
13436        int NL = mLaunchingProviders.size();
13437        boolean restart = false;
13438        for (int i=0; i<NL; i++) {
13439            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13440            if (cpr.launchingApp == app) {
13441                if (!alwaysBad && !app.bad) {
13442                    restart = true;
13443                } else {
13444                    removeDyingProviderLocked(app, cpr, true);
13445                    // cpr should have been removed from mLaunchingProviders
13446                    NL = mLaunchingProviders.size();
13447                    i--;
13448                }
13449            }
13450        }
13451        return restart;
13452    }
13453
13454    // =========================================================
13455    // SERVICES
13456    // =========================================================
13457
13458    @Override
13459    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13460            int flags) {
13461        enforceNotIsolatedCaller("getServices");
13462        synchronized (this) {
13463            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13464        }
13465    }
13466
13467    @Override
13468    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13469        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13470        synchronized (this) {
13471            return mServices.getRunningServiceControlPanelLocked(name);
13472        }
13473    }
13474
13475    @Override
13476    public ComponentName startService(IApplicationThread caller, Intent service,
13477            String resolvedType, int userId) {
13478        enforceNotIsolatedCaller("startService");
13479        // Refuse possible leaked file descriptors
13480        if (service != null && service.hasFileDescriptors() == true) {
13481            throw new IllegalArgumentException("File descriptors passed in Intent");
13482        }
13483
13484        if (DEBUG_SERVICE)
13485            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13486        synchronized(this) {
13487            final int callingPid = Binder.getCallingPid();
13488            final int callingUid = Binder.getCallingUid();
13489            final long origId = Binder.clearCallingIdentity();
13490            ComponentName res = mServices.startServiceLocked(caller, service,
13491                    resolvedType, callingPid, callingUid, userId);
13492            Binder.restoreCallingIdentity(origId);
13493            return res;
13494        }
13495    }
13496
13497    ComponentName startServiceInPackage(int uid,
13498            Intent service, String resolvedType, int userId) {
13499        synchronized(this) {
13500            if (DEBUG_SERVICE)
13501                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13502            final long origId = Binder.clearCallingIdentity();
13503            ComponentName res = mServices.startServiceLocked(null, service,
13504                    resolvedType, -1, uid, userId);
13505            Binder.restoreCallingIdentity(origId);
13506            return res;
13507        }
13508    }
13509
13510    @Override
13511    public int stopService(IApplicationThread caller, Intent service,
13512            String resolvedType, int userId) {
13513        enforceNotIsolatedCaller("stopService");
13514        // Refuse possible leaked file descriptors
13515        if (service != null && service.hasFileDescriptors() == true) {
13516            throw new IllegalArgumentException("File descriptors passed in Intent");
13517        }
13518
13519        synchronized(this) {
13520            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13521        }
13522    }
13523
13524    @Override
13525    public IBinder peekService(Intent service, String resolvedType) {
13526        enforceNotIsolatedCaller("peekService");
13527        // Refuse possible leaked file descriptors
13528        if (service != null && service.hasFileDescriptors() == true) {
13529            throw new IllegalArgumentException("File descriptors passed in Intent");
13530        }
13531        synchronized(this) {
13532            return mServices.peekServiceLocked(service, resolvedType);
13533        }
13534    }
13535
13536    @Override
13537    public boolean stopServiceToken(ComponentName className, IBinder token,
13538            int startId) {
13539        synchronized(this) {
13540            return mServices.stopServiceTokenLocked(className, token, startId);
13541        }
13542    }
13543
13544    @Override
13545    public void setServiceForeground(ComponentName className, IBinder token,
13546            int id, Notification notification, boolean removeNotification) {
13547        synchronized(this) {
13548            mServices.setServiceForegroundLocked(className, token, id, notification,
13549                    removeNotification);
13550        }
13551    }
13552
13553    @Override
13554    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13555            boolean requireFull, String name, String callerPackage) {
13556        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
13557                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
13558    }
13559
13560    int unsafeConvertIncomingUser(int userId) {
13561        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
13562                ? mCurrentUserId : userId;
13563    }
13564
13565    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13566            int allowMode, String name, String callerPackage) {
13567        final int callingUserId = UserHandle.getUserId(callingUid);
13568        if (callingUserId == userId) {
13569            return userId;
13570        }
13571
13572        // Note that we may be accessing mCurrentUserId outside of a lock...
13573        // shouldn't be a big deal, if this is being called outside
13574        // of a locked context there is intrinsically a race with
13575        // the value the caller will receive and someone else changing it.
13576        // We assume that USER_CURRENT_OR_SELF will use the current user; later
13577        // we will switch to the calling user if access to the current user fails.
13578        int targetUserId = unsafeConvertIncomingUser(userId);
13579
13580        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13581            final boolean allow;
13582            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
13583                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
13584                // If the caller has this permission, they always pass go.  And collect $200.
13585                allow = true;
13586            } else if (allowMode == ALLOW_FULL_ONLY) {
13587                // We require full access, sucks to be you.
13588                allow = false;
13589            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
13590                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
13591                // If the caller does not have either permission, they are always doomed.
13592                allow = false;
13593            } else if (allowMode == ALLOW_NON_FULL) {
13594                // We are blanket allowing non-full access, you lucky caller!
13595                allow = true;
13596            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
13597                // We may or may not allow this depending on whether the two users are
13598                // in the same profile.
13599                synchronized (mUserProfileGroupIdsSelfLocked) {
13600                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
13601                            UserInfo.NO_PROFILE_GROUP_ID);
13602                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
13603                            UserInfo.NO_PROFILE_GROUP_ID);
13604                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
13605                            && callingProfile == targetProfile;
13606                }
13607            } else {
13608                throw new IllegalArgumentException("Unknown mode: " + allowMode);
13609            }
13610            if (!allow) {
13611                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13612                    // In this case, they would like to just execute as their
13613                    // owner user instead of failing.
13614                    targetUserId = callingUserId;
13615                } else {
13616                    StringBuilder builder = new StringBuilder(128);
13617                    builder.append("Permission Denial: ");
13618                    builder.append(name);
13619                    if (callerPackage != null) {
13620                        builder.append(" from ");
13621                        builder.append(callerPackage);
13622                    }
13623                    builder.append(" asks to run as user ");
13624                    builder.append(userId);
13625                    builder.append(" but is calling from user ");
13626                    builder.append(UserHandle.getUserId(callingUid));
13627                    builder.append("; this requires ");
13628                    builder.append(INTERACT_ACROSS_USERS_FULL);
13629                    if (allowMode != ALLOW_FULL_ONLY) {
13630                        builder.append(" or ");
13631                        builder.append(INTERACT_ACROSS_USERS);
13632                    }
13633                    String msg = builder.toString();
13634                    Slog.w(TAG, msg);
13635                    throw new SecurityException(msg);
13636                }
13637            }
13638        }
13639        if (!allowAll && targetUserId < 0) {
13640            throw new IllegalArgumentException(
13641                    "Call does not support special user #" + targetUserId);
13642        }
13643        return targetUserId;
13644    }
13645
13646    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13647            String className, int flags) {
13648        boolean result = false;
13649        // For apps that don't have pre-defined UIDs, check for permission
13650        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13651            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13652                if (ActivityManager.checkUidPermission(
13653                        INTERACT_ACROSS_USERS,
13654                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13655                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13656                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13657                            + " requests FLAG_SINGLE_USER, but app does not hold "
13658                            + INTERACT_ACROSS_USERS;
13659                    Slog.w(TAG, msg);
13660                    throw new SecurityException(msg);
13661                }
13662                // Permission passed
13663                result = true;
13664            }
13665        } else if ("system".equals(componentProcessName)) {
13666            result = true;
13667        } else {
13668            // App with pre-defined UID, check if it's a persistent app
13669            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13670        }
13671        if (DEBUG_MU) {
13672            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13673                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13674        }
13675        return result;
13676    }
13677
13678    /**
13679     * Checks to see if the caller is in the same app as the singleton
13680     * component, or the component is in a special app. It allows special apps
13681     * to export singleton components but prevents exporting singleton
13682     * components for regular apps.
13683     */
13684    boolean isValidSingletonCall(int callingUid, int componentUid) {
13685        int componentAppId = UserHandle.getAppId(componentUid);
13686        return UserHandle.isSameApp(callingUid, componentUid)
13687                || componentAppId == Process.SYSTEM_UID
13688                || componentAppId == Process.PHONE_UID
13689                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13690                        == PackageManager.PERMISSION_GRANTED;
13691    }
13692
13693    public int bindService(IApplicationThread caller, IBinder token,
13694            Intent service, String resolvedType,
13695            IServiceConnection connection, int flags, int userId) {
13696        enforceNotIsolatedCaller("bindService");
13697        // Refuse possible leaked file descriptors
13698        if (service != null && service.hasFileDescriptors() == true) {
13699            throw new IllegalArgumentException("File descriptors passed in Intent");
13700        }
13701
13702        synchronized(this) {
13703            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13704                    connection, flags, userId);
13705        }
13706    }
13707
13708    public boolean unbindService(IServiceConnection connection) {
13709        synchronized (this) {
13710            return mServices.unbindServiceLocked(connection);
13711        }
13712    }
13713
13714    public void publishService(IBinder token, Intent intent, IBinder service) {
13715        // Refuse possible leaked file descriptors
13716        if (intent != null && intent.hasFileDescriptors() == true) {
13717            throw new IllegalArgumentException("File descriptors passed in Intent");
13718        }
13719
13720        synchronized(this) {
13721            if (!(token instanceof ServiceRecord)) {
13722                throw new IllegalArgumentException("Invalid service token");
13723            }
13724            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13725        }
13726    }
13727
13728    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13729        // Refuse possible leaked file descriptors
13730        if (intent != null && intent.hasFileDescriptors() == true) {
13731            throw new IllegalArgumentException("File descriptors passed in Intent");
13732        }
13733
13734        synchronized(this) {
13735            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13736        }
13737    }
13738
13739    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13740        synchronized(this) {
13741            if (!(token instanceof ServiceRecord)) {
13742                throw new IllegalArgumentException("Invalid service token");
13743            }
13744            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13745        }
13746    }
13747
13748    // =========================================================
13749    // BACKUP AND RESTORE
13750    // =========================================================
13751
13752    // Cause the target app to be launched if necessary and its backup agent
13753    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13754    // activity manager to announce its creation.
13755    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13756        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13757        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
13758
13759        synchronized(this) {
13760            // !!! TODO: currently no check here that we're already bound
13761            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13762            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13763            synchronized (stats) {
13764                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13765            }
13766
13767            // Backup agent is now in use, its package can't be stopped.
13768            try {
13769                AppGlobals.getPackageManager().setPackageStoppedState(
13770                        app.packageName, false, UserHandle.getUserId(app.uid));
13771            } catch (RemoteException e) {
13772            } catch (IllegalArgumentException e) {
13773                Slog.w(TAG, "Failed trying to unstop package "
13774                        + app.packageName + ": " + e);
13775            }
13776
13777            BackupRecord r = new BackupRecord(ss, app, backupMode);
13778            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13779                    ? new ComponentName(app.packageName, app.backupAgentName)
13780                    : new ComponentName("android", "FullBackupAgent");
13781            // startProcessLocked() returns existing proc's record if it's already running
13782            ProcessRecord proc = startProcessLocked(app.processName, app,
13783                    false, 0, "backup", hostingName, false, false, false);
13784            if (proc == null) {
13785                Slog.e(TAG, "Unable to start backup agent process " + r);
13786                return false;
13787            }
13788
13789            r.app = proc;
13790            mBackupTarget = r;
13791            mBackupAppName = app.packageName;
13792
13793            // Try not to kill the process during backup
13794            updateOomAdjLocked(proc);
13795
13796            // If the process is already attached, schedule the creation of the backup agent now.
13797            // If it is not yet live, this will be done when it attaches to the framework.
13798            if (proc.thread != null) {
13799                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13800                try {
13801                    proc.thread.scheduleCreateBackupAgent(app,
13802                            compatibilityInfoForPackageLocked(app), backupMode);
13803                } catch (RemoteException e) {
13804                    // Will time out on the backup manager side
13805                }
13806            } else {
13807                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13808            }
13809            // Invariants: at this point, the target app process exists and the application
13810            // is either already running or in the process of coming up.  mBackupTarget and
13811            // mBackupAppName describe the app, so that when it binds back to the AM we
13812            // know that it's scheduled for a backup-agent operation.
13813        }
13814
13815        return true;
13816    }
13817
13818    @Override
13819    public void clearPendingBackup() {
13820        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13821        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13822
13823        synchronized (this) {
13824            mBackupTarget = null;
13825            mBackupAppName = null;
13826        }
13827    }
13828
13829    // A backup agent has just come up
13830    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13831        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13832                + " = " + agent);
13833
13834        synchronized(this) {
13835            if (!agentPackageName.equals(mBackupAppName)) {
13836                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13837                return;
13838            }
13839        }
13840
13841        long oldIdent = Binder.clearCallingIdentity();
13842        try {
13843            IBackupManager bm = IBackupManager.Stub.asInterface(
13844                    ServiceManager.getService(Context.BACKUP_SERVICE));
13845            bm.agentConnected(agentPackageName, agent);
13846        } catch (RemoteException e) {
13847            // can't happen; the backup manager service is local
13848        } catch (Exception e) {
13849            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13850            e.printStackTrace();
13851        } finally {
13852            Binder.restoreCallingIdentity(oldIdent);
13853        }
13854    }
13855
13856    // done with this agent
13857    public void unbindBackupAgent(ApplicationInfo appInfo) {
13858        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13859        if (appInfo == null) {
13860            Slog.w(TAG, "unbind backup agent for null app");
13861            return;
13862        }
13863
13864        synchronized(this) {
13865            try {
13866                if (mBackupAppName == null) {
13867                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13868                    return;
13869                }
13870
13871                if (!mBackupAppName.equals(appInfo.packageName)) {
13872                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13873                    return;
13874                }
13875
13876                // Not backing this app up any more; reset its OOM adjustment
13877                final ProcessRecord proc = mBackupTarget.app;
13878                updateOomAdjLocked(proc);
13879
13880                // If the app crashed during backup, 'thread' will be null here
13881                if (proc.thread != null) {
13882                    try {
13883                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13884                                compatibilityInfoForPackageLocked(appInfo));
13885                    } catch (Exception e) {
13886                        Slog.e(TAG, "Exception when unbinding backup agent:");
13887                        e.printStackTrace();
13888                    }
13889                }
13890            } finally {
13891                mBackupTarget = null;
13892                mBackupAppName = null;
13893            }
13894        }
13895    }
13896    // =========================================================
13897    // BROADCASTS
13898    // =========================================================
13899
13900    private final List getStickiesLocked(String action, IntentFilter filter,
13901            List cur, int userId) {
13902        final ContentResolver resolver = mContext.getContentResolver();
13903        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13904        if (stickies == null) {
13905            return cur;
13906        }
13907        final ArrayList<Intent> list = stickies.get(action);
13908        if (list == null) {
13909            return cur;
13910        }
13911        int N = list.size();
13912        for (int i=0; i<N; i++) {
13913            Intent intent = list.get(i);
13914            if (filter.match(resolver, intent, true, TAG) >= 0) {
13915                if (cur == null) {
13916                    cur = new ArrayList<Intent>();
13917                }
13918                cur.add(intent);
13919            }
13920        }
13921        return cur;
13922    }
13923
13924    boolean isPendingBroadcastProcessLocked(int pid) {
13925        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13926                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13927    }
13928
13929    void skipPendingBroadcastLocked(int pid) {
13930            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13931            for (BroadcastQueue queue : mBroadcastQueues) {
13932                queue.skipPendingBroadcastLocked(pid);
13933            }
13934    }
13935
13936    // The app just attached; send any pending broadcasts that it should receive
13937    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13938        boolean didSomething = false;
13939        for (BroadcastQueue queue : mBroadcastQueues) {
13940            didSomething |= queue.sendPendingBroadcastsLocked(app);
13941        }
13942        return didSomething;
13943    }
13944
13945    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13946            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13947        enforceNotIsolatedCaller("registerReceiver");
13948        int callingUid;
13949        int callingPid;
13950        synchronized(this) {
13951            ProcessRecord callerApp = null;
13952            if (caller != null) {
13953                callerApp = getRecordForAppLocked(caller);
13954                if (callerApp == null) {
13955                    throw new SecurityException(
13956                            "Unable to find app for caller " + caller
13957                            + " (pid=" + Binder.getCallingPid()
13958                            + ") when registering receiver " + receiver);
13959                }
13960                if (callerApp.info.uid != Process.SYSTEM_UID &&
13961                        !callerApp.pkgList.containsKey(callerPackage) &&
13962                        !"android".equals(callerPackage)) {
13963                    throw new SecurityException("Given caller package " + callerPackage
13964                            + " is not running in process " + callerApp);
13965                }
13966                callingUid = callerApp.info.uid;
13967                callingPid = callerApp.pid;
13968            } else {
13969                callerPackage = null;
13970                callingUid = Binder.getCallingUid();
13971                callingPid = Binder.getCallingPid();
13972            }
13973
13974            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13975                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
13976
13977            List allSticky = null;
13978
13979            // Look for any matching sticky broadcasts...
13980            Iterator actions = filter.actionsIterator();
13981            if (actions != null) {
13982                while (actions.hasNext()) {
13983                    String action = (String)actions.next();
13984                    allSticky = getStickiesLocked(action, filter, allSticky,
13985                            UserHandle.USER_ALL);
13986                    allSticky = getStickiesLocked(action, filter, allSticky,
13987                            UserHandle.getUserId(callingUid));
13988                }
13989            } else {
13990                allSticky = getStickiesLocked(null, filter, allSticky,
13991                        UserHandle.USER_ALL);
13992                allSticky = getStickiesLocked(null, filter, allSticky,
13993                        UserHandle.getUserId(callingUid));
13994            }
13995
13996            // The first sticky in the list is returned directly back to
13997            // the client.
13998            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13999
14000            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14001                    + ": " + sticky);
14002
14003            if (receiver == null) {
14004                return sticky;
14005            }
14006
14007            ReceiverList rl
14008                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14009            if (rl == null) {
14010                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14011                        userId, receiver);
14012                if (rl.app != null) {
14013                    rl.app.receivers.add(rl);
14014                } else {
14015                    try {
14016                        receiver.asBinder().linkToDeath(rl, 0);
14017                    } catch (RemoteException e) {
14018                        return sticky;
14019                    }
14020                    rl.linkedToDeath = true;
14021                }
14022                mRegisteredReceivers.put(receiver.asBinder(), rl);
14023            } else if (rl.uid != callingUid) {
14024                throw new IllegalArgumentException(
14025                        "Receiver requested to register for uid " + callingUid
14026                        + " was previously registered for uid " + rl.uid);
14027            } else if (rl.pid != callingPid) {
14028                throw new IllegalArgumentException(
14029                        "Receiver requested to register for pid " + callingPid
14030                        + " was previously registered for pid " + rl.pid);
14031            } else if (rl.userId != userId) {
14032                throw new IllegalArgumentException(
14033                        "Receiver requested to register for user " + userId
14034                        + " was previously registered for user " + rl.userId);
14035            }
14036            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14037                    permission, callingUid, userId);
14038            rl.add(bf);
14039            if (!bf.debugCheck()) {
14040                Slog.w(TAG, "==> For Dynamic broadast");
14041            }
14042            mReceiverResolver.addFilter(bf);
14043
14044            // Enqueue broadcasts for all existing stickies that match
14045            // this filter.
14046            if (allSticky != null) {
14047                ArrayList receivers = new ArrayList();
14048                receivers.add(bf);
14049
14050                int N = allSticky.size();
14051                for (int i=0; i<N; i++) {
14052                    Intent intent = (Intent)allSticky.get(i);
14053                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14054                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14055                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14056                            null, null, false, true, true, -1);
14057                    queue.enqueueParallelBroadcastLocked(r);
14058                    queue.scheduleBroadcastsLocked();
14059                }
14060            }
14061
14062            return sticky;
14063        }
14064    }
14065
14066    public void unregisterReceiver(IIntentReceiver receiver) {
14067        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14068
14069        final long origId = Binder.clearCallingIdentity();
14070        try {
14071            boolean doTrim = false;
14072
14073            synchronized(this) {
14074                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14075                if (rl != null) {
14076                    if (rl.curBroadcast != null) {
14077                        BroadcastRecord r = rl.curBroadcast;
14078                        final boolean doNext = finishReceiverLocked(
14079                                receiver.asBinder(), r.resultCode, r.resultData,
14080                                r.resultExtras, r.resultAbort);
14081                        if (doNext) {
14082                            doTrim = true;
14083                            r.queue.processNextBroadcast(false);
14084                        }
14085                    }
14086
14087                    if (rl.app != null) {
14088                        rl.app.receivers.remove(rl);
14089                    }
14090                    removeReceiverLocked(rl);
14091                    if (rl.linkedToDeath) {
14092                        rl.linkedToDeath = false;
14093                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14094                    }
14095                }
14096            }
14097
14098            // If we actually concluded any broadcasts, we might now be able
14099            // to trim the recipients' apps from our working set
14100            if (doTrim) {
14101                trimApplications();
14102                return;
14103            }
14104
14105        } finally {
14106            Binder.restoreCallingIdentity(origId);
14107        }
14108    }
14109
14110    void removeReceiverLocked(ReceiverList rl) {
14111        mRegisteredReceivers.remove(rl.receiver.asBinder());
14112        int N = rl.size();
14113        for (int i=0; i<N; i++) {
14114            mReceiverResolver.removeFilter(rl.get(i));
14115        }
14116    }
14117
14118    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14119        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14120            ProcessRecord r = mLruProcesses.get(i);
14121            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14122                try {
14123                    r.thread.dispatchPackageBroadcast(cmd, packages);
14124                } catch (RemoteException ex) {
14125                }
14126            }
14127        }
14128    }
14129
14130    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14131            int[] users) {
14132        List<ResolveInfo> receivers = null;
14133        try {
14134            HashSet<ComponentName> singleUserReceivers = null;
14135            boolean scannedFirstReceivers = false;
14136            for (int user : users) {
14137                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14138                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14139                if (user != 0 && newReceivers != null) {
14140                    // If this is not the primary user, we need to check for
14141                    // any receivers that should be filtered out.
14142                    for (int i=0; i<newReceivers.size(); i++) {
14143                        ResolveInfo ri = newReceivers.get(i);
14144                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14145                            newReceivers.remove(i);
14146                            i--;
14147                        }
14148                    }
14149                }
14150                if (newReceivers != null && newReceivers.size() == 0) {
14151                    newReceivers = null;
14152                }
14153                if (receivers == null) {
14154                    receivers = newReceivers;
14155                } else if (newReceivers != null) {
14156                    // We need to concatenate the additional receivers
14157                    // found with what we have do far.  This would be easy,
14158                    // but we also need to de-dup any receivers that are
14159                    // singleUser.
14160                    if (!scannedFirstReceivers) {
14161                        // Collect any single user receivers we had already retrieved.
14162                        scannedFirstReceivers = true;
14163                        for (int i=0; i<receivers.size(); i++) {
14164                            ResolveInfo ri = receivers.get(i);
14165                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14166                                ComponentName cn = new ComponentName(
14167                                        ri.activityInfo.packageName, ri.activityInfo.name);
14168                                if (singleUserReceivers == null) {
14169                                    singleUserReceivers = new HashSet<ComponentName>();
14170                                }
14171                                singleUserReceivers.add(cn);
14172                            }
14173                        }
14174                    }
14175                    // Add the new results to the existing results, tracking
14176                    // and de-dupping single user receivers.
14177                    for (int i=0; i<newReceivers.size(); i++) {
14178                        ResolveInfo ri = newReceivers.get(i);
14179                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14180                            ComponentName cn = new ComponentName(
14181                                    ri.activityInfo.packageName, ri.activityInfo.name);
14182                            if (singleUserReceivers == null) {
14183                                singleUserReceivers = new HashSet<ComponentName>();
14184                            }
14185                            if (!singleUserReceivers.contains(cn)) {
14186                                singleUserReceivers.add(cn);
14187                                receivers.add(ri);
14188                            }
14189                        } else {
14190                            receivers.add(ri);
14191                        }
14192                    }
14193                }
14194            }
14195        } catch (RemoteException ex) {
14196            // pm is in same process, this will never happen.
14197        }
14198        return receivers;
14199    }
14200
14201    private final int broadcastIntentLocked(ProcessRecord callerApp,
14202            String callerPackage, Intent intent, String resolvedType,
14203            IIntentReceiver resultTo, int resultCode, String resultData,
14204            Bundle map, String requiredPermission, int appOp,
14205            boolean ordered, boolean sticky, int callingPid, int callingUid,
14206            int userId) {
14207        intent = new Intent(intent);
14208
14209        // By default broadcasts do not go to stopped apps.
14210        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
14211
14212        if (DEBUG_BROADCAST_LIGHT) Slog.v(
14213            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
14214            + " ordered=" + ordered + " userid=" + userId);
14215        if ((resultTo != null) && !ordered) {
14216            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
14217        }
14218
14219        userId = handleIncomingUser(callingPid, callingUid, userId,
14220                true, ALLOW_NON_FULL, "broadcast", callerPackage);
14221
14222        // Make sure that the user who is receiving this broadcast is started.
14223        // If not, we will just skip it.
14224
14225
14226        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
14227            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14228                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14229                Slog.w(TAG, "Skipping broadcast of " + intent
14230                        + ": user " + userId + " is stopped");
14231                return ActivityManager.BROADCAST_SUCCESS;
14232            }
14233        }
14234
14235        /*
14236         * Prevent non-system code (defined here to be non-persistent
14237         * processes) from sending protected broadcasts.
14238         */
14239        int callingAppId = UserHandle.getAppId(callingUid);
14240        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14241            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14242            || callingAppId == Process.NFC_UID || callingUid == 0) {
14243            // Always okay.
14244        } else if (callerApp == null || !callerApp.persistent) {
14245            try {
14246                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14247                        intent.getAction())) {
14248                    String msg = "Permission Denial: not allowed to send broadcast "
14249                            + intent.getAction() + " from pid="
14250                            + callingPid + ", uid=" + callingUid;
14251                    Slog.w(TAG, msg);
14252                    throw new SecurityException(msg);
14253                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14254                    // Special case for compatibility: we don't want apps to send this,
14255                    // but historically it has not been protected and apps may be using it
14256                    // to poke their own app widget.  So, instead of making it protected,
14257                    // just limit it to the caller.
14258                    if (callerApp == null) {
14259                        String msg = "Permission Denial: not allowed to send broadcast "
14260                                + intent.getAction() + " from unknown caller.";
14261                        Slog.w(TAG, msg);
14262                        throw new SecurityException(msg);
14263                    } else if (intent.getComponent() != null) {
14264                        // They are good enough to send to an explicit component...  verify
14265                        // it is being sent to the calling app.
14266                        if (!intent.getComponent().getPackageName().equals(
14267                                callerApp.info.packageName)) {
14268                            String msg = "Permission Denial: not allowed to send broadcast "
14269                                    + intent.getAction() + " to "
14270                                    + intent.getComponent().getPackageName() + " from "
14271                                    + callerApp.info.packageName;
14272                            Slog.w(TAG, msg);
14273                            throw new SecurityException(msg);
14274                        }
14275                    } else {
14276                        // Limit broadcast to their own package.
14277                        intent.setPackage(callerApp.info.packageName);
14278                    }
14279                }
14280            } catch (RemoteException e) {
14281                Slog.w(TAG, "Remote exception", e);
14282                return ActivityManager.BROADCAST_SUCCESS;
14283            }
14284        }
14285
14286        // Handle special intents: if this broadcast is from the package
14287        // manager about a package being removed, we need to remove all of
14288        // its activities from the history stack.
14289        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14290                intent.getAction());
14291        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14292                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14293                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14294                || uidRemoved) {
14295            if (checkComponentPermission(
14296                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14297                    callingPid, callingUid, -1, true)
14298                    == PackageManager.PERMISSION_GRANTED) {
14299                if (uidRemoved) {
14300                    final Bundle intentExtras = intent.getExtras();
14301                    final int uid = intentExtras != null
14302                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14303                    if (uid >= 0) {
14304                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14305                        synchronized (bs) {
14306                            bs.removeUidStatsLocked(uid);
14307                        }
14308                        mAppOpsService.uidRemoved(uid);
14309                    }
14310                } else {
14311                    // If resources are unavailable just force stop all
14312                    // those packages and flush the attribute cache as well.
14313                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14314                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14315                        if (list != null && (list.length > 0)) {
14316                            for (String pkg : list) {
14317                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14318                                        "storage unmount");
14319                            }
14320                            sendPackageBroadcastLocked(
14321                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14322                        }
14323                    } else {
14324                        Uri data = intent.getData();
14325                        String ssp;
14326                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14327                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14328                                    intent.getAction());
14329                            boolean fullUninstall = removed &&
14330                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14331                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14332                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14333                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14334                                        false, fullUninstall, userId,
14335                                        removed ? "pkg removed" : "pkg changed");
14336                            }
14337                            if (removed) {
14338                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14339                                        new String[] {ssp}, userId);
14340                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14341                                    mAppOpsService.packageRemoved(
14342                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14343
14344                                    // Remove all permissions granted from/to this package
14345                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14346                                }
14347                            }
14348                        }
14349                    }
14350                }
14351            } else {
14352                String msg = "Permission Denial: " + intent.getAction()
14353                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14354                        + ", uid=" + callingUid + ")"
14355                        + " requires "
14356                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14357                Slog.w(TAG, msg);
14358                throw new SecurityException(msg);
14359            }
14360
14361        // Special case for adding a package: by default turn on compatibility
14362        // mode.
14363        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14364            Uri data = intent.getData();
14365            String ssp;
14366            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14367                mCompatModePackages.handlePackageAddedLocked(ssp,
14368                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14369            }
14370        }
14371
14372        /*
14373         * If this is the time zone changed action, queue up a message that will reset the timezone
14374         * of all currently running processes. This message will get queued up before the broadcast
14375         * happens.
14376         */
14377        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14378            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14379        }
14380
14381        /*
14382         * If the user set the time, let all running processes know.
14383         */
14384        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14385            final int is24Hour = intent.getBooleanExtra(
14386                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14387            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14388        }
14389
14390        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14391            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14392        }
14393
14394        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14395            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14396            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14397        }
14398
14399        // Add to the sticky list if requested.
14400        if (sticky) {
14401            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14402                    callingPid, callingUid)
14403                    != PackageManager.PERMISSION_GRANTED) {
14404                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14405                        + callingPid + ", uid=" + callingUid
14406                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14407                Slog.w(TAG, msg);
14408                throw new SecurityException(msg);
14409            }
14410            if (requiredPermission != null) {
14411                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14412                        + " and enforce permission " + requiredPermission);
14413                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14414            }
14415            if (intent.getComponent() != null) {
14416                throw new SecurityException(
14417                        "Sticky broadcasts can't target a specific component");
14418            }
14419            // We use userId directly here, since the "all" target is maintained
14420            // as a separate set of sticky broadcasts.
14421            if (userId != UserHandle.USER_ALL) {
14422                // But first, if this is not a broadcast to all users, then
14423                // make sure it doesn't conflict with an existing broadcast to
14424                // all users.
14425                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14426                        UserHandle.USER_ALL);
14427                if (stickies != null) {
14428                    ArrayList<Intent> list = stickies.get(intent.getAction());
14429                    if (list != null) {
14430                        int N = list.size();
14431                        int i;
14432                        for (i=0; i<N; i++) {
14433                            if (intent.filterEquals(list.get(i))) {
14434                                throw new IllegalArgumentException(
14435                                        "Sticky broadcast " + intent + " for user "
14436                                        + userId + " conflicts with existing global broadcast");
14437                            }
14438                        }
14439                    }
14440                }
14441            }
14442            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14443            if (stickies == null) {
14444                stickies = new ArrayMap<String, ArrayList<Intent>>();
14445                mStickyBroadcasts.put(userId, stickies);
14446            }
14447            ArrayList<Intent> list = stickies.get(intent.getAction());
14448            if (list == null) {
14449                list = new ArrayList<Intent>();
14450                stickies.put(intent.getAction(), list);
14451            }
14452            int N = list.size();
14453            int i;
14454            for (i=0; i<N; i++) {
14455                if (intent.filterEquals(list.get(i))) {
14456                    // This sticky already exists, replace it.
14457                    list.set(i, new Intent(intent));
14458                    break;
14459                }
14460            }
14461            if (i >= N) {
14462                list.add(new Intent(intent));
14463            }
14464        }
14465
14466        int[] users;
14467        if (userId == UserHandle.USER_ALL) {
14468            // Caller wants broadcast to go to all started users.
14469            users = mStartedUserArray;
14470        } else {
14471            // Caller wants broadcast to go to one specific user.
14472            users = new int[] {userId};
14473        }
14474
14475        // Figure out who all will receive this broadcast.
14476        List receivers = null;
14477        List<BroadcastFilter> registeredReceivers = null;
14478        // Need to resolve the intent to interested receivers...
14479        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14480                 == 0) {
14481            receivers = collectReceiverComponents(intent, resolvedType, users);
14482        }
14483        if (intent.getComponent() == null) {
14484            registeredReceivers = mReceiverResolver.queryIntent(intent,
14485                    resolvedType, false, userId);
14486        }
14487
14488        final boolean replacePending =
14489                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14490
14491        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14492                + " replacePending=" + replacePending);
14493
14494        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14495        if (!ordered && NR > 0) {
14496            // If we are not serializing this broadcast, then send the
14497            // registered receivers separately so they don't wait for the
14498            // components to be launched.
14499            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14500            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14501                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14502                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14503                    ordered, sticky, false, userId);
14504            if (DEBUG_BROADCAST) Slog.v(
14505                    TAG, "Enqueueing parallel broadcast " + r);
14506            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14507            if (!replaced) {
14508                queue.enqueueParallelBroadcastLocked(r);
14509                queue.scheduleBroadcastsLocked();
14510            }
14511            registeredReceivers = null;
14512            NR = 0;
14513        }
14514
14515        // Merge into one list.
14516        int ir = 0;
14517        if (receivers != null) {
14518            // A special case for PACKAGE_ADDED: do not allow the package
14519            // being added to see this broadcast.  This prevents them from
14520            // using this as a back door to get run as soon as they are
14521            // installed.  Maybe in the future we want to have a special install
14522            // broadcast or such for apps, but we'd like to deliberately make
14523            // this decision.
14524            String skipPackages[] = null;
14525            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14526                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14527                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14528                Uri data = intent.getData();
14529                if (data != null) {
14530                    String pkgName = data.getSchemeSpecificPart();
14531                    if (pkgName != null) {
14532                        skipPackages = new String[] { pkgName };
14533                    }
14534                }
14535            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14536                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14537            }
14538            if (skipPackages != null && (skipPackages.length > 0)) {
14539                for (String skipPackage : skipPackages) {
14540                    if (skipPackage != null) {
14541                        int NT = receivers.size();
14542                        for (int it=0; it<NT; it++) {
14543                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14544                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14545                                receivers.remove(it);
14546                                it--;
14547                                NT--;
14548                            }
14549                        }
14550                    }
14551                }
14552            }
14553
14554            int NT = receivers != null ? receivers.size() : 0;
14555            int it = 0;
14556            ResolveInfo curt = null;
14557            BroadcastFilter curr = null;
14558            while (it < NT && ir < NR) {
14559                if (curt == null) {
14560                    curt = (ResolveInfo)receivers.get(it);
14561                }
14562                if (curr == null) {
14563                    curr = registeredReceivers.get(ir);
14564                }
14565                if (curr.getPriority() >= curt.priority) {
14566                    // Insert this broadcast record into the final list.
14567                    receivers.add(it, curr);
14568                    ir++;
14569                    curr = null;
14570                    it++;
14571                    NT++;
14572                } else {
14573                    // Skip to the next ResolveInfo in the final list.
14574                    it++;
14575                    curt = null;
14576                }
14577            }
14578        }
14579        while (ir < NR) {
14580            if (receivers == null) {
14581                receivers = new ArrayList();
14582            }
14583            receivers.add(registeredReceivers.get(ir));
14584            ir++;
14585        }
14586
14587        if ((receivers != null && receivers.size() > 0)
14588                || resultTo != null) {
14589            BroadcastQueue queue = broadcastQueueForIntent(intent);
14590            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14591                    callerPackage, callingPid, callingUid, resolvedType,
14592                    requiredPermission, appOp, receivers, resultTo, resultCode,
14593                    resultData, map, ordered, sticky, false, userId);
14594            if (DEBUG_BROADCAST) Slog.v(
14595                    TAG, "Enqueueing ordered broadcast " + r
14596                    + ": prev had " + queue.mOrderedBroadcasts.size());
14597            if (DEBUG_BROADCAST) {
14598                int seq = r.intent.getIntExtra("seq", -1);
14599                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14600            }
14601            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14602            if (!replaced) {
14603                queue.enqueueOrderedBroadcastLocked(r);
14604                queue.scheduleBroadcastsLocked();
14605            }
14606        }
14607
14608        return ActivityManager.BROADCAST_SUCCESS;
14609    }
14610
14611    final Intent verifyBroadcastLocked(Intent intent) {
14612        // Refuse possible leaked file descriptors
14613        if (intent != null && intent.hasFileDescriptors() == true) {
14614            throw new IllegalArgumentException("File descriptors passed in Intent");
14615        }
14616
14617        int flags = intent.getFlags();
14618
14619        if (!mProcessesReady) {
14620            // if the caller really truly claims to know what they're doing, go
14621            // ahead and allow the broadcast without launching any receivers
14622            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14623                intent = new Intent(intent);
14624                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14625            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14626                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14627                        + " before boot completion");
14628                throw new IllegalStateException("Cannot broadcast before boot completed");
14629            }
14630        }
14631
14632        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14633            throw new IllegalArgumentException(
14634                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14635        }
14636
14637        return intent;
14638    }
14639
14640    public final int broadcastIntent(IApplicationThread caller,
14641            Intent intent, String resolvedType, IIntentReceiver resultTo,
14642            int resultCode, String resultData, Bundle map,
14643            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14644        enforceNotIsolatedCaller("broadcastIntent");
14645        synchronized(this) {
14646            intent = verifyBroadcastLocked(intent);
14647
14648            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14649            final int callingPid = Binder.getCallingPid();
14650            final int callingUid = Binder.getCallingUid();
14651            final long origId = Binder.clearCallingIdentity();
14652            int res = broadcastIntentLocked(callerApp,
14653                    callerApp != null ? callerApp.info.packageName : null,
14654                    intent, resolvedType, resultTo,
14655                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14656                    callingPid, callingUid, userId);
14657            Binder.restoreCallingIdentity(origId);
14658            return res;
14659        }
14660    }
14661
14662    int broadcastIntentInPackage(String packageName, int uid,
14663            Intent intent, String resolvedType, IIntentReceiver resultTo,
14664            int resultCode, String resultData, Bundle map,
14665            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14666        synchronized(this) {
14667            intent = verifyBroadcastLocked(intent);
14668
14669            final long origId = Binder.clearCallingIdentity();
14670            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14671                    resultTo, resultCode, resultData, map, requiredPermission,
14672                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14673            Binder.restoreCallingIdentity(origId);
14674            return res;
14675        }
14676    }
14677
14678    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14679        // Refuse possible leaked file descriptors
14680        if (intent != null && intent.hasFileDescriptors() == true) {
14681            throw new IllegalArgumentException("File descriptors passed in Intent");
14682        }
14683
14684        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14685                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
14686
14687        synchronized(this) {
14688            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14689                    != PackageManager.PERMISSION_GRANTED) {
14690                String msg = "Permission Denial: unbroadcastIntent() from pid="
14691                        + Binder.getCallingPid()
14692                        + ", uid=" + Binder.getCallingUid()
14693                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14694                Slog.w(TAG, msg);
14695                throw new SecurityException(msg);
14696            }
14697            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14698            if (stickies != null) {
14699                ArrayList<Intent> list = stickies.get(intent.getAction());
14700                if (list != null) {
14701                    int N = list.size();
14702                    int i;
14703                    for (i=0; i<N; i++) {
14704                        if (intent.filterEquals(list.get(i))) {
14705                            list.remove(i);
14706                            break;
14707                        }
14708                    }
14709                    if (list.size() <= 0) {
14710                        stickies.remove(intent.getAction());
14711                    }
14712                }
14713                if (stickies.size() <= 0) {
14714                    mStickyBroadcasts.remove(userId);
14715                }
14716            }
14717        }
14718    }
14719
14720    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14721            String resultData, Bundle resultExtras, boolean resultAbort) {
14722        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14723        if (r == null) {
14724            Slog.w(TAG, "finishReceiver called but not found on queue");
14725            return false;
14726        }
14727
14728        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14729    }
14730
14731    void backgroundServicesFinishedLocked(int userId) {
14732        for (BroadcastQueue queue : mBroadcastQueues) {
14733            queue.backgroundServicesFinishedLocked(userId);
14734        }
14735    }
14736
14737    public void finishReceiver(IBinder who, int resultCode, String resultData,
14738            Bundle resultExtras, boolean resultAbort) {
14739        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14740
14741        // Refuse possible leaked file descriptors
14742        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14743            throw new IllegalArgumentException("File descriptors passed in Bundle");
14744        }
14745
14746        final long origId = Binder.clearCallingIdentity();
14747        try {
14748            boolean doNext = false;
14749            BroadcastRecord r;
14750
14751            synchronized(this) {
14752                r = broadcastRecordForReceiverLocked(who);
14753                if (r != null) {
14754                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14755                        resultData, resultExtras, resultAbort, true);
14756                }
14757            }
14758
14759            if (doNext) {
14760                r.queue.processNextBroadcast(false);
14761            }
14762            trimApplications();
14763        } finally {
14764            Binder.restoreCallingIdentity(origId);
14765        }
14766    }
14767
14768    // =========================================================
14769    // INSTRUMENTATION
14770    // =========================================================
14771
14772    public boolean startInstrumentation(ComponentName className,
14773            String profileFile, int flags, Bundle arguments,
14774            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14775            int userId, String abiOverride) {
14776        enforceNotIsolatedCaller("startInstrumentation");
14777        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14778                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
14779        // Refuse possible leaked file descriptors
14780        if (arguments != null && arguments.hasFileDescriptors()) {
14781            throw new IllegalArgumentException("File descriptors passed in Bundle");
14782        }
14783
14784        synchronized(this) {
14785            InstrumentationInfo ii = null;
14786            ApplicationInfo ai = null;
14787            try {
14788                ii = mContext.getPackageManager().getInstrumentationInfo(
14789                    className, STOCK_PM_FLAGS);
14790                ai = AppGlobals.getPackageManager().getApplicationInfo(
14791                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14792            } catch (PackageManager.NameNotFoundException e) {
14793            } catch (RemoteException e) {
14794            }
14795            if (ii == null) {
14796                reportStartInstrumentationFailure(watcher, className,
14797                        "Unable to find instrumentation info for: " + className);
14798                return false;
14799            }
14800            if (ai == null) {
14801                reportStartInstrumentationFailure(watcher, className,
14802                        "Unable to find instrumentation target package: " + ii.targetPackage);
14803                return false;
14804            }
14805
14806            int match = mContext.getPackageManager().checkSignatures(
14807                    ii.targetPackage, ii.packageName);
14808            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14809                String msg = "Permission Denial: starting instrumentation "
14810                        + className + " from pid="
14811                        + Binder.getCallingPid()
14812                        + ", uid=" + Binder.getCallingPid()
14813                        + " not allowed because package " + ii.packageName
14814                        + " does not have a signature matching the target "
14815                        + ii.targetPackage;
14816                reportStartInstrumentationFailure(watcher, className, msg);
14817                throw new SecurityException(msg);
14818            }
14819
14820            final long origId = Binder.clearCallingIdentity();
14821            // Instrumentation can kill and relaunch even persistent processes
14822            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14823                    "start instr");
14824            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14825            app.instrumentationClass = className;
14826            app.instrumentationInfo = ai;
14827            app.instrumentationProfileFile = profileFile;
14828            app.instrumentationArguments = arguments;
14829            app.instrumentationWatcher = watcher;
14830            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14831            app.instrumentationResultClass = className;
14832            Binder.restoreCallingIdentity(origId);
14833        }
14834
14835        return true;
14836    }
14837
14838    /**
14839     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14840     * error to the logs, but if somebody is watching, send the report there too.  This enables
14841     * the "am" command to report errors with more information.
14842     *
14843     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14844     * @param cn The component name of the instrumentation.
14845     * @param report The error report.
14846     */
14847    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14848            ComponentName cn, String report) {
14849        Slog.w(TAG, report);
14850        try {
14851            if (watcher != null) {
14852                Bundle results = new Bundle();
14853                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14854                results.putString("Error", report);
14855                watcher.instrumentationStatus(cn, -1, results);
14856            }
14857        } catch (RemoteException e) {
14858            Slog.w(TAG, e);
14859        }
14860    }
14861
14862    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14863        if (app.instrumentationWatcher != null) {
14864            try {
14865                // NOTE:  IInstrumentationWatcher *must* be oneway here
14866                app.instrumentationWatcher.instrumentationFinished(
14867                    app.instrumentationClass,
14868                    resultCode,
14869                    results);
14870            } catch (RemoteException e) {
14871            }
14872        }
14873        if (app.instrumentationUiAutomationConnection != null) {
14874            try {
14875                app.instrumentationUiAutomationConnection.shutdown();
14876            } catch (RemoteException re) {
14877                /* ignore */
14878            }
14879            // Only a UiAutomation can set this flag and now that
14880            // it is finished we make sure it is reset to its default.
14881            mUserIsMonkey = false;
14882        }
14883        app.instrumentationWatcher = null;
14884        app.instrumentationUiAutomationConnection = null;
14885        app.instrumentationClass = null;
14886        app.instrumentationInfo = null;
14887        app.instrumentationProfileFile = null;
14888        app.instrumentationArguments = null;
14889
14890        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14891                "finished inst");
14892    }
14893
14894    public void finishInstrumentation(IApplicationThread target,
14895            int resultCode, Bundle results) {
14896        int userId = UserHandle.getCallingUserId();
14897        // Refuse possible leaked file descriptors
14898        if (results != null && results.hasFileDescriptors()) {
14899            throw new IllegalArgumentException("File descriptors passed in Intent");
14900        }
14901
14902        synchronized(this) {
14903            ProcessRecord app = getRecordForAppLocked(target);
14904            if (app == null) {
14905                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14906                return;
14907            }
14908            final long origId = Binder.clearCallingIdentity();
14909            finishInstrumentationLocked(app, resultCode, results);
14910            Binder.restoreCallingIdentity(origId);
14911        }
14912    }
14913
14914    // =========================================================
14915    // CONFIGURATION
14916    // =========================================================
14917
14918    public ConfigurationInfo getDeviceConfigurationInfo() {
14919        ConfigurationInfo config = new ConfigurationInfo();
14920        synchronized (this) {
14921            config.reqTouchScreen = mConfiguration.touchscreen;
14922            config.reqKeyboardType = mConfiguration.keyboard;
14923            config.reqNavigation = mConfiguration.navigation;
14924            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14925                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14926                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14927            }
14928            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14929                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14930                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14931            }
14932            config.reqGlEsVersion = GL_ES_VERSION;
14933        }
14934        return config;
14935    }
14936
14937    ActivityStack getFocusedStack() {
14938        return mStackSupervisor.getFocusedStack();
14939    }
14940
14941    public Configuration getConfiguration() {
14942        Configuration ci;
14943        synchronized(this) {
14944            ci = new Configuration(mConfiguration);
14945        }
14946        return ci;
14947    }
14948
14949    public void updatePersistentConfiguration(Configuration values) {
14950        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14951                "updateConfiguration()");
14952        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14953                "updateConfiguration()");
14954        if (values == null) {
14955            throw new NullPointerException("Configuration must not be null");
14956        }
14957
14958        synchronized(this) {
14959            final long origId = Binder.clearCallingIdentity();
14960            updateConfigurationLocked(values, null, true, false);
14961            Binder.restoreCallingIdentity(origId);
14962        }
14963    }
14964
14965    public void updateConfiguration(Configuration values) {
14966        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14967                "updateConfiguration()");
14968
14969        synchronized(this) {
14970            if (values == null && mWindowManager != null) {
14971                // sentinel: fetch the current configuration from the window manager
14972                values = mWindowManager.computeNewConfiguration();
14973            }
14974
14975            if (mWindowManager != null) {
14976                mProcessList.applyDisplaySize(mWindowManager);
14977            }
14978
14979            final long origId = Binder.clearCallingIdentity();
14980            if (values != null) {
14981                Settings.System.clearConfiguration(values);
14982            }
14983            updateConfigurationLocked(values, null, false, false);
14984            Binder.restoreCallingIdentity(origId);
14985        }
14986    }
14987
14988    /**
14989     * Do either or both things: (1) change the current configuration, and (2)
14990     * make sure the given activity is running with the (now) current
14991     * configuration.  Returns true if the activity has been left running, or
14992     * false if <var>starting</var> is being destroyed to match the new
14993     * configuration.
14994     * @param persistent TODO
14995     */
14996    boolean updateConfigurationLocked(Configuration values,
14997            ActivityRecord starting, boolean persistent, boolean initLocale) {
14998        int changes = 0;
14999
15000        if (values != null) {
15001            Configuration newConfig = new Configuration(mConfiguration);
15002            changes = newConfig.updateFrom(values);
15003            if (changes != 0) {
15004                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15005                    Slog.i(TAG, "Updating configuration to: " + values);
15006                }
15007
15008                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15009
15010                if (values.locale != null && !initLocale) {
15011                    saveLocaleLocked(values.locale,
15012                                     !values.locale.equals(mConfiguration.locale),
15013                                     values.userSetLocale);
15014                }
15015
15016                mConfigurationSeq++;
15017                if (mConfigurationSeq <= 0) {
15018                    mConfigurationSeq = 1;
15019                }
15020                newConfig.seq = mConfigurationSeq;
15021                mConfiguration = newConfig;
15022                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15023                mUsageStatsService.noteStartConfig(newConfig);
15024
15025                final Configuration configCopy = new Configuration(mConfiguration);
15026
15027                // TODO: If our config changes, should we auto dismiss any currently
15028                // showing dialogs?
15029                mShowDialogs = shouldShowDialogs(newConfig);
15030
15031                AttributeCache ac = AttributeCache.instance();
15032                if (ac != null) {
15033                    ac.updateConfiguration(configCopy);
15034                }
15035
15036                // Make sure all resources in our process are updated
15037                // right now, so that anyone who is going to retrieve
15038                // resource values after we return will be sure to get
15039                // the new ones.  This is especially important during
15040                // boot, where the first config change needs to guarantee
15041                // all resources have that config before following boot
15042                // code is executed.
15043                mSystemThread.applyConfigurationToResources(configCopy);
15044
15045                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15046                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15047                    msg.obj = new Configuration(configCopy);
15048                    mHandler.sendMessage(msg);
15049                }
15050
15051                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15052                    ProcessRecord app = mLruProcesses.get(i);
15053                    try {
15054                        if (app.thread != null) {
15055                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15056                                    + app.processName + " new config " + mConfiguration);
15057                            app.thread.scheduleConfigurationChanged(configCopy);
15058                        }
15059                    } catch (Exception e) {
15060                    }
15061                }
15062                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15063                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15064                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15065                        | Intent.FLAG_RECEIVER_FOREGROUND);
15066                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15067                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15068                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15069                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15070                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15071                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15072                    broadcastIntentLocked(null, null, intent,
15073                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15074                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15075                }
15076            }
15077        }
15078
15079        boolean kept = true;
15080        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15081        // mainStack is null during startup.
15082        if (mainStack != null) {
15083            if (changes != 0 && starting == null) {
15084                // If the configuration changed, and the caller is not already
15085                // in the process of starting an activity, then find the top
15086                // activity to check if its configuration needs to change.
15087                starting = mainStack.topRunningActivityLocked(null);
15088            }
15089
15090            if (starting != null) {
15091                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15092                // And we need to make sure at this point that all other activities
15093                // are made visible with the correct configuration.
15094                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15095            }
15096        }
15097
15098        if (values != null && mWindowManager != null) {
15099            mWindowManager.setNewConfiguration(mConfiguration);
15100        }
15101
15102        return kept;
15103    }
15104
15105    /**
15106     * Decide based on the configuration whether we should shouw the ANR,
15107     * crash, etc dialogs.  The idea is that if there is no affordnace to
15108     * press the on-screen buttons, we shouldn't show the dialog.
15109     *
15110     * A thought: SystemUI might also want to get told about this, the Power
15111     * dialog / global actions also might want different behaviors.
15112     */
15113    private static final boolean shouldShowDialogs(Configuration config) {
15114        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15115                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15116    }
15117
15118    /**
15119     * Save the locale.  You must be inside a synchronized (this) block.
15120     */
15121    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15122        if(isDiff) {
15123            SystemProperties.set("user.language", l.getLanguage());
15124            SystemProperties.set("user.region", l.getCountry());
15125        }
15126
15127        if(isPersist) {
15128            SystemProperties.set("persist.sys.language", l.getLanguage());
15129            SystemProperties.set("persist.sys.country", l.getCountry());
15130            SystemProperties.set("persist.sys.localevar", l.getVariant());
15131        }
15132    }
15133
15134    @Override
15135    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
15136        ActivityRecord srec = ActivityRecord.forToken(token);
15137        return srec != null && srec.task.affinity != null &&
15138                srec.task.affinity.equals(destAffinity);
15139    }
15140
15141    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15142            Intent resultData) {
15143
15144        synchronized (this) {
15145            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15146            if (stack != null) {
15147                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15148            }
15149            return false;
15150        }
15151    }
15152
15153    public int getLaunchedFromUid(IBinder activityToken) {
15154        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15155        if (srec == null) {
15156            return -1;
15157        }
15158        return srec.launchedFromUid;
15159    }
15160
15161    public String getLaunchedFromPackage(IBinder activityToken) {
15162        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15163        if (srec == null) {
15164            return null;
15165        }
15166        return srec.launchedFromPackage;
15167    }
15168
15169    // =========================================================
15170    // LIFETIME MANAGEMENT
15171    // =========================================================
15172
15173    // Returns which broadcast queue the app is the current [or imminent] receiver
15174    // on, or 'null' if the app is not an active broadcast recipient.
15175    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
15176        BroadcastRecord r = app.curReceiver;
15177        if (r != null) {
15178            return r.queue;
15179        }
15180
15181        // It's not the current receiver, but it might be starting up to become one
15182        synchronized (this) {
15183            for (BroadcastQueue queue : mBroadcastQueues) {
15184                r = queue.mPendingBroadcast;
15185                if (r != null && r.curApp == app) {
15186                    // found it; report which queue it's in
15187                    return queue;
15188                }
15189            }
15190        }
15191
15192        return null;
15193    }
15194
15195    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
15196            boolean doingAll, long now) {
15197        if (mAdjSeq == app.adjSeq) {
15198            // This adjustment has already been computed.
15199            return app.curRawAdj;
15200        }
15201
15202        if (app.thread == null) {
15203            app.adjSeq = mAdjSeq;
15204            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15205            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15206            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
15207        }
15208
15209        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
15210        app.adjSource = null;
15211        app.adjTarget = null;
15212        app.empty = false;
15213        app.cached = false;
15214
15215        final int activitiesSize = app.activities.size();
15216
15217        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15218            // The max adjustment doesn't allow this app to be anything
15219            // below foreground, so it is not worth doing work for it.
15220            app.adjType = "fixed";
15221            app.adjSeq = mAdjSeq;
15222            app.curRawAdj = app.maxAdj;
15223            app.foregroundActivities = false;
15224            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
15225            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
15226            // System processes can do UI, and when they do we want to have
15227            // them trim their memory after the user leaves the UI.  To
15228            // facilitate this, here we need to determine whether or not it
15229            // is currently showing UI.
15230            app.systemNoUi = true;
15231            if (app == TOP_APP) {
15232                app.systemNoUi = false;
15233            } else if (activitiesSize > 0) {
15234                for (int j = 0; j < activitiesSize; j++) {
15235                    final ActivityRecord r = app.activities.get(j);
15236                    if (r.visible) {
15237                        app.systemNoUi = false;
15238                    }
15239                }
15240            }
15241            if (!app.systemNoUi) {
15242                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15243            }
15244            return (app.curAdj=app.maxAdj);
15245        }
15246
15247        app.systemNoUi = false;
15248
15249        // Determine the importance of the process, starting with most
15250        // important to least, and assign an appropriate OOM adjustment.
15251        int adj;
15252        int schedGroup;
15253        int procState;
15254        boolean foregroundActivities = false;
15255        BroadcastQueue queue;
15256        if (app == TOP_APP) {
15257            // The last app on the list is the foreground app.
15258            adj = ProcessList.FOREGROUND_APP_ADJ;
15259            schedGroup = Process.THREAD_GROUP_DEFAULT;
15260            app.adjType = "top-activity";
15261            foregroundActivities = true;
15262            procState = ActivityManager.PROCESS_STATE_TOP;
15263        } else if (app.instrumentationClass != null) {
15264            // Don't want to kill running instrumentation.
15265            adj = ProcessList.FOREGROUND_APP_ADJ;
15266            schedGroup = Process.THREAD_GROUP_DEFAULT;
15267            app.adjType = "instrumentation";
15268            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15269        } else if ((queue = isReceivingBroadcast(app)) != null) {
15270            // An app that is currently receiving a broadcast also
15271            // counts as being in the foreground for OOM killer purposes.
15272            // It's placed in a sched group based on the nature of the
15273            // broadcast as reflected by which queue it's active in.
15274            adj = ProcessList.FOREGROUND_APP_ADJ;
15275            schedGroup = (queue == mFgBroadcastQueue)
15276                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15277            app.adjType = "broadcast";
15278            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15279        } else if (app.executingServices.size() > 0) {
15280            // An app that is currently executing a service callback also
15281            // counts as being in the foreground.
15282            adj = ProcessList.FOREGROUND_APP_ADJ;
15283            schedGroup = app.execServicesFg ?
15284                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15285            app.adjType = "exec-service";
15286            procState = ActivityManager.PROCESS_STATE_SERVICE;
15287            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15288        } else {
15289            // As far as we know the process is empty.  We may change our mind later.
15290            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15291            // At this point we don't actually know the adjustment.  Use the cached adj
15292            // value that the caller wants us to.
15293            adj = cachedAdj;
15294            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15295            app.cached = true;
15296            app.empty = true;
15297            app.adjType = "cch-empty";
15298        }
15299
15300        // Examine all activities if not already foreground.
15301        if (!foregroundActivities && activitiesSize > 0) {
15302            for (int j = 0; j < activitiesSize; j++) {
15303                final ActivityRecord r = app.activities.get(j);
15304                if (r.app != app) {
15305                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15306                            + app + "?!?");
15307                    continue;
15308                }
15309                if (r.visible) {
15310                    // App has a visible activity; only upgrade adjustment.
15311                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15312                        adj = ProcessList.VISIBLE_APP_ADJ;
15313                        app.adjType = "visible";
15314                    }
15315                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15316                        procState = ActivityManager.PROCESS_STATE_TOP;
15317                    }
15318                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15319                    app.cached = false;
15320                    app.empty = false;
15321                    foregroundActivities = true;
15322                    break;
15323                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15324                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15325                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15326                        app.adjType = "pausing";
15327                    }
15328                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15329                        procState = ActivityManager.PROCESS_STATE_TOP;
15330                    }
15331                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15332                    app.cached = false;
15333                    app.empty = false;
15334                    foregroundActivities = true;
15335                } else if (r.state == ActivityState.STOPPING) {
15336                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15337                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15338                        app.adjType = "stopping";
15339                    }
15340                    // For the process state, we will at this point consider the
15341                    // process to be cached.  It will be cached either as an activity
15342                    // or empty depending on whether the activity is finishing.  We do
15343                    // this so that we can treat the process as cached for purposes of
15344                    // memory trimming (determing current memory level, trim command to
15345                    // send to process) since there can be an arbitrary number of stopping
15346                    // processes and they should soon all go into the cached state.
15347                    if (!r.finishing) {
15348                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15349                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15350                        }
15351                    }
15352                    app.cached = false;
15353                    app.empty = false;
15354                    foregroundActivities = true;
15355                } else {
15356                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15357                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15358                        app.adjType = "cch-act";
15359                    }
15360                }
15361            }
15362        }
15363
15364        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15365            if (app.foregroundServices) {
15366                // The user is aware of this app, so make it visible.
15367                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15368                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15369                app.cached = false;
15370                app.adjType = "fg-service";
15371                schedGroup = Process.THREAD_GROUP_DEFAULT;
15372            } else if (app.forcingToForeground != null) {
15373                // The user is aware of this app, so make it visible.
15374                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15375                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15376                app.cached = false;
15377                app.adjType = "force-fg";
15378                app.adjSource = app.forcingToForeground;
15379                schedGroup = Process.THREAD_GROUP_DEFAULT;
15380            }
15381        }
15382
15383        if (app == mHeavyWeightProcess) {
15384            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15385                // We don't want to kill the current heavy-weight process.
15386                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15387                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15388                app.cached = false;
15389                app.adjType = "heavy";
15390            }
15391            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15392                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15393            }
15394        }
15395
15396        if (app == mHomeProcess) {
15397            if (adj > ProcessList.HOME_APP_ADJ) {
15398                // This process is hosting what we currently consider to be the
15399                // home app, so we don't want to let it go into the background.
15400                adj = ProcessList.HOME_APP_ADJ;
15401                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15402                app.cached = false;
15403                app.adjType = "home";
15404            }
15405            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15406                procState = ActivityManager.PROCESS_STATE_HOME;
15407            }
15408        }
15409
15410        if (app == mPreviousProcess && app.activities.size() > 0) {
15411            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15412                // This was the previous process that showed UI to the user.
15413                // We want to try to keep it around more aggressively, to give
15414                // a good experience around switching between two apps.
15415                adj = ProcessList.PREVIOUS_APP_ADJ;
15416                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15417                app.cached = false;
15418                app.adjType = "previous";
15419            }
15420            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15421                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15422            }
15423        }
15424
15425        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15426                + " reason=" + app.adjType);
15427
15428        // By default, we use the computed adjustment.  It may be changed if
15429        // there are applications dependent on our services or providers, but
15430        // this gives us a baseline and makes sure we don't get into an
15431        // infinite recursion.
15432        app.adjSeq = mAdjSeq;
15433        app.curRawAdj = adj;
15434        app.hasStartedServices = false;
15435
15436        if (mBackupTarget != null && app == mBackupTarget.app) {
15437            // If possible we want to avoid killing apps while they're being backed up
15438            if (adj > ProcessList.BACKUP_APP_ADJ) {
15439                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15440                adj = ProcessList.BACKUP_APP_ADJ;
15441                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15442                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15443                }
15444                app.adjType = "backup";
15445                app.cached = false;
15446            }
15447            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15448                procState = ActivityManager.PROCESS_STATE_BACKUP;
15449            }
15450        }
15451
15452        boolean mayBeTop = false;
15453
15454        for (int is = app.services.size()-1;
15455                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15456                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15457                        || procState > ActivityManager.PROCESS_STATE_TOP);
15458                is--) {
15459            ServiceRecord s = app.services.valueAt(is);
15460            if (s.startRequested) {
15461                app.hasStartedServices = true;
15462                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15463                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15464                }
15465                if (app.hasShownUi && app != mHomeProcess) {
15466                    // If this process has shown some UI, let it immediately
15467                    // go to the LRU list because it may be pretty heavy with
15468                    // UI stuff.  We'll tag it with a label just to help
15469                    // debug and understand what is going on.
15470                    if (adj > ProcessList.SERVICE_ADJ) {
15471                        app.adjType = "cch-started-ui-services";
15472                    }
15473                } else {
15474                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15475                        // This service has seen some activity within
15476                        // recent memory, so we will keep its process ahead
15477                        // of the background processes.
15478                        if (adj > ProcessList.SERVICE_ADJ) {
15479                            adj = ProcessList.SERVICE_ADJ;
15480                            app.adjType = "started-services";
15481                            app.cached = false;
15482                        }
15483                    }
15484                    // If we have let the service slide into the background
15485                    // state, still have some text describing what it is doing
15486                    // even though the service no longer has an impact.
15487                    if (adj > ProcessList.SERVICE_ADJ) {
15488                        app.adjType = "cch-started-services";
15489                    }
15490                }
15491            }
15492            for (int conni = s.connections.size()-1;
15493                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15494                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15495                            || procState > ActivityManager.PROCESS_STATE_TOP);
15496                    conni--) {
15497                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15498                for (int i = 0;
15499                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15500                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15501                                || procState > ActivityManager.PROCESS_STATE_TOP);
15502                        i++) {
15503                    // XXX should compute this based on the max of
15504                    // all connected clients.
15505                    ConnectionRecord cr = clist.get(i);
15506                    if (cr.binding.client == app) {
15507                        // Binding to ourself is not interesting.
15508                        continue;
15509                    }
15510                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15511                        ProcessRecord client = cr.binding.client;
15512                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15513                                TOP_APP, doingAll, now);
15514                        int clientProcState = client.curProcState;
15515                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15516                            // If the other app is cached for any reason, for purposes here
15517                            // we are going to consider it empty.  The specific cached state
15518                            // doesn't propagate except under certain conditions.
15519                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15520                        }
15521                        String adjType = null;
15522                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15523                            // Not doing bind OOM management, so treat
15524                            // this guy more like a started service.
15525                            if (app.hasShownUi && app != mHomeProcess) {
15526                                // If this process has shown some UI, let it immediately
15527                                // go to the LRU list because it may be pretty heavy with
15528                                // UI stuff.  We'll tag it with a label just to help
15529                                // debug and understand what is going on.
15530                                if (adj > clientAdj) {
15531                                    adjType = "cch-bound-ui-services";
15532                                }
15533                                app.cached = false;
15534                                clientAdj = adj;
15535                                clientProcState = procState;
15536                            } else {
15537                                if (now >= (s.lastActivity
15538                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15539                                    // This service has not seen activity within
15540                                    // recent memory, so allow it to drop to the
15541                                    // LRU list if there is no other reason to keep
15542                                    // it around.  We'll also tag it with a label just
15543                                    // to help debug and undertand what is going on.
15544                                    if (adj > clientAdj) {
15545                                        adjType = "cch-bound-services";
15546                                    }
15547                                    clientAdj = adj;
15548                                }
15549                            }
15550                        }
15551                        if (adj > clientAdj) {
15552                            // If this process has recently shown UI, and
15553                            // the process that is binding to it is less
15554                            // important than being visible, then we don't
15555                            // care about the binding as much as we care
15556                            // about letting this process get into the LRU
15557                            // list to be killed and restarted if needed for
15558                            // memory.
15559                            if (app.hasShownUi && app != mHomeProcess
15560                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15561                                adjType = "cch-bound-ui-services";
15562                            } else {
15563                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15564                                        |Context.BIND_IMPORTANT)) != 0) {
15565                                    adj = clientAdj;
15566                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15567                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15568                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15569                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15570                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15571                                    adj = clientAdj;
15572                                } else {
15573                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15574                                        adj = ProcessList.VISIBLE_APP_ADJ;
15575                                    }
15576                                }
15577                                if (!client.cached) {
15578                                    app.cached = false;
15579                                }
15580                                adjType = "service";
15581                            }
15582                        }
15583                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15584                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15585                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15586                            }
15587                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15588                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15589                                    // Special handling of clients who are in the top state.
15590                                    // We *may* want to consider this process to be in the
15591                                    // top state as well, but only if there is not another
15592                                    // reason for it to be running.  Being on the top is a
15593                                    // special state, meaning you are specifically running
15594                                    // for the current top app.  If the process is already
15595                                    // running in the background for some other reason, it
15596                                    // is more important to continue considering it to be
15597                                    // in the background state.
15598                                    mayBeTop = true;
15599                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15600                                } else {
15601                                    // Special handling for above-top states (persistent
15602                                    // processes).  These should not bring the current process
15603                                    // into the top state, since they are not on top.  Instead
15604                                    // give them the best state after that.
15605                                    clientProcState =
15606                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15607                                }
15608                            }
15609                        } else {
15610                            if (clientProcState <
15611                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15612                                clientProcState =
15613                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15614                            }
15615                        }
15616                        if (procState > clientProcState) {
15617                            procState = clientProcState;
15618                        }
15619                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15620                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15621                            app.pendingUiClean = true;
15622                        }
15623                        if (adjType != null) {
15624                            app.adjType = adjType;
15625                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15626                                    .REASON_SERVICE_IN_USE;
15627                            app.adjSource = cr.binding.client;
15628                            app.adjSourceProcState = clientProcState;
15629                            app.adjTarget = s.name;
15630                        }
15631                    }
15632                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15633                        app.treatLikeActivity = true;
15634                    }
15635                    final ActivityRecord a = cr.activity;
15636                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15637                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15638                                (a.visible || a.state == ActivityState.RESUMED
15639                                 || a.state == ActivityState.PAUSING)) {
15640                            adj = ProcessList.FOREGROUND_APP_ADJ;
15641                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15642                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15643                            }
15644                            app.cached = false;
15645                            app.adjType = "service";
15646                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15647                                    .REASON_SERVICE_IN_USE;
15648                            app.adjSource = a;
15649                            app.adjSourceProcState = procState;
15650                            app.adjTarget = s.name;
15651                        }
15652                    }
15653                }
15654            }
15655        }
15656
15657        for (int provi = app.pubProviders.size()-1;
15658                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15659                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15660                        || procState > ActivityManager.PROCESS_STATE_TOP);
15661                provi--) {
15662            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15663            for (int i = cpr.connections.size()-1;
15664                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15665                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15666                            || procState > ActivityManager.PROCESS_STATE_TOP);
15667                    i--) {
15668                ContentProviderConnection conn = cpr.connections.get(i);
15669                ProcessRecord client = conn.client;
15670                if (client == app) {
15671                    // Being our own client is not interesting.
15672                    continue;
15673                }
15674                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15675                int clientProcState = client.curProcState;
15676                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15677                    // If the other app is cached for any reason, for purposes here
15678                    // we are going to consider it empty.
15679                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15680                }
15681                if (adj > clientAdj) {
15682                    if (app.hasShownUi && app != mHomeProcess
15683                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15684                        app.adjType = "cch-ui-provider";
15685                    } else {
15686                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15687                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15688                        app.adjType = "provider";
15689                    }
15690                    app.cached &= client.cached;
15691                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15692                            .REASON_PROVIDER_IN_USE;
15693                    app.adjSource = client;
15694                    app.adjSourceProcState = clientProcState;
15695                    app.adjTarget = cpr.name;
15696                }
15697                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15698                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15699                        // Special handling of clients who are in the top state.
15700                        // We *may* want to consider this process to be in the
15701                        // top state as well, but only if there is not another
15702                        // reason for it to be running.  Being on the top is a
15703                        // special state, meaning you are specifically running
15704                        // for the current top app.  If the process is already
15705                        // running in the background for some other reason, it
15706                        // is more important to continue considering it to be
15707                        // in the background state.
15708                        mayBeTop = true;
15709                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15710                    } else {
15711                        // Special handling for above-top states (persistent
15712                        // processes).  These should not bring the current process
15713                        // into the top state, since they are not on top.  Instead
15714                        // give them the best state after that.
15715                        clientProcState =
15716                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15717                    }
15718                }
15719                if (procState > clientProcState) {
15720                    procState = clientProcState;
15721                }
15722                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15723                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15724                }
15725            }
15726            // If the provider has external (non-framework) process
15727            // dependencies, ensure that its adjustment is at least
15728            // FOREGROUND_APP_ADJ.
15729            if (cpr.hasExternalProcessHandles()) {
15730                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15731                    adj = ProcessList.FOREGROUND_APP_ADJ;
15732                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15733                    app.cached = false;
15734                    app.adjType = "provider";
15735                    app.adjTarget = cpr.name;
15736                }
15737                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15738                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15739                }
15740            }
15741        }
15742
15743        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15744            // A client of one of our services or providers is in the top state.  We
15745            // *may* want to be in the top state, but not if we are already running in
15746            // the background for some other reason.  For the decision here, we are going
15747            // to pick out a few specific states that we want to remain in when a client
15748            // is top (states that tend to be longer-term) and otherwise allow it to go
15749            // to the top state.
15750            switch (procState) {
15751                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15752                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15753                case ActivityManager.PROCESS_STATE_SERVICE:
15754                    // These all are longer-term states, so pull them up to the top
15755                    // of the background states, but not all the way to the top state.
15756                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15757                    break;
15758                default:
15759                    // Otherwise, top is a better choice, so take it.
15760                    procState = ActivityManager.PROCESS_STATE_TOP;
15761                    break;
15762            }
15763        }
15764
15765        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15766            if (app.hasClientActivities) {
15767                // This is a cached process, but with client activities.  Mark it so.
15768                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15769                app.adjType = "cch-client-act";
15770            } else if (app.treatLikeActivity) {
15771                // This is a cached process, but somebody wants us to treat it like it has
15772                // an activity, okay!
15773                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15774                app.adjType = "cch-as-act";
15775            }
15776        }
15777
15778        if (adj == ProcessList.SERVICE_ADJ) {
15779            if (doingAll) {
15780                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15781                mNewNumServiceProcs++;
15782                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15783                if (!app.serviceb) {
15784                    // This service isn't far enough down on the LRU list to
15785                    // normally be a B service, but if we are low on RAM and it
15786                    // is large we want to force it down since we would prefer to
15787                    // keep launcher over it.
15788                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15789                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15790                        app.serviceHighRam = true;
15791                        app.serviceb = true;
15792                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15793                    } else {
15794                        mNewNumAServiceProcs++;
15795                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15796                    }
15797                } else {
15798                    app.serviceHighRam = false;
15799                }
15800            }
15801            if (app.serviceb) {
15802                adj = ProcessList.SERVICE_B_ADJ;
15803            }
15804        }
15805
15806        app.curRawAdj = adj;
15807
15808        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15809        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15810        if (adj > app.maxAdj) {
15811            adj = app.maxAdj;
15812            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15813                schedGroup = Process.THREAD_GROUP_DEFAULT;
15814            }
15815        }
15816
15817        // Do final modification to adj.  Everything we do between here and applying
15818        // the final setAdj must be done in this function, because we will also use
15819        // it when computing the final cached adj later.  Note that we don't need to
15820        // worry about this for max adj above, since max adj will always be used to
15821        // keep it out of the cached vaues.
15822        app.curAdj = app.modifyRawOomAdj(adj);
15823        app.curSchedGroup = schedGroup;
15824        app.curProcState = procState;
15825        app.foregroundActivities = foregroundActivities;
15826
15827        return app.curRawAdj;
15828    }
15829
15830    /**
15831     * Schedule PSS collection of a process.
15832     */
15833    void requestPssLocked(ProcessRecord proc, int procState) {
15834        if (mPendingPssProcesses.contains(proc)) {
15835            return;
15836        }
15837        if (mPendingPssProcesses.size() == 0) {
15838            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15839        }
15840        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15841        proc.pssProcState = procState;
15842        mPendingPssProcesses.add(proc);
15843    }
15844
15845    /**
15846     * Schedule PSS collection of all processes.
15847     */
15848    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15849        if (!always) {
15850            if (now < (mLastFullPssTime +
15851                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15852                return;
15853            }
15854        }
15855        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15856        mLastFullPssTime = now;
15857        mFullPssPending = true;
15858        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15859        mPendingPssProcesses.clear();
15860        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15861            ProcessRecord app = mLruProcesses.get(i);
15862            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15863                app.pssProcState = app.setProcState;
15864                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15865                        isSleeping(), now);
15866                mPendingPssProcesses.add(app);
15867            }
15868        }
15869        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15870    }
15871
15872    /**
15873     * Ask a given process to GC right now.
15874     */
15875    final void performAppGcLocked(ProcessRecord app) {
15876        try {
15877            app.lastRequestedGc = SystemClock.uptimeMillis();
15878            if (app.thread != null) {
15879                if (app.reportLowMemory) {
15880                    app.reportLowMemory = false;
15881                    app.thread.scheduleLowMemory();
15882                } else {
15883                    app.thread.processInBackground();
15884                }
15885            }
15886        } catch (Exception e) {
15887            // whatever.
15888        }
15889    }
15890
15891    /**
15892     * Returns true if things are idle enough to perform GCs.
15893     */
15894    private final boolean canGcNowLocked() {
15895        boolean processingBroadcasts = false;
15896        for (BroadcastQueue q : mBroadcastQueues) {
15897            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15898                processingBroadcasts = true;
15899            }
15900        }
15901        return !processingBroadcasts
15902                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15903    }
15904
15905    /**
15906     * Perform GCs on all processes that are waiting for it, but only
15907     * if things are idle.
15908     */
15909    final void performAppGcsLocked() {
15910        final int N = mProcessesToGc.size();
15911        if (N <= 0) {
15912            return;
15913        }
15914        if (canGcNowLocked()) {
15915            while (mProcessesToGc.size() > 0) {
15916                ProcessRecord proc = mProcessesToGc.remove(0);
15917                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15918                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15919                            <= SystemClock.uptimeMillis()) {
15920                        // To avoid spamming the system, we will GC processes one
15921                        // at a time, waiting a few seconds between each.
15922                        performAppGcLocked(proc);
15923                        scheduleAppGcsLocked();
15924                        return;
15925                    } else {
15926                        // It hasn't been long enough since we last GCed this
15927                        // process...  put it in the list to wait for its time.
15928                        addProcessToGcListLocked(proc);
15929                        break;
15930                    }
15931                }
15932            }
15933
15934            scheduleAppGcsLocked();
15935        }
15936    }
15937
15938    /**
15939     * If all looks good, perform GCs on all processes waiting for them.
15940     */
15941    final void performAppGcsIfAppropriateLocked() {
15942        if (canGcNowLocked()) {
15943            performAppGcsLocked();
15944            return;
15945        }
15946        // Still not idle, wait some more.
15947        scheduleAppGcsLocked();
15948    }
15949
15950    /**
15951     * Schedule the execution of all pending app GCs.
15952     */
15953    final void scheduleAppGcsLocked() {
15954        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15955
15956        if (mProcessesToGc.size() > 0) {
15957            // Schedule a GC for the time to the next process.
15958            ProcessRecord proc = mProcessesToGc.get(0);
15959            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15960
15961            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15962            long now = SystemClock.uptimeMillis();
15963            if (when < (now+GC_TIMEOUT)) {
15964                when = now + GC_TIMEOUT;
15965            }
15966            mHandler.sendMessageAtTime(msg, when);
15967        }
15968    }
15969
15970    /**
15971     * Add a process to the array of processes waiting to be GCed.  Keeps the
15972     * list in sorted order by the last GC time.  The process can't already be
15973     * on the list.
15974     */
15975    final void addProcessToGcListLocked(ProcessRecord proc) {
15976        boolean added = false;
15977        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15978            if (mProcessesToGc.get(i).lastRequestedGc <
15979                    proc.lastRequestedGc) {
15980                added = true;
15981                mProcessesToGc.add(i+1, proc);
15982                break;
15983            }
15984        }
15985        if (!added) {
15986            mProcessesToGc.add(0, proc);
15987        }
15988    }
15989
15990    /**
15991     * Set up to ask a process to GC itself.  This will either do it
15992     * immediately, or put it on the list of processes to gc the next
15993     * time things are idle.
15994     */
15995    final void scheduleAppGcLocked(ProcessRecord app) {
15996        long now = SystemClock.uptimeMillis();
15997        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15998            return;
15999        }
16000        if (!mProcessesToGc.contains(app)) {
16001            addProcessToGcListLocked(app);
16002            scheduleAppGcsLocked();
16003        }
16004    }
16005
16006    final void checkExcessivePowerUsageLocked(boolean doKills) {
16007        updateCpuStatsNow();
16008
16009        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16010        boolean doWakeKills = doKills;
16011        boolean doCpuKills = doKills;
16012        if (mLastPowerCheckRealtime == 0) {
16013            doWakeKills = false;
16014        }
16015        if (mLastPowerCheckUptime == 0) {
16016            doCpuKills = false;
16017        }
16018        if (stats.isScreenOn()) {
16019            doWakeKills = false;
16020        }
16021        final long curRealtime = SystemClock.elapsedRealtime();
16022        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16023        final long curUptime = SystemClock.uptimeMillis();
16024        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16025        mLastPowerCheckRealtime = curRealtime;
16026        mLastPowerCheckUptime = curUptime;
16027        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16028            doWakeKills = false;
16029        }
16030        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16031            doCpuKills = false;
16032        }
16033        int i = mLruProcesses.size();
16034        while (i > 0) {
16035            i--;
16036            ProcessRecord app = mLruProcesses.get(i);
16037            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16038                long wtime;
16039                synchronized (stats) {
16040                    wtime = stats.getProcessWakeTime(app.info.uid,
16041                            app.pid, curRealtime);
16042                }
16043                long wtimeUsed = wtime - app.lastWakeTime;
16044                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16045                if (DEBUG_POWER) {
16046                    StringBuilder sb = new StringBuilder(128);
16047                    sb.append("Wake for ");
16048                    app.toShortString(sb);
16049                    sb.append(": over ");
16050                    TimeUtils.formatDuration(realtimeSince, sb);
16051                    sb.append(" used ");
16052                    TimeUtils.formatDuration(wtimeUsed, sb);
16053                    sb.append(" (");
16054                    sb.append((wtimeUsed*100)/realtimeSince);
16055                    sb.append("%)");
16056                    Slog.i(TAG, sb.toString());
16057                    sb.setLength(0);
16058                    sb.append("CPU for ");
16059                    app.toShortString(sb);
16060                    sb.append(": over ");
16061                    TimeUtils.formatDuration(uptimeSince, sb);
16062                    sb.append(" used ");
16063                    TimeUtils.formatDuration(cputimeUsed, sb);
16064                    sb.append(" (");
16065                    sb.append((cputimeUsed*100)/uptimeSince);
16066                    sb.append("%)");
16067                    Slog.i(TAG, sb.toString());
16068                }
16069                // If a process has held a wake lock for more
16070                // than 50% of the time during this period,
16071                // that sounds bad.  Kill!
16072                if (doWakeKills && realtimeSince > 0
16073                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16074                    synchronized (stats) {
16075                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16076                                realtimeSince, wtimeUsed);
16077                    }
16078                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
16079                            + " during " + realtimeSince);
16080                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16081                } else if (doCpuKills && uptimeSince > 0
16082                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16083                    synchronized (stats) {
16084                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16085                                uptimeSince, cputimeUsed);
16086                    }
16087                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
16088                            + " during " + uptimeSince);
16089                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16090                } else {
16091                    app.lastWakeTime = wtime;
16092                    app.lastCpuTime = app.curCpuTime;
16093                }
16094            }
16095        }
16096    }
16097
16098    private final boolean applyOomAdjLocked(ProcessRecord app,
16099            ProcessRecord TOP_APP, boolean doingAll, long now) {
16100        boolean success = true;
16101
16102        if (app.curRawAdj != app.setRawAdj) {
16103            app.setRawAdj = app.curRawAdj;
16104        }
16105
16106        int changes = 0;
16107
16108        if (app.curAdj != app.setAdj) {
16109            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16110            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16111                TAG, "Set " + app.pid + " " + app.processName +
16112                " adj " + app.curAdj + ": " + app.adjType);
16113            app.setAdj = app.curAdj;
16114        }
16115
16116        if (app.setSchedGroup != app.curSchedGroup) {
16117            app.setSchedGroup = app.curSchedGroup;
16118            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16119                    "Setting process group of " + app.processName
16120                    + " to " + app.curSchedGroup);
16121            if (app.waitingToKill != null &&
16122                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16123                killUnneededProcessLocked(app, app.waitingToKill);
16124                success = false;
16125            } else {
16126                if (true) {
16127                    long oldId = Binder.clearCallingIdentity();
16128                    try {
16129                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16130                    } catch (Exception e) {
16131                        Slog.w(TAG, "Failed setting process group of " + app.pid
16132                                + " to " + app.curSchedGroup);
16133                        e.printStackTrace();
16134                    } finally {
16135                        Binder.restoreCallingIdentity(oldId);
16136                    }
16137                } else {
16138                    if (app.thread != null) {
16139                        try {
16140                            app.thread.setSchedulingGroup(app.curSchedGroup);
16141                        } catch (RemoteException e) {
16142                        }
16143                    }
16144                }
16145                Process.setSwappiness(app.pid,
16146                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16147            }
16148        }
16149        if (app.repForegroundActivities != app.foregroundActivities) {
16150            app.repForegroundActivities = app.foregroundActivities;
16151            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16152        }
16153        if (app.repProcState != app.curProcState) {
16154            app.repProcState = app.curProcState;
16155            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16156            if (app.thread != null) {
16157                try {
16158                    if (false) {
16159                        //RuntimeException h = new RuntimeException("here");
16160                        Slog.i(TAG, "Sending new process state " + app.repProcState
16161                                + " to " + app /*, h*/);
16162                    }
16163                    app.thread.setProcessState(app.repProcState);
16164                } catch (RemoteException e) {
16165                }
16166            }
16167        }
16168        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16169                app.setProcState)) {
16170            app.lastStateTime = now;
16171            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16172                    isSleeping(), now);
16173            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16174                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16175                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16176                    + (app.nextPssTime-now) + ": " + app);
16177        } else {
16178            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16179                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16180                requestPssLocked(app, app.setProcState);
16181                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16182                        isSleeping(), now);
16183            } else if (false && DEBUG_PSS) {
16184                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16185            }
16186        }
16187        if (app.setProcState != app.curProcState) {
16188            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16189                    "Proc state change of " + app.processName
16190                    + " to " + app.curProcState);
16191            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
16192            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
16193            if (setImportant && !curImportant) {
16194                // This app is no longer something we consider important enough to allow to
16195                // use arbitrary amounts of battery power.  Note
16196                // its current wake lock time to later know to kill it if
16197                // it is not behaving well.
16198                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16199                synchronized (stats) {
16200                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
16201                            app.pid, SystemClock.elapsedRealtime());
16202                }
16203                app.lastCpuTime = app.curCpuTime;
16204
16205            }
16206            app.setProcState = app.curProcState;
16207            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16208                app.notCachedSinceIdle = false;
16209            }
16210            if (!doingAll) {
16211                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
16212            } else {
16213                app.procStateChanged = true;
16214            }
16215        }
16216
16217        if (changes != 0) {
16218            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16219            int i = mPendingProcessChanges.size()-1;
16220            ProcessChangeItem item = null;
16221            while (i >= 0) {
16222                item = mPendingProcessChanges.get(i);
16223                if (item.pid == app.pid) {
16224                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16225                    break;
16226                }
16227                i--;
16228            }
16229            if (i < 0) {
16230                // No existing item in pending changes; need a new one.
16231                final int NA = mAvailProcessChanges.size();
16232                if (NA > 0) {
16233                    item = mAvailProcessChanges.remove(NA-1);
16234                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16235                } else {
16236                    item = new ProcessChangeItem();
16237                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16238                }
16239                item.changes = 0;
16240                item.pid = app.pid;
16241                item.uid = app.info.uid;
16242                if (mPendingProcessChanges.size() == 0) {
16243                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16244                            "*** Enqueueing dispatch processes changed!");
16245                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16246                }
16247                mPendingProcessChanges.add(item);
16248            }
16249            item.changes |= changes;
16250            item.processState = app.repProcState;
16251            item.foregroundActivities = app.repForegroundActivities;
16252            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16253                    + Integer.toHexString(System.identityHashCode(item))
16254                    + " " + app.toShortString() + ": changes=" + item.changes
16255                    + " procState=" + item.processState
16256                    + " foreground=" + item.foregroundActivities
16257                    + " type=" + app.adjType + " source=" + app.adjSource
16258                    + " target=" + app.adjTarget);
16259        }
16260
16261        return success;
16262    }
16263
16264    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
16265        if (proc.thread != null) {
16266            if (proc.baseProcessTracker != null) {
16267                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16268            }
16269            if (proc.repProcState >= 0) {
16270                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
16271                        proc.repProcState);
16272            }
16273        }
16274    }
16275
16276    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16277            ProcessRecord TOP_APP, boolean doingAll, long now) {
16278        if (app.thread == null) {
16279            return false;
16280        }
16281
16282        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16283
16284        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
16285    }
16286
16287    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16288            boolean oomAdj) {
16289        if (isForeground != proc.foregroundServices) {
16290            proc.foregroundServices = isForeground;
16291            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16292                    proc.info.uid);
16293            if (isForeground) {
16294                if (curProcs == null) {
16295                    curProcs = new ArrayList<ProcessRecord>();
16296                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16297                }
16298                if (!curProcs.contains(proc)) {
16299                    curProcs.add(proc);
16300                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16301                            proc.info.packageName, proc.info.uid);
16302                }
16303            } else {
16304                if (curProcs != null) {
16305                    if (curProcs.remove(proc)) {
16306                        mBatteryStatsService.noteEvent(
16307                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16308                                proc.info.packageName, proc.info.uid);
16309                        if (curProcs.size() <= 0) {
16310                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16311                        }
16312                    }
16313                }
16314            }
16315            if (oomAdj) {
16316                updateOomAdjLocked();
16317            }
16318        }
16319    }
16320
16321    private final ActivityRecord resumedAppLocked() {
16322        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16323        String pkg;
16324        int uid;
16325        if (act != null) {
16326            pkg = act.packageName;
16327            uid = act.info.applicationInfo.uid;
16328        } else {
16329            pkg = null;
16330            uid = -1;
16331        }
16332        // Has the UID or resumed package name changed?
16333        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16334                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16335            if (mCurResumedPackage != null) {
16336                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16337                        mCurResumedPackage, mCurResumedUid);
16338            }
16339            mCurResumedPackage = pkg;
16340            mCurResumedUid = uid;
16341            if (mCurResumedPackage != null) {
16342                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16343                        mCurResumedPackage, mCurResumedUid);
16344            }
16345        }
16346        return act;
16347    }
16348
16349    final boolean updateOomAdjLocked(ProcessRecord app) {
16350        final ActivityRecord TOP_ACT = resumedAppLocked();
16351        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16352        final boolean wasCached = app.cached;
16353
16354        mAdjSeq++;
16355
16356        // This is the desired cached adjusment we want to tell it to use.
16357        // If our app is currently cached, we know it, and that is it.  Otherwise,
16358        // we don't know it yet, and it needs to now be cached we will then
16359        // need to do a complete oom adj.
16360        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16361                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16362        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16363                SystemClock.uptimeMillis());
16364        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16365            // Changed to/from cached state, so apps after it in the LRU
16366            // list may also be changed.
16367            updateOomAdjLocked();
16368        }
16369        return success;
16370    }
16371
16372    final void updateOomAdjLocked() {
16373        final ActivityRecord TOP_ACT = resumedAppLocked();
16374        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16375        final long now = SystemClock.uptimeMillis();
16376        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16377        final int N = mLruProcesses.size();
16378
16379        if (false) {
16380            RuntimeException e = new RuntimeException();
16381            e.fillInStackTrace();
16382            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16383        }
16384
16385        mAdjSeq++;
16386        mNewNumServiceProcs = 0;
16387        mNewNumAServiceProcs = 0;
16388
16389        final int emptyProcessLimit;
16390        final int cachedProcessLimit;
16391        if (mProcessLimit <= 0) {
16392            emptyProcessLimit = cachedProcessLimit = 0;
16393        } else if (mProcessLimit == 1) {
16394            emptyProcessLimit = 1;
16395            cachedProcessLimit = 0;
16396        } else {
16397            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16398            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16399        }
16400
16401        // Let's determine how many processes we have running vs.
16402        // how many slots we have for background processes; we may want
16403        // to put multiple processes in a slot of there are enough of
16404        // them.
16405        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16406                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16407        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16408        if (numEmptyProcs > cachedProcessLimit) {
16409            // If there are more empty processes than our limit on cached
16410            // processes, then use the cached process limit for the factor.
16411            // This ensures that the really old empty processes get pushed
16412            // down to the bottom, so if we are running low on memory we will
16413            // have a better chance at keeping around more cached processes
16414            // instead of a gazillion empty processes.
16415            numEmptyProcs = cachedProcessLimit;
16416        }
16417        int emptyFactor = numEmptyProcs/numSlots;
16418        if (emptyFactor < 1) emptyFactor = 1;
16419        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16420        if (cachedFactor < 1) cachedFactor = 1;
16421        int stepCached = 0;
16422        int stepEmpty = 0;
16423        int numCached = 0;
16424        int numEmpty = 0;
16425        int numTrimming = 0;
16426
16427        mNumNonCachedProcs = 0;
16428        mNumCachedHiddenProcs = 0;
16429
16430        // First update the OOM adjustment for each of the
16431        // application processes based on their current state.
16432        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16433        int nextCachedAdj = curCachedAdj+1;
16434        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16435        int nextEmptyAdj = curEmptyAdj+2;
16436        for (int i=N-1; i>=0; i--) {
16437            ProcessRecord app = mLruProcesses.get(i);
16438            if (!app.killedByAm && app.thread != null) {
16439                app.procStateChanged = false;
16440                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16441
16442                // If we haven't yet assigned the final cached adj
16443                // to the process, do that now.
16444                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16445                    switch (app.curProcState) {
16446                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16447                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16448                            // This process is a cached process holding activities...
16449                            // assign it the next cached value for that type, and then
16450                            // step that cached level.
16451                            app.curRawAdj = curCachedAdj;
16452                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16453                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16454                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16455                                    + ")");
16456                            if (curCachedAdj != nextCachedAdj) {
16457                                stepCached++;
16458                                if (stepCached >= cachedFactor) {
16459                                    stepCached = 0;
16460                                    curCachedAdj = nextCachedAdj;
16461                                    nextCachedAdj += 2;
16462                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16463                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16464                                    }
16465                                }
16466                            }
16467                            break;
16468                        default:
16469                            // For everything else, assign next empty cached process
16470                            // level and bump that up.  Note that this means that
16471                            // long-running services that have dropped down to the
16472                            // cached level will be treated as empty (since their process
16473                            // state is still as a service), which is what we want.
16474                            app.curRawAdj = curEmptyAdj;
16475                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16476                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16477                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16478                                    + ")");
16479                            if (curEmptyAdj != nextEmptyAdj) {
16480                                stepEmpty++;
16481                                if (stepEmpty >= emptyFactor) {
16482                                    stepEmpty = 0;
16483                                    curEmptyAdj = nextEmptyAdj;
16484                                    nextEmptyAdj += 2;
16485                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16486                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16487                                    }
16488                                }
16489                            }
16490                            break;
16491                    }
16492                }
16493
16494                applyOomAdjLocked(app, TOP_APP, true, now);
16495
16496                // Count the number of process types.
16497                switch (app.curProcState) {
16498                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16499                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16500                        mNumCachedHiddenProcs++;
16501                        numCached++;
16502                        if (numCached > cachedProcessLimit) {
16503                            killUnneededProcessLocked(app, "cached #" + numCached);
16504                        }
16505                        break;
16506                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16507                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16508                                && app.lastActivityTime < oldTime) {
16509                            killUnneededProcessLocked(app, "empty for "
16510                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16511                                    / 1000) + "s");
16512                        } else {
16513                            numEmpty++;
16514                            if (numEmpty > emptyProcessLimit) {
16515                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16516                            }
16517                        }
16518                        break;
16519                    default:
16520                        mNumNonCachedProcs++;
16521                        break;
16522                }
16523
16524                if (app.isolated && app.services.size() <= 0) {
16525                    // If this is an isolated process, and there are no
16526                    // services running in it, then the process is no longer
16527                    // needed.  We agressively kill these because we can by
16528                    // definition not re-use the same process again, and it is
16529                    // good to avoid having whatever code was running in them
16530                    // left sitting around after no longer needed.
16531                    killUnneededProcessLocked(app, "isolated not needed");
16532                }
16533
16534                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16535                        && !app.killedByAm) {
16536                    numTrimming++;
16537                }
16538            }
16539        }
16540
16541        mNumServiceProcs = mNewNumServiceProcs;
16542
16543        // Now determine the memory trimming level of background processes.
16544        // Unfortunately we need to start at the back of the list to do this
16545        // properly.  We only do this if the number of background apps we
16546        // are managing to keep around is less than half the maximum we desire;
16547        // if we are keeping a good number around, we'll let them use whatever
16548        // memory they want.
16549        final int numCachedAndEmpty = numCached + numEmpty;
16550        int memFactor;
16551        if (numCached <= ProcessList.TRIM_CACHED_APPS
16552                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16553            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16554                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16555            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16556                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16557            } else {
16558                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16559            }
16560        } else {
16561            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16562        }
16563        // We always allow the memory level to go up (better).  We only allow it to go
16564        // down if we are in a state where that is allowed, *and* the total number of processes
16565        // has gone down since last time.
16566        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16567                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16568                + " last=" + mLastNumProcesses);
16569        if (memFactor > mLastMemoryLevel) {
16570            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16571                memFactor = mLastMemoryLevel;
16572                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16573            }
16574        }
16575        mLastMemoryLevel = memFactor;
16576        mLastNumProcesses = mLruProcesses.size();
16577        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16578        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16579        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16580            if (mLowRamStartTime == 0) {
16581                mLowRamStartTime = now;
16582            }
16583            int step = 0;
16584            int fgTrimLevel;
16585            switch (memFactor) {
16586                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16587                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16588                    break;
16589                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16590                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16591                    break;
16592                default:
16593                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16594                    break;
16595            }
16596            int factor = numTrimming/3;
16597            int minFactor = 2;
16598            if (mHomeProcess != null) minFactor++;
16599            if (mPreviousProcess != null) minFactor++;
16600            if (factor < minFactor) factor = minFactor;
16601            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16602            for (int i=N-1; i>=0; i--) {
16603                ProcessRecord app = mLruProcesses.get(i);
16604                if (allChanged || app.procStateChanged) {
16605                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16606                    app.procStateChanged = false;
16607                }
16608                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16609                        && !app.killedByAm) {
16610                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16611                        try {
16612                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16613                                    "Trimming memory of " + app.processName
16614                                    + " to " + curLevel);
16615                            app.thread.scheduleTrimMemory(curLevel);
16616                        } catch (RemoteException e) {
16617                        }
16618                        if (false) {
16619                            // For now we won't do this; our memory trimming seems
16620                            // to be good enough at this point that destroying
16621                            // activities causes more harm than good.
16622                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16623                                    && app != mHomeProcess && app != mPreviousProcess) {
16624                                // Need to do this on its own message because the stack may not
16625                                // be in a consistent state at this point.
16626                                // For these apps we will also finish their activities
16627                                // to help them free memory.
16628                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16629                            }
16630                        }
16631                    }
16632                    app.trimMemoryLevel = curLevel;
16633                    step++;
16634                    if (step >= factor) {
16635                        step = 0;
16636                        switch (curLevel) {
16637                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16638                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16639                                break;
16640                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16641                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16642                                break;
16643                        }
16644                    }
16645                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16646                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16647                            && app.thread != null) {
16648                        try {
16649                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16650                                    "Trimming memory of heavy-weight " + app.processName
16651                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16652                            app.thread.scheduleTrimMemory(
16653                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16654                        } catch (RemoteException e) {
16655                        }
16656                    }
16657                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16658                } else {
16659                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16660                            || app.systemNoUi) && app.pendingUiClean) {
16661                        // If this application is now in the background and it
16662                        // had done UI, then give it the special trim level to
16663                        // have it free UI resources.
16664                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16665                        if (app.trimMemoryLevel < level && app.thread != null) {
16666                            try {
16667                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16668                                        "Trimming memory of bg-ui " + app.processName
16669                                        + " to " + level);
16670                                app.thread.scheduleTrimMemory(level);
16671                            } catch (RemoteException e) {
16672                            }
16673                        }
16674                        app.pendingUiClean = false;
16675                    }
16676                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16677                        try {
16678                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16679                                    "Trimming memory of fg " + app.processName
16680                                    + " to " + fgTrimLevel);
16681                            app.thread.scheduleTrimMemory(fgTrimLevel);
16682                        } catch (RemoteException e) {
16683                        }
16684                    }
16685                    app.trimMemoryLevel = fgTrimLevel;
16686                }
16687            }
16688        } else {
16689            if (mLowRamStartTime != 0) {
16690                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16691                mLowRamStartTime = 0;
16692            }
16693            for (int i=N-1; i>=0; i--) {
16694                ProcessRecord app = mLruProcesses.get(i);
16695                if (allChanged || app.procStateChanged) {
16696                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16697                    app.procStateChanged = false;
16698                }
16699                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16700                        || app.systemNoUi) && app.pendingUiClean) {
16701                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16702                            && app.thread != null) {
16703                        try {
16704                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16705                                    "Trimming memory of ui hidden " + app.processName
16706                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16707                            app.thread.scheduleTrimMemory(
16708                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16709                        } catch (RemoteException e) {
16710                        }
16711                    }
16712                    app.pendingUiClean = false;
16713                }
16714                app.trimMemoryLevel = 0;
16715            }
16716        }
16717
16718        if (mAlwaysFinishActivities) {
16719            // Need to do this on its own message because the stack may not
16720            // be in a consistent state at this point.
16721            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16722        }
16723
16724        if (allChanged) {
16725            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16726        }
16727
16728        if (mProcessStats.shouldWriteNowLocked(now)) {
16729            mHandler.post(new Runnable() {
16730                @Override public void run() {
16731                    synchronized (ActivityManagerService.this) {
16732                        mProcessStats.writeStateAsyncLocked();
16733                    }
16734                }
16735            });
16736        }
16737
16738        if (DEBUG_OOM_ADJ) {
16739            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16740        }
16741    }
16742
16743    final void trimApplications() {
16744        synchronized (this) {
16745            int i;
16746
16747            // First remove any unused application processes whose package
16748            // has been removed.
16749            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16750                final ProcessRecord app = mRemovedProcesses.get(i);
16751                if (app.activities.size() == 0
16752                        && app.curReceiver == null && app.services.size() == 0) {
16753                    Slog.i(
16754                        TAG, "Exiting empty application process "
16755                        + app.processName + " ("
16756                        + (app.thread != null ? app.thread.asBinder() : null)
16757                        + ")\n");
16758                    if (app.pid > 0 && app.pid != MY_PID) {
16759                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16760                                app.processName, app.setAdj, "empty");
16761                        app.killedByAm = true;
16762                        Process.killProcessQuiet(app.pid);
16763                        Process.killProcessGroup(app.info.uid, app.pid);
16764                    } else {
16765                        try {
16766                            app.thread.scheduleExit();
16767                        } catch (Exception e) {
16768                            // Ignore exceptions.
16769                        }
16770                    }
16771                    cleanUpApplicationRecordLocked(app, false, true, -1);
16772                    mRemovedProcesses.remove(i);
16773
16774                    if (app.persistent) {
16775                        addAppLocked(app.info, false, null /* ABI override */);
16776                    }
16777                }
16778            }
16779
16780            // Now update the oom adj for all processes.
16781            updateOomAdjLocked();
16782        }
16783    }
16784
16785    /** This method sends the specified signal to each of the persistent apps */
16786    public void signalPersistentProcesses(int sig) throws RemoteException {
16787        if (sig != Process.SIGNAL_USR1) {
16788            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16789        }
16790
16791        synchronized (this) {
16792            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16793                    != PackageManager.PERMISSION_GRANTED) {
16794                throw new SecurityException("Requires permission "
16795                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16796            }
16797
16798            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16799                ProcessRecord r = mLruProcesses.get(i);
16800                if (r.thread != null && r.persistent) {
16801                    Process.sendSignal(r.pid, sig);
16802                }
16803            }
16804        }
16805    }
16806
16807    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16808        if (proc == null || proc == mProfileProc) {
16809            proc = mProfileProc;
16810            path = mProfileFile;
16811            profileType = mProfileType;
16812            clearProfilerLocked();
16813        }
16814        if (proc == null) {
16815            return;
16816        }
16817        try {
16818            proc.thread.profilerControl(false, path, null, profileType);
16819        } catch (RemoteException e) {
16820            throw new IllegalStateException("Process disappeared");
16821        }
16822    }
16823
16824    private void clearProfilerLocked() {
16825        if (mProfileFd != null) {
16826            try {
16827                mProfileFd.close();
16828            } catch (IOException e) {
16829            }
16830        }
16831        mProfileApp = null;
16832        mProfileProc = null;
16833        mProfileFile = null;
16834        mProfileType = 0;
16835        mAutoStopProfiler = false;
16836    }
16837
16838    public boolean profileControl(String process, int userId, boolean start,
16839            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16840
16841        try {
16842            synchronized (this) {
16843                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16844                // its own permission.
16845                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16846                        != PackageManager.PERMISSION_GRANTED) {
16847                    throw new SecurityException("Requires permission "
16848                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16849                }
16850
16851                if (start && fd == null) {
16852                    throw new IllegalArgumentException("null fd");
16853                }
16854
16855                ProcessRecord proc = null;
16856                if (process != null) {
16857                    proc = findProcessLocked(process, userId, "profileControl");
16858                }
16859
16860                if (start && (proc == null || proc.thread == null)) {
16861                    throw new IllegalArgumentException("Unknown process: " + process);
16862                }
16863
16864                if (start) {
16865                    stopProfilerLocked(null, null, 0);
16866                    setProfileApp(proc.info, proc.processName, path, fd, false);
16867                    mProfileProc = proc;
16868                    mProfileType = profileType;
16869                    try {
16870                        fd = fd.dup();
16871                    } catch (IOException e) {
16872                        fd = null;
16873                    }
16874                    proc.thread.profilerControl(start, path, fd, profileType);
16875                    fd = null;
16876                    mProfileFd = null;
16877                } else {
16878                    stopProfilerLocked(proc, path, profileType);
16879                    if (fd != null) {
16880                        try {
16881                            fd.close();
16882                        } catch (IOException e) {
16883                        }
16884                    }
16885                }
16886
16887                return true;
16888            }
16889        } catch (RemoteException e) {
16890            throw new IllegalStateException("Process disappeared");
16891        } finally {
16892            if (fd != null) {
16893                try {
16894                    fd.close();
16895                } catch (IOException e) {
16896                }
16897            }
16898        }
16899    }
16900
16901    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16902        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16903                userId, true, ALLOW_FULL_ONLY, callName, null);
16904        ProcessRecord proc = null;
16905        try {
16906            int pid = Integer.parseInt(process);
16907            synchronized (mPidsSelfLocked) {
16908                proc = mPidsSelfLocked.get(pid);
16909            }
16910        } catch (NumberFormatException e) {
16911        }
16912
16913        if (proc == null) {
16914            ArrayMap<String, SparseArray<ProcessRecord>> all
16915                    = mProcessNames.getMap();
16916            SparseArray<ProcessRecord> procs = all.get(process);
16917            if (procs != null && procs.size() > 0) {
16918                proc = procs.valueAt(0);
16919                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16920                    for (int i=1; i<procs.size(); i++) {
16921                        ProcessRecord thisProc = procs.valueAt(i);
16922                        if (thisProc.userId == userId) {
16923                            proc = thisProc;
16924                            break;
16925                        }
16926                    }
16927                }
16928            }
16929        }
16930
16931        return proc;
16932    }
16933
16934    public boolean dumpHeap(String process, int userId, boolean managed,
16935            String path, ParcelFileDescriptor fd) throws RemoteException {
16936
16937        try {
16938            synchronized (this) {
16939                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16940                // its own permission (same as profileControl).
16941                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16942                        != PackageManager.PERMISSION_GRANTED) {
16943                    throw new SecurityException("Requires permission "
16944                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16945                }
16946
16947                if (fd == null) {
16948                    throw new IllegalArgumentException("null fd");
16949                }
16950
16951                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16952                if (proc == null || proc.thread == null) {
16953                    throw new IllegalArgumentException("Unknown process: " + process);
16954                }
16955
16956                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16957                if (!isDebuggable) {
16958                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16959                        throw new SecurityException("Process not debuggable: " + proc);
16960                    }
16961                }
16962
16963                proc.thread.dumpHeap(managed, path, fd);
16964                fd = null;
16965                return true;
16966            }
16967        } catch (RemoteException e) {
16968            throw new IllegalStateException("Process disappeared");
16969        } finally {
16970            if (fd != null) {
16971                try {
16972                    fd.close();
16973                } catch (IOException e) {
16974                }
16975            }
16976        }
16977    }
16978
16979    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16980    public void monitor() {
16981        synchronized (this) { }
16982    }
16983
16984    void onCoreSettingsChange(Bundle settings) {
16985        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16986            ProcessRecord processRecord = mLruProcesses.get(i);
16987            try {
16988                if (processRecord.thread != null) {
16989                    processRecord.thread.setCoreSettings(settings);
16990                }
16991            } catch (RemoteException re) {
16992                /* ignore */
16993            }
16994        }
16995    }
16996
16997    // Multi-user methods
16998
16999    /**
17000     * Start user, if its not already running, but don't bring it to foreground.
17001     */
17002    @Override
17003    public boolean startUserInBackground(final int userId) {
17004        return startUser(userId, /* foreground */ false);
17005    }
17006
17007    /**
17008     * Refreshes the list of users related to the current user when either a
17009     * user switch happens or when a new related user is started in the
17010     * background.
17011     */
17012    private void updateCurrentProfileIdsLocked() {
17013        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17014                mCurrentUserId, false /* enabledOnly */);
17015        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17016        for (int i = 0; i < currentProfileIds.length; i++) {
17017            currentProfileIds[i] = profiles.get(i).id;
17018        }
17019        mCurrentProfileIds = currentProfileIds;
17020
17021        synchronized (mUserProfileGroupIdsSelfLocked) {
17022            mUserProfileGroupIdsSelfLocked.clear();
17023            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17024            for (int i = 0; i < users.size(); i++) {
17025                UserInfo user = users.get(i);
17026                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17027                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17028                }
17029            }
17030        }
17031    }
17032
17033    private Set getProfileIdsLocked(int userId) {
17034        Set userIds = new HashSet<Integer>();
17035        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17036                userId, false /* enabledOnly */);
17037        for (UserInfo user : profiles) {
17038            userIds.add(Integer.valueOf(user.id));
17039        }
17040        return userIds;
17041    }
17042
17043    @Override
17044    public boolean switchUser(final int userId) {
17045        return startUser(userId, /* foregound */ true);
17046    }
17047
17048    private boolean startUser(final int userId, boolean foreground) {
17049        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17050                != PackageManager.PERMISSION_GRANTED) {
17051            String msg = "Permission Denial: switchUser() from pid="
17052                    + Binder.getCallingPid()
17053                    + ", uid=" + Binder.getCallingUid()
17054                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17055            Slog.w(TAG, msg);
17056            throw new SecurityException(msg);
17057        }
17058
17059        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17060
17061        final long ident = Binder.clearCallingIdentity();
17062        try {
17063            synchronized (this) {
17064                final int oldUserId = mCurrentUserId;
17065                if (oldUserId == userId) {
17066                    return true;
17067                }
17068
17069                mStackSupervisor.setLockTaskModeLocked(null, false);
17070
17071                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17072                if (userInfo == null) {
17073                    Slog.w(TAG, "No user info for user #" + userId);
17074                    return false;
17075                }
17076
17077                if (foreground) {
17078                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17079                            R.anim.screen_user_enter);
17080                }
17081
17082                boolean needStart = false;
17083
17084                // If the user we are switching to is not currently started, then
17085                // we need to start it now.
17086                if (mStartedUsers.get(userId) == null) {
17087                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17088                    updateStartedUserArrayLocked();
17089                    needStart = true;
17090                }
17091
17092                final Integer userIdInt = Integer.valueOf(userId);
17093                mUserLru.remove(userIdInt);
17094                mUserLru.add(userIdInt);
17095
17096                if (foreground) {
17097                    mCurrentUserId = userId;
17098                    updateCurrentProfileIdsLocked();
17099                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17100                    // Once the internal notion of the active user has switched, we lock the device
17101                    // with the option to show the user switcher on the keyguard.
17102                    mWindowManager.lockNow(null);
17103                } else {
17104                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17105                    updateCurrentProfileIdsLocked();
17106                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17107                    mUserLru.remove(currentUserIdInt);
17108                    mUserLru.add(currentUserIdInt);
17109                }
17110
17111                final UserStartedState uss = mStartedUsers.get(userId);
17112
17113                // Make sure user is in the started state.  If it is currently
17114                // stopping, we need to knock that off.
17115                if (uss.mState == UserStartedState.STATE_STOPPING) {
17116                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17117                    // so we can just fairly silently bring the user back from
17118                    // the almost-dead.
17119                    uss.mState = UserStartedState.STATE_RUNNING;
17120                    updateStartedUserArrayLocked();
17121                    needStart = true;
17122                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17123                    // This means ACTION_SHUTDOWN has been sent, so we will
17124                    // need to treat this as a new boot of the user.
17125                    uss.mState = UserStartedState.STATE_BOOTING;
17126                    updateStartedUserArrayLocked();
17127                    needStart = true;
17128                }
17129
17130                if (uss.mState == UserStartedState.STATE_BOOTING) {
17131                    // Booting up a new user, need to tell system services about it.
17132                    // Note that this is on the same handler as scheduling of broadcasts,
17133                    // which is important because it needs to go first.
17134                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
17135                }
17136
17137                if (foreground) {
17138                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
17139                            oldUserId));
17140                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17141                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17142                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
17143                            oldUserId, userId, uss));
17144                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
17145                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
17146                }
17147
17148                if (needStart) {
17149                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
17150                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17151                            | Intent.FLAG_RECEIVER_FOREGROUND);
17152                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17153                    broadcastIntentLocked(null, null, intent,
17154                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17155                            false, false, MY_PID, Process.SYSTEM_UID, userId);
17156                }
17157
17158                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
17159                    if (userId != UserHandle.USER_OWNER) {
17160                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
17161                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17162                        broadcastIntentLocked(null, null, intent, null,
17163                                new IIntentReceiver.Stub() {
17164                                    public void performReceive(Intent intent, int resultCode,
17165                                            String data, Bundle extras, boolean ordered,
17166                                            boolean sticky, int sendingUser) {
17167                                        userInitialized(uss, userId);
17168                                    }
17169                                }, 0, null, null, null, AppOpsManager.OP_NONE,
17170                                true, false, MY_PID, Process.SYSTEM_UID,
17171                                userId);
17172                        uss.initializing = true;
17173                    } else {
17174                        getUserManagerLocked().makeInitialized(userInfo.id);
17175                    }
17176                }
17177
17178                if (foreground) {
17179                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
17180                    if (homeInFront) {
17181                        startHomeActivityLocked(userId);
17182                    } else {
17183                        mStackSupervisor.resumeTopActivitiesLocked();
17184                    }
17185                    EventLogTags.writeAmSwitchUser(userId);
17186                    getUserManagerLocked().userForeground(userId);
17187                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
17188                } else {
17189                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
17190                }
17191
17192                if (needStart) {
17193                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
17194                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17195                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17196                    broadcastIntentLocked(null, null, intent,
17197                            null, new IIntentReceiver.Stub() {
17198                                @Override
17199                                public void performReceive(Intent intent, int resultCode, String data,
17200                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
17201                                        throws RemoteException {
17202                                }
17203                            }, 0, null, null,
17204                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17205                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17206                }
17207            }
17208        } finally {
17209            Binder.restoreCallingIdentity(ident);
17210        }
17211
17212        return true;
17213    }
17214
17215    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
17216        long ident = Binder.clearCallingIdentity();
17217        try {
17218            Intent intent;
17219            if (oldUserId >= 0) {
17220                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
17221                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
17222                int count = profiles.size();
17223                for (int i = 0; i < count; i++) {
17224                    int profileUserId = profiles.get(i).id;
17225                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
17226                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17227                            | Intent.FLAG_RECEIVER_FOREGROUND);
17228                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17229                    broadcastIntentLocked(null, null, intent,
17230                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17231                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17232                }
17233            }
17234            if (newUserId >= 0) {
17235                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
17236                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
17237                int count = profiles.size();
17238                for (int i = 0; i < count; i++) {
17239                    int profileUserId = profiles.get(i).id;
17240                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
17241                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17242                            | Intent.FLAG_RECEIVER_FOREGROUND);
17243                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17244                    broadcastIntentLocked(null, null, intent,
17245                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17246                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17247                }
17248                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17249                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17250                        | Intent.FLAG_RECEIVER_FOREGROUND);
17251                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17252                broadcastIntentLocked(null, null, intent,
17253                        null, null, 0, null, null,
17254                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17255                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17256            }
17257        } finally {
17258            Binder.restoreCallingIdentity(ident);
17259        }
17260    }
17261
17262    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17263            final int newUserId) {
17264        final int N = mUserSwitchObservers.beginBroadcast();
17265        if (N > 0) {
17266            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17267                int mCount = 0;
17268                @Override
17269                public void sendResult(Bundle data) throws RemoteException {
17270                    synchronized (ActivityManagerService.this) {
17271                        if (mCurUserSwitchCallback == this) {
17272                            mCount++;
17273                            if (mCount == N) {
17274                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17275                            }
17276                        }
17277                    }
17278                }
17279            };
17280            synchronized (this) {
17281                uss.switching = true;
17282                mCurUserSwitchCallback = callback;
17283            }
17284            for (int i=0; i<N; i++) {
17285                try {
17286                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17287                            newUserId, callback);
17288                } catch (RemoteException e) {
17289                }
17290            }
17291        } else {
17292            synchronized (this) {
17293                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17294            }
17295        }
17296        mUserSwitchObservers.finishBroadcast();
17297    }
17298
17299    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17300        synchronized (this) {
17301            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17302            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17303        }
17304    }
17305
17306    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17307        mCurUserSwitchCallback = null;
17308        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17309        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17310                oldUserId, newUserId, uss));
17311    }
17312
17313    void userInitialized(UserStartedState uss, int newUserId) {
17314        completeSwitchAndInitalize(uss, newUserId, true, false);
17315    }
17316
17317    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17318        completeSwitchAndInitalize(uss, newUserId, false, true);
17319    }
17320
17321    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17322            boolean clearInitializing, boolean clearSwitching) {
17323        boolean unfrozen = false;
17324        synchronized (this) {
17325            if (clearInitializing) {
17326                uss.initializing = false;
17327                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17328            }
17329            if (clearSwitching) {
17330                uss.switching = false;
17331            }
17332            if (!uss.switching && !uss.initializing) {
17333                mWindowManager.stopFreezingScreen();
17334                unfrozen = true;
17335            }
17336        }
17337        if (unfrozen) {
17338            final int N = mUserSwitchObservers.beginBroadcast();
17339            for (int i=0; i<N; i++) {
17340                try {
17341                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17342                } catch (RemoteException e) {
17343                }
17344            }
17345            mUserSwitchObservers.finishBroadcast();
17346        }
17347    }
17348
17349    void scheduleStartProfilesLocked() {
17350        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17351            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17352                    DateUtils.SECOND_IN_MILLIS);
17353        }
17354    }
17355
17356    void startProfilesLocked() {
17357        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17358        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17359                mCurrentUserId, false /* enabledOnly */);
17360        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17361        for (UserInfo user : profiles) {
17362            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17363                    && user.id != mCurrentUserId) {
17364                toStart.add(user);
17365            }
17366        }
17367        final int n = toStart.size();
17368        int i = 0;
17369        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17370            startUserInBackground(toStart.get(i).id);
17371        }
17372        if (i < n) {
17373            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17374        }
17375    }
17376
17377    void finishUserBoot(UserStartedState uss) {
17378        synchronized (this) {
17379            if (uss.mState == UserStartedState.STATE_BOOTING
17380                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17381                uss.mState = UserStartedState.STATE_RUNNING;
17382                final int userId = uss.mHandle.getIdentifier();
17383                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17384                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17385                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17386                broadcastIntentLocked(null, null, intent,
17387                        null, null, 0, null, null,
17388                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17389                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17390            }
17391        }
17392    }
17393
17394    void finishUserSwitch(UserStartedState uss) {
17395        synchronized (this) {
17396            finishUserBoot(uss);
17397
17398            startProfilesLocked();
17399
17400            int num = mUserLru.size();
17401            int i = 0;
17402            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17403                Integer oldUserId = mUserLru.get(i);
17404                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17405                if (oldUss == null) {
17406                    // Shouldn't happen, but be sane if it does.
17407                    mUserLru.remove(i);
17408                    num--;
17409                    continue;
17410                }
17411                if (oldUss.mState == UserStartedState.STATE_STOPPING
17412                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17413                    // This user is already stopping, doesn't count.
17414                    num--;
17415                    i++;
17416                    continue;
17417                }
17418                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17419                    // Owner and current can't be stopped, but count as running.
17420                    i++;
17421                    continue;
17422                }
17423                // This is a user to be stopped.
17424                stopUserLocked(oldUserId, null);
17425                num--;
17426                i++;
17427            }
17428        }
17429    }
17430
17431    @Override
17432    public int stopUser(final int userId, final IStopUserCallback callback) {
17433        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17434                != PackageManager.PERMISSION_GRANTED) {
17435            String msg = "Permission Denial: switchUser() from pid="
17436                    + Binder.getCallingPid()
17437                    + ", uid=" + Binder.getCallingUid()
17438                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17439            Slog.w(TAG, msg);
17440            throw new SecurityException(msg);
17441        }
17442        if (userId <= 0) {
17443            throw new IllegalArgumentException("Can't stop primary user " + userId);
17444        }
17445        synchronized (this) {
17446            return stopUserLocked(userId, callback);
17447        }
17448    }
17449
17450    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17451        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17452        if (mCurrentUserId == userId) {
17453            return ActivityManager.USER_OP_IS_CURRENT;
17454        }
17455
17456        final UserStartedState uss = mStartedUsers.get(userId);
17457        if (uss == null) {
17458            // User is not started, nothing to do...  but we do need to
17459            // callback if requested.
17460            if (callback != null) {
17461                mHandler.post(new Runnable() {
17462                    @Override
17463                    public void run() {
17464                        try {
17465                            callback.userStopped(userId);
17466                        } catch (RemoteException e) {
17467                        }
17468                    }
17469                });
17470            }
17471            return ActivityManager.USER_OP_SUCCESS;
17472        }
17473
17474        if (callback != null) {
17475            uss.mStopCallbacks.add(callback);
17476        }
17477
17478        if (uss.mState != UserStartedState.STATE_STOPPING
17479                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17480            uss.mState = UserStartedState.STATE_STOPPING;
17481            updateStartedUserArrayLocked();
17482
17483            long ident = Binder.clearCallingIdentity();
17484            try {
17485                // We are going to broadcast ACTION_USER_STOPPING and then
17486                // once that is done send a final ACTION_SHUTDOWN and then
17487                // stop the user.
17488                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17489                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17490                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17491                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17492                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17493                // This is the result receiver for the final shutdown broadcast.
17494                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17495                    @Override
17496                    public void performReceive(Intent intent, int resultCode, String data,
17497                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17498                        finishUserStop(uss);
17499                    }
17500                };
17501                // This is the result receiver for the initial stopping broadcast.
17502                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17503                    @Override
17504                    public void performReceive(Intent intent, int resultCode, String data,
17505                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17506                        // On to the next.
17507                        synchronized (ActivityManagerService.this) {
17508                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17509                                // Whoops, we are being started back up.  Abort, abort!
17510                                return;
17511                            }
17512                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17513                        }
17514                        mBatteryStatsService.noteEvent(
17515                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
17516                                Integer.toString(userId), userId);
17517                        mSystemServiceManager.stopUser(userId);
17518                        broadcastIntentLocked(null, null, shutdownIntent,
17519                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17520                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17521                    }
17522                };
17523                // Kick things off.
17524                broadcastIntentLocked(null, null, stoppingIntent,
17525                        null, stoppingReceiver, 0, null, null,
17526                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17527                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17528            } finally {
17529                Binder.restoreCallingIdentity(ident);
17530            }
17531        }
17532
17533        return ActivityManager.USER_OP_SUCCESS;
17534    }
17535
17536    void finishUserStop(UserStartedState uss) {
17537        final int userId = uss.mHandle.getIdentifier();
17538        boolean stopped;
17539        ArrayList<IStopUserCallback> callbacks;
17540        synchronized (this) {
17541            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17542            if (mStartedUsers.get(userId) != uss) {
17543                stopped = false;
17544            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17545                stopped = false;
17546            } else {
17547                stopped = true;
17548                // User can no longer run.
17549                mStartedUsers.remove(userId);
17550                mUserLru.remove(Integer.valueOf(userId));
17551                updateStartedUserArrayLocked();
17552
17553                // Clean up all state and processes associated with the user.
17554                // Kill all the processes for the user.
17555                forceStopUserLocked(userId, "finish user");
17556            }
17557        }
17558
17559        for (int i=0; i<callbacks.size(); i++) {
17560            try {
17561                if (stopped) callbacks.get(i).userStopped(userId);
17562                else callbacks.get(i).userStopAborted(userId);
17563            } catch (RemoteException e) {
17564            }
17565        }
17566
17567        if (stopped) {
17568            mSystemServiceManager.cleanupUser(userId);
17569            synchronized (this) {
17570                mStackSupervisor.removeUserLocked(userId);
17571            }
17572        }
17573    }
17574
17575    @Override
17576    public UserInfo getCurrentUser() {
17577        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
17578                != PackageManager.PERMISSION_GRANTED) && (
17579                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17580                != PackageManager.PERMISSION_GRANTED)) {
17581            String msg = "Permission Denial: getCurrentUser() from pid="
17582                    + Binder.getCallingPid()
17583                    + ", uid=" + Binder.getCallingUid()
17584                    + " requires " + INTERACT_ACROSS_USERS;
17585            Slog.w(TAG, msg);
17586            throw new SecurityException(msg);
17587        }
17588        synchronized (this) {
17589            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17590        }
17591    }
17592
17593    int getCurrentUserIdLocked() {
17594        return mCurrentUserId;
17595    }
17596
17597    @Override
17598    public boolean isUserRunning(int userId, boolean orStopped) {
17599        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17600                != PackageManager.PERMISSION_GRANTED) {
17601            String msg = "Permission Denial: isUserRunning() from pid="
17602                    + Binder.getCallingPid()
17603                    + ", uid=" + Binder.getCallingUid()
17604                    + " requires " + INTERACT_ACROSS_USERS;
17605            Slog.w(TAG, msg);
17606            throw new SecurityException(msg);
17607        }
17608        synchronized (this) {
17609            return isUserRunningLocked(userId, orStopped);
17610        }
17611    }
17612
17613    boolean isUserRunningLocked(int userId, boolean orStopped) {
17614        UserStartedState state = mStartedUsers.get(userId);
17615        if (state == null) {
17616            return false;
17617        }
17618        if (orStopped) {
17619            return true;
17620        }
17621        return state.mState != UserStartedState.STATE_STOPPING
17622                && state.mState != UserStartedState.STATE_SHUTDOWN;
17623    }
17624
17625    @Override
17626    public int[] getRunningUserIds() {
17627        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17628                != PackageManager.PERMISSION_GRANTED) {
17629            String msg = "Permission Denial: isUserRunning() from pid="
17630                    + Binder.getCallingPid()
17631                    + ", uid=" + Binder.getCallingUid()
17632                    + " requires " + INTERACT_ACROSS_USERS;
17633            Slog.w(TAG, msg);
17634            throw new SecurityException(msg);
17635        }
17636        synchronized (this) {
17637            return mStartedUserArray;
17638        }
17639    }
17640
17641    private void updateStartedUserArrayLocked() {
17642        int num = 0;
17643        for (int i=0; i<mStartedUsers.size();  i++) {
17644            UserStartedState uss = mStartedUsers.valueAt(i);
17645            // This list does not include stopping users.
17646            if (uss.mState != UserStartedState.STATE_STOPPING
17647                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17648                num++;
17649            }
17650        }
17651        mStartedUserArray = new int[num];
17652        num = 0;
17653        for (int i=0; i<mStartedUsers.size();  i++) {
17654            UserStartedState uss = mStartedUsers.valueAt(i);
17655            if (uss.mState != UserStartedState.STATE_STOPPING
17656                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17657                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17658                num++;
17659            }
17660        }
17661    }
17662
17663    @Override
17664    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17665        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17666                != PackageManager.PERMISSION_GRANTED) {
17667            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17668                    + Binder.getCallingPid()
17669                    + ", uid=" + Binder.getCallingUid()
17670                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17671            Slog.w(TAG, msg);
17672            throw new SecurityException(msg);
17673        }
17674
17675        mUserSwitchObservers.register(observer);
17676    }
17677
17678    @Override
17679    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17680        mUserSwitchObservers.unregister(observer);
17681    }
17682
17683    private boolean userExists(int userId) {
17684        if (userId == 0) {
17685            return true;
17686        }
17687        UserManagerService ums = getUserManagerLocked();
17688        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17689    }
17690
17691    int[] getUsersLocked() {
17692        UserManagerService ums = getUserManagerLocked();
17693        return ums != null ? ums.getUserIds() : new int[] { 0 };
17694    }
17695
17696    UserManagerService getUserManagerLocked() {
17697        if (mUserManager == null) {
17698            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17699            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17700        }
17701        return mUserManager;
17702    }
17703
17704    private int applyUserId(int uid, int userId) {
17705        return UserHandle.getUid(userId, uid);
17706    }
17707
17708    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17709        if (info == null) return null;
17710        ApplicationInfo newInfo = new ApplicationInfo(info);
17711        newInfo.uid = applyUserId(info.uid, userId);
17712        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17713                + info.packageName;
17714        return newInfo;
17715    }
17716
17717    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17718        if (aInfo == null
17719                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17720            return aInfo;
17721        }
17722
17723        ActivityInfo info = new ActivityInfo(aInfo);
17724        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17725        return info;
17726    }
17727
17728    private final class LocalService extends ActivityManagerInternal {
17729        @Override
17730        public void goingToSleep() {
17731            ActivityManagerService.this.goingToSleep();
17732        }
17733
17734        @Override
17735        public void wakingUp() {
17736            ActivityManagerService.this.wakingUp();
17737        }
17738    }
17739
17740    /**
17741     * An implementation of IAppTask, that allows an app to manage its own tasks via
17742     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17743     * only the process that calls getAppTasks() can call the AppTask methods.
17744     */
17745    class AppTaskImpl extends IAppTask.Stub {
17746        private int mTaskId;
17747        private int mCallingUid;
17748
17749        public AppTaskImpl(int taskId, int callingUid) {
17750            mTaskId = taskId;
17751            mCallingUid = callingUid;
17752        }
17753
17754        @Override
17755        public void finishAndRemoveTask() {
17756            // Ensure that we are called from the same process that created this AppTask
17757            if (mCallingUid != Binder.getCallingUid()) {
17758                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17759                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17760                return;
17761            }
17762
17763            synchronized (ActivityManagerService.this) {
17764                long origId = Binder.clearCallingIdentity();
17765                try {
17766                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17767                    if (tr != null) {
17768                        // Only kill the process if we are not a new document
17769                        int flags = tr.getBaseIntent().getFlags();
17770                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17771                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17772                        removeTaskByIdLocked(mTaskId,
17773                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17774                    }
17775                } finally {
17776                    Binder.restoreCallingIdentity(origId);
17777                }
17778            }
17779        }
17780
17781        @Override
17782        public ActivityManager.RecentTaskInfo getTaskInfo() {
17783            // Ensure that we are called from the same process that created this AppTask
17784            if (mCallingUid != Binder.getCallingUid()) {
17785                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17786                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17787                return null;
17788            }
17789
17790            synchronized (ActivityManagerService.this) {
17791                long origId = Binder.clearCallingIdentity();
17792                try {
17793                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17794                    if (tr != null) {
17795                        return createRecentTaskInfoFromTaskRecord(tr);
17796                    }
17797                } finally {
17798                    Binder.restoreCallingIdentity(origId);
17799                }
17800                return null;
17801            }
17802        }
17803    }
17804}
17805