ActivityManagerService.java revision bb742462781a73bb25516067c8fe6311c1c8a93e
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                mSystemServiceManager.startUser(msg.arg1);
1815                break;
1816            }
1817            case SYSTEM_USER_CURRENT_MSG: {
1818                mSystemServiceManager.switchUser(msg.arg1);
1819                break;
1820            }
1821            }
1822        }
1823    };
1824
1825    static final int COLLECT_PSS_BG_MSG = 1;
1826
1827    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1828        @Override
1829        public void handleMessage(Message msg) {
1830            switch (msg.what) {
1831            case COLLECT_PSS_BG_MSG: {
1832                long start = SystemClock.uptimeMillis();
1833                MemInfoReader memInfo = null;
1834                synchronized (ActivityManagerService.this) {
1835                    if (mFullPssPending) {
1836                        mFullPssPending = false;
1837                        memInfo = new MemInfoReader();
1838                    }
1839                }
1840                if (memInfo != null) {
1841                    updateCpuStatsNow();
1842                    long nativeTotalPss = 0;
1843                    synchronized (mProcessCpuThread) {
1844                        final int N = mProcessCpuTracker.countStats();
1845                        for (int j=0; j<N; j++) {
1846                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1847                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1848                                // This is definitely an application process; skip it.
1849                                continue;
1850                            }
1851                            synchronized (mPidsSelfLocked) {
1852                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1853                                    // This is one of our own processes; skip it.
1854                                    continue;
1855                                }
1856                            }
1857                            nativeTotalPss += Debug.getPss(st.pid, null);
1858                        }
1859                    }
1860                    memInfo.readMemInfo();
1861                    synchronized (this) {
1862                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1863                                + (SystemClock.uptimeMillis()-start) + "ms");
1864                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1865                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1866                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1867                                        +memInfo.getSlabSizeKb(),
1868                                nativeTotalPss);
1869                    }
1870                }
1871
1872                int i=0, num=0;
1873                long[] tmp = new long[1];
1874                do {
1875                    ProcessRecord proc;
1876                    int procState;
1877                    int pid;
1878                    synchronized (ActivityManagerService.this) {
1879                        if (i >= mPendingPssProcesses.size()) {
1880                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1881                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1882                            mPendingPssProcesses.clear();
1883                            return;
1884                        }
1885                        proc = mPendingPssProcesses.get(i);
1886                        procState = proc.pssProcState;
1887                        if (proc.thread != null && procState == proc.setProcState) {
1888                            pid = proc.pid;
1889                        } else {
1890                            proc = null;
1891                            pid = 0;
1892                        }
1893                        i++;
1894                    }
1895                    if (proc != null) {
1896                        long pss = Debug.getPss(pid, tmp);
1897                        synchronized (ActivityManagerService.this) {
1898                            if (proc.thread != null && proc.setProcState == procState
1899                                    && proc.pid == pid) {
1900                                num++;
1901                                proc.lastPssTime = SystemClock.uptimeMillis();
1902                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1903                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1904                                        + ": " + pss + " lastPss=" + proc.lastPss
1905                                        + " state=" + ProcessList.makeProcStateString(procState));
1906                                if (proc.initialIdlePss == 0) {
1907                                    proc.initialIdlePss = pss;
1908                                }
1909                                proc.lastPss = pss;
1910                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1911                                    proc.lastCachedPss = pss;
1912                                }
1913                            }
1914                        }
1915                    }
1916                } while (true);
1917            }
1918            }
1919        }
1920    };
1921
1922    /**
1923     * Monitor for package changes and update our internal state.
1924     */
1925    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1926        @Override
1927        public void onPackageRemoved(String packageName, int uid) {
1928            // Remove all tasks with activities in the specified package from the list of recent tasks
1929            synchronized (ActivityManagerService.this) {
1930                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1931                    TaskRecord tr = mRecentTasks.get(i);
1932                    ComponentName cn = tr.intent.getComponent();
1933                    if (cn != null && cn.getPackageName().equals(packageName)) {
1934                        // If the package name matches, remove the task and kill the process
1935                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1936                    }
1937                }
1938            }
1939        }
1940
1941        @Override
1942        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1943            onPackageModified(packageName);
1944            return true;
1945        }
1946
1947        @Override
1948        public void onPackageModified(String packageName) {
1949            final PackageManager pm = mContext.getPackageManager();
1950            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1951                    new ArrayList<Pair<Intent, Integer>>();
1952            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1953            // Copy the list of recent tasks so that we don't hold onto the lock on
1954            // ActivityManagerService for long periods while checking if components exist.
1955            synchronized (ActivityManagerService.this) {
1956                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1957                    TaskRecord tr = mRecentTasks.get(i);
1958                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1959                }
1960            }
1961            // Check the recent tasks and filter out all tasks with components that no longer exist.
1962            Intent tmpI = new Intent();
1963            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1964                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1965                ComponentName cn = p.first.getComponent();
1966                if (cn != null && cn.getPackageName().equals(packageName)) {
1967                    try {
1968                        // Add the task to the list to remove if the component no longer exists
1969                        tmpI.setComponent(cn);
1970                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1971                            tasksToRemove.add(p.second);
1972                        }
1973                    } catch (Exception e) {}
1974                }
1975            }
1976            // Prune all the tasks with removed components from the list of recent tasks
1977            synchronized (ActivityManagerService.this) {
1978                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1979                    // Remove the task but don't kill the process (since other components in that
1980                    // package may still be running and in the background)
1981                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1982                }
1983            }
1984        }
1985
1986        @Override
1987        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1988            // Force stop the specified packages
1989            if (packages != null) {
1990                for (String pkg : packages) {
1991                    synchronized (ActivityManagerService.this) {
1992                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
1993                                "finished booting")) {
1994                            return true;
1995                        }
1996                    }
1997                }
1998            }
1999            return false;
2000        }
2001    };
2002
2003    public void setSystemProcess() {
2004        try {
2005            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2006            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2007            ServiceManager.addService("meminfo", new MemBinder(this));
2008            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2009            ServiceManager.addService("dbinfo", new DbBinder(this));
2010            if (MONITOR_CPU_USAGE) {
2011                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2012            }
2013            ServiceManager.addService("permission", new PermissionController(this));
2014
2015            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2016                    "android", STOCK_PM_FLAGS);
2017            mSystemThread.installSystemApplicationInfo(info);
2018
2019            synchronized (this) {
2020                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
2021                app.persistent = true;
2022                app.pid = MY_PID;
2023                app.maxAdj = ProcessList.SYSTEM_ADJ;
2024                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2025                mProcessNames.put(app.processName, app.uid, app);
2026                synchronized (mPidsSelfLocked) {
2027                    mPidsSelfLocked.put(app.pid, app);
2028                }
2029                updateLruProcessLocked(app, false, null);
2030                updateOomAdjLocked();
2031            }
2032        } catch (PackageManager.NameNotFoundException e) {
2033            throw new RuntimeException(
2034                    "Unable to find android system package", e);
2035        }
2036    }
2037
2038    public void setWindowManager(WindowManagerService wm) {
2039        mWindowManager = wm;
2040        mStackSupervisor.setWindowManager(wm);
2041    }
2042
2043    public void startObservingNativeCrashes() {
2044        final NativeCrashListener ncl = new NativeCrashListener(this);
2045        ncl.start();
2046    }
2047
2048    public IAppOpsService getAppOpsService() {
2049        return mAppOpsService;
2050    }
2051
2052    static class MemBinder extends Binder {
2053        ActivityManagerService mActivityManagerService;
2054        MemBinder(ActivityManagerService activityManagerService) {
2055            mActivityManagerService = activityManagerService;
2056        }
2057
2058        @Override
2059        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2060            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2061                    != PackageManager.PERMISSION_GRANTED) {
2062                pw.println("Permission Denial: can't dump meminfo from from pid="
2063                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2064                        + " without permission " + android.Manifest.permission.DUMP);
2065                return;
2066            }
2067
2068            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2069        }
2070    }
2071
2072    static class GraphicsBinder extends Binder {
2073        ActivityManagerService mActivityManagerService;
2074        GraphicsBinder(ActivityManagerService activityManagerService) {
2075            mActivityManagerService = activityManagerService;
2076        }
2077
2078        @Override
2079        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2080            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2081                    != PackageManager.PERMISSION_GRANTED) {
2082                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2083                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2084                        + " without permission " + android.Manifest.permission.DUMP);
2085                return;
2086            }
2087
2088            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2089        }
2090    }
2091
2092    static class DbBinder extends Binder {
2093        ActivityManagerService mActivityManagerService;
2094        DbBinder(ActivityManagerService activityManagerService) {
2095            mActivityManagerService = activityManagerService;
2096        }
2097
2098        @Override
2099        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2100            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2101                    != PackageManager.PERMISSION_GRANTED) {
2102                pw.println("Permission Denial: can't dump dbinfo from from pid="
2103                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2104                        + " without permission " + android.Manifest.permission.DUMP);
2105                return;
2106            }
2107
2108            mActivityManagerService.dumpDbInfo(fd, pw, args);
2109        }
2110    }
2111
2112    static class CpuBinder extends Binder {
2113        ActivityManagerService mActivityManagerService;
2114        CpuBinder(ActivityManagerService activityManagerService) {
2115            mActivityManagerService = activityManagerService;
2116        }
2117
2118        @Override
2119        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2120            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2121                    != PackageManager.PERMISSION_GRANTED) {
2122                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2123                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2124                        + " without permission " + android.Manifest.permission.DUMP);
2125                return;
2126            }
2127
2128            synchronized (mActivityManagerService.mProcessCpuThread) {
2129                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2130                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2131                        SystemClock.uptimeMillis()));
2132            }
2133        }
2134    }
2135
2136    public static final class Lifecycle extends SystemService {
2137        private final ActivityManagerService mService;
2138
2139        public Lifecycle(Context context) {
2140            super(context);
2141            mService = new ActivityManagerService(context);
2142        }
2143
2144        @Override
2145        public void onStart() {
2146            mService.start();
2147        }
2148
2149        public ActivityManagerService getService() {
2150            return mService;
2151        }
2152    }
2153
2154    // Note: This method is invoked on the main thread but may need to attach various
2155    // handlers to other threads.  So take care to be explicit about the looper.
2156    public ActivityManagerService(Context systemContext) {
2157        mContext = systemContext;
2158        mFactoryTest = FactoryTest.getMode();
2159        mSystemThread = ActivityThread.currentActivityThread();
2160
2161        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2162
2163        mHandlerThread = new ServiceThread(TAG,
2164                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2165        mHandlerThread.start();
2166        mHandler = new MainHandler(mHandlerThread.getLooper());
2167
2168        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2169                "foreground", BROADCAST_FG_TIMEOUT, false);
2170        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2171                "background", BROADCAST_BG_TIMEOUT, true);
2172        mBroadcastQueues[0] = mFgBroadcastQueue;
2173        mBroadcastQueues[1] = mBgBroadcastQueue;
2174
2175        mServices = new ActiveServices(this);
2176        mProviderMap = new ProviderMap(this);
2177
2178        // TODO: Move creation of battery stats service outside of activity manager service.
2179        File dataDir = Environment.getDataDirectory();
2180        File systemDir = new File(dataDir, "system");
2181        systemDir.mkdirs();
2182        mBatteryStatsService = new BatteryStatsService(new File(
2183                systemDir, "batterystats.bin").toString(), mHandler);
2184        mBatteryStatsService.getActiveStatistics().readLocked();
2185        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2186        mOnBattery = DEBUG_POWER ? true
2187                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2188        mBatteryStatsService.getActiveStatistics().setCallback(this);
2189
2190        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2191
2192        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
2193        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2194
2195        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2196
2197        // User 0 is the first and only user that runs at boot.
2198        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2199        mUserLru.add(Integer.valueOf(0));
2200        updateStartedUserArrayLocked();
2201
2202        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2203            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2204
2205        mConfiguration.setToDefaults();
2206        mConfiguration.setLocale(Locale.getDefault());
2207
2208        mConfigurationSeq = mConfiguration.seq = 1;
2209        mProcessCpuTracker.init();
2210
2211        mHasRecents = mContext.getResources().getBoolean(
2212                com.android.internal.R.bool.config_hasRecents);
2213
2214        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2215        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2216        mStackSupervisor = new ActivityStackSupervisor(this);
2217        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2218
2219        mProcessCpuThread = new Thread("CpuTracker") {
2220            @Override
2221            public void run() {
2222                while (true) {
2223                    try {
2224                        try {
2225                            synchronized(this) {
2226                                final long now = SystemClock.uptimeMillis();
2227                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2228                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2229                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2230                                //        + ", write delay=" + nextWriteDelay);
2231                                if (nextWriteDelay < nextCpuDelay) {
2232                                    nextCpuDelay = nextWriteDelay;
2233                                }
2234                                if (nextCpuDelay > 0) {
2235                                    mProcessCpuMutexFree.set(true);
2236                                    this.wait(nextCpuDelay);
2237                                }
2238                            }
2239                        } catch (InterruptedException e) {
2240                        }
2241                        updateCpuStatsNow();
2242                    } catch (Exception e) {
2243                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2244                    }
2245                }
2246            }
2247        };
2248
2249        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2250
2251        Watchdog.getInstance().addMonitor(this);
2252        Watchdog.getInstance().addThread(mHandler);
2253    }
2254
2255    public void setSystemServiceManager(SystemServiceManager mgr) {
2256        mSystemServiceManager = mgr;
2257    }
2258
2259    private void start() {
2260        Process.removeAllProcessGroups();
2261        mProcessCpuThread.start();
2262
2263        mBatteryStatsService.publish(mContext);
2264        mUsageStatsService.publish(mContext);
2265        mAppOpsService.publish(mContext);
2266        Slog.d("AppOps", "AppOpsService published");
2267        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2268    }
2269
2270    public void initPowerManagement() {
2271        mStackSupervisor.initPowerManagement();
2272        mBatteryStatsService.initPowerManagement();
2273    }
2274
2275    @Override
2276    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2277            throws RemoteException {
2278        if (code == SYSPROPS_TRANSACTION) {
2279            // We need to tell all apps about the system property change.
2280            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2281            synchronized(this) {
2282                final int NP = mProcessNames.getMap().size();
2283                for (int ip=0; ip<NP; ip++) {
2284                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2285                    final int NA = apps.size();
2286                    for (int ia=0; ia<NA; ia++) {
2287                        ProcessRecord app = apps.valueAt(ia);
2288                        if (app.thread != null) {
2289                            procs.add(app.thread.asBinder());
2290                        }
2291                    }
2292                }
2293            }
2294
2295            int N = procs.size();
2296            for (int i=0; i<N; i++) {
2297                Parcel data2 = Parcel.obtain();
2298                try {
2299                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2300                } catch (RemoteException e) {
2301                }
2302                data2.recycle();
2303            }
2304        }
2305        try {
2306            return super.onTransact(code, data, reply, flags);
2307        } catch (RuntimeException e) {
2308            // The activity manager only throws security exceptions, so let's
2309            // log all others.
2310            if (!(e instanceof SecurityException)) {
2311                Slog.wtf(TAG, "Activity Manager Crash", e);
2312            }
2313            throw e;
2314        }
2315    }
2316
2317    void updateCpuStats() {
2318        final long now = SystemClock.uptimeMillis();
2319        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2320            return;
2321        }
2322        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2323            synchronized (mProcessCpuThread) {
2324                mProcessCpuThread.notify();
2325            }
2326        }
2327    }
2328
2329    void updateCpuStatsNow() {
2330        synchronized (mProcessCpuThread) {
2331            mProcessCpuMutexFree.set(false);
2332            final long now = SystemClock.uptimeMillis();
2333            boolean haveNewCpuStats = false;
2334
2335            if (MONITOR_CPU_USAGE &&
2336                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2337                mLastCpuTime.set(now);
2338                haveNewCpuStats = true;
2339                mProcessCpuTracker.update();
2340                //Slog.i(TAG, mProcessCpu.printCurrentState());
2341                //Slog.i(TAG, "Total CPU usage: "
2342                //        + mProcessCpu.getTotalCpuPercent() + "%");
2343
2344                // Slog the cpu usage if the property is set.
2345                if ("true".equals(SystemProperties.get("events.cpu"))) {
2346                    int user = mProcessCpuTracker.getLastUserTime();
2347                    int system = mProcessCpuTracker.getLastSystemTime();
2348                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2349                    int irq = mProcessCpuTracker.getLastIrqTime();
2350                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2351                    int idle = mProcessCpuTracker.getLastIdleTime();
2352
2353                    int total = user + system + iowait + irq + softIrq + idle;
2354                    if (total == 0) total = 1;
2355
2356                    EventLog.writeEvent(EventLogTags.CPU,
2357                            ((user+system+iowait+irq+softIrq) * 100) / total,
2358                            (user * 100) / total,
2359                            (system * 100) / total,
2360                            (iowait * 100) / total,
2361                            (irq * 100) / total,
2362                            (softIrq * 100) / total);
2363                }
2364            }
2365
2366            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2367            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2368            synchronized(bstats) {
2369                synchronized(mPidsSelfLocked) {
2370                    if (haveNewCpuStats) {
2371                        if (mOnBattery) {
2372                            int perc = bstats.startAddingCpuLocked();
2373                            int totalUTime = 0;
2374                            int totalSTime = 0;
2375                            final int N = mProcessCpuTracker.countStats();
2376                            for (int i=0; i<N; i++) {
2377                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2378                                if (!st.working) {
2379                                    continue;
2380                                }
2381                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2382                                int otherUTime = (st.rel_utime*perc)/100;
2383                                int otherSTime = (st.rel_stime*perc)/100;
2384                                totalUTime += otherUTime;
2385                                totalSTime += otherSTime;
2386                                if (pr != null) {
2387                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2388                                    if (ps == null || !ps.isActive()) {
2389                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2390                                                pr.info.uid, pr.processName);
2391                                    }
2392                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2393                                            st.rel_stime-otherSTime);
2394                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2395                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2396                                } else {
2397                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2398                                    if (ps == null || !ps.isActive()) {
2399                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2400                                                bstats.mapUid(st.uid), st.name);
2401                                    }
2402                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2403                                            st.rel_stime-otherSTime);
2404                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2405                                }
2406                            }
2407                            bstats.finishAddingCpuLocked(perc, totalUTime,
2408                                    totalSTime, cpuSpeedTimes);
2409                        }
2410                    }
2411                }
2412
2413                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2414                    mLastWriteTime = now;
2415                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2416                }
2417            }
2418        }
2419    }
2420
2421    @Override
2422    public void batteryNeedsCpuUpdate() {
2423        updateCpuStatsNow();
2424    }
2425
2426    @Override
2427    public void batteryPowerChanged(boolean onBattery) {
2428        // When plugging in, update the CPU stats first before changing
2429        // the plug state.
2430        updateCpuStatsNow();
2431        synchronized (this) {
2432            synchronized(mPidsSelfLocked) {
2433                mOnBattery = DEBUG_POWER ? true : onBattery;
2434            }
2435        }
2436    }
2437
2438    /**
2439     * Initialize the application bind args. These are passed to each
2440     * process when the bindApplication() IPC is sent to the process. They're
2441     * lazily setup to make sure the services are running when they're asked for.
2442     */
2443    private HashMap<String, IBinder> getCommonServicesLocked() {
2444        if (mAppBindArgs == null) {
2445            mAppBindArgs = new HashMap<String, IBinder>();
2446
2447            // Setup the application init args
2448            mAppBindArgs.put("package", ServiceManager.getService("package"));
2449            mAppBindArgs.put("window", ServiceManager.getService("window"));
2450            mAppBindArgs.put(Context.ALARM_SERVICE,
2451                    ServiceManager.getService(Context.ALARM_SERVICE));
2452        }
2453        return mAppBindArgs;
2454    }
2455
2456    final void setFocusedActivityLocked(ActivityRecord r) {
2457        if (mFocusedActivity != r) {
2458            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2459            mFocusedActivity = r;
2460            if (r.task != null && r.task.voiceInteractor != null) {
2461                startRunningVoiceLocked();
2462            } else {
2463                finishRunningVoiceLocked();
2464            }
2465            mStackSupervisor.setFocusedStack(r);
2466            if (r != null) {
2467                mWindowManager.setFocusedApp(r.appToken, true);
2468            }
2469            applyUpdateLockStateLocked(r);
2470        }
2471    }
2472
2473    final void clearFocusedActivity(ActivityRecord r) {
2474        if (mFocusedActivity == r) {
2475            mFocusedActivity = null;
2476        }
2477    }
2478
2479    @Override
2480    public void setFocusedStack(int stackId) {
2481        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2482        synchronized (ActivityManagerService.this) {
2483            ActivityStack stack = mStackSupervisor.getStack(stackId);
2484            if (stack != null) {
2485                ActivityRecord r = stack.topRunningActivityLocked(null);
2486                if (r != null) {
2487                    setFocusedActivityLocked(r);
2488                }
2489            }
2490        }
2491    }
2492
2493    @Override
2494    public void notifyActivityDrawn(IBinder token) {
2495        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2496        synchronized (this) {
2497            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2498            if (r != null) {
2499                r.task.stack.notifyActivityDrawnLocked(r);
2500            }
2501        }
2502    }
2503
2504    final void applyUpdateLockStateLocked(ActivityRecord r) {
2505        // Modifications to the UpdateLock state are done on our handler, outside
2506        // the activity manager's locks.  The new state is determined based on the
2507        // state *now* of the relevant activity record.  The object is passed to
2508        // the handler solely for logging detail, not to be consulted/modified.
2509        final boolean nextState = r != null && r.immersive;
2510        mHandler.sendMessage(
2511                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2512    }
2513
2514    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2515        Message msg = Message.obtain();
2516        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2517        msg.obj = r.task.askedCompatMode ? null : r;
2518        mHandler.sendMessage(msg);
2519    }
2520
2521    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2522            String what, Object obj, ProcessRecord srcApp) {
2523        app.lastActivityTime = now;
2524
2525        if (app.activities.size() > 0) {
2526            // Don't want to touch dependent processes that are hosting activities.
2527            return index;
2528        }
2529
2530        int lrui = mLruProcesses.lastIndexOf(app);
2531        if (lrui < 0) {
2532            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2533                    + what + " " + obj + " from " + srcApp);
2534            return index;
2535        }
2536
2537        if (lrui >= index) {
2538            // Don't want to cause this to move dependent processes *back* in the
2539            // list as if they were less frequently used.
2540            return index;
2541        }
2542
2543        if (lrui >= mLruProcessActivityStart) {
2544            // Don't want to touch dependent processes that are hosting activities.
2545            return index;
2546        }
2547
2548        mLruProcesses.remove(lrui);
2549        if (index > 0) {
2550            index--;
2551        }
2552        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2553                + " in LRU list: " + app);
2554        mLruProcesses.add(index, app);
2555        return index;
2556    }
2557
2558    final void removeLruProcessLocked(ProcessRecord app) {
2559        int lrui = mLruProcesses.lastIndexOf(app);
2560        if (lrui >= 0) {
2561            if (lrui <= mLruProcessActivityStart) {
2562                mLruProcessActivityStart--;
2563            }
2564            if (lrui <= mLruProcessServiceStart) {
2565                mLruProcessServiceStart--;
2566            }
2567            mLruProcesses.remove(lrui);
2568        }
2569    }
2570
2571    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2572            ProcessRecord client) {
2573        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2574                || app.treatLikeActivity;
2575        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2576        if (!activityChange && hasActivity) {
2577            // The process has activities, so we are only allowing activity-based adjustments
2578            // to move it.  It should be kept in the front of the list with other
2579            // processes that have activities, and we don't want those to change their
2580            // order except due to activity operations.
2581            return;
2582        }
2583
2584        mLruSeq++;
2585        final long now = SystemClock.uptimeMillis();
2586        app.lastActivityTime = now;
2587
2588        // First a quick reject: if the app is already at the position we will
2589        // put it, then there is nothing to do.
2590        if (hasActivity) {
2591            final int N = mLruProcesses.size();
2592            if (N > 0 && mLruProcesses.get(N-1) == app) {
2593                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2594                return;
2595            }
2596        } else {
2597            if (mLruProcessServiceStart > 0
2598                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2599                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2600                return;
2601            }
2602        }
2603
2604        int lrui = mLruProcesses.lastIndexOf(app);
2605
2606        if (app.persistent && lrui >= 0) {
2607            // We don't care about the position of persistent processes, as long as
2608            // they are in the list.
2609            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2610            return;
2611        }
2612
2613        /* In progress: compute new position first, so we can avoid doing work
2614           if the process is not actually going to move.  Not yet working.
2615        int addIndex;
2616        int nextIndex;
2617        boolean inActivity = false, inService = false;
2618        if (hasActivity) {
2619            // Process has activities, put it at the very tipsy-top.
2620            addIndex = mLruProcesses.size();
2621            nextIndex = mLruProcessServiceStart;
2622            inActivity = true;
2623        } else if (hasService) {
2624            // Process has services, put it at the top of the service list.
2625            addIndex = mLruProcessActivityStart;
2626            nextIndex = mLruProcessServiceStart;
2627            inActivity = true;
2628            inService = true;
2629        } else  {
2630            // Process not otherwise of interest, it goes to the top of the non-service area.
2631            addIndex = mLruProcessServiceStart;
2632            if (client != null) {
2633                int clientIndex = mLruProcesses.lastIndexOf(client);
2634                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2635                        + app);
2636                if (clientIndex >= 0 && addIndex > clientIndex) {
2637                    addIndex = clientIndex;
2638                }
2639            }
2640            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2641        }
2642
2643        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2644                + mLruProcessActivityStart + "): " + app);
2645        */
2646
2647        if (lrui >= 0) {
2648            if (lrui < mLruProcessActivityStart) {
2649                mLruProcessActivityStart--;
2650            }
2651            if (lrui < mLruProcessServiceStart) {
2652                mLruProcessServiceStart--;
2653            }
2654            /*
2655            if (addIndex > lrui) {
2656                addIndex--;
2657            }
2658            if (nextIndex > lrui) {
2659                nextIndex--;
2660            }
2661            */
2662            mLruProcesses.remove(lrui);
2663        }
2664
2665        /*
2666        mLruProcesses.add(addIndex, app);
2667        if (inActivity) {
2668            mLruProcessActivityStart++;
2669        }
2670        if (inService) {
2671            mLruProcessActivityStart++;
2672        }
2673        */
2674
2675        int nextIndex;
2676        if (hasActivity) {
2677            final int N = mLruProcesses.size();
2678            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2679                // Process doesn't have activities, but has clients with
2680                // activities...  move it up, but one below the top (the top
2681                // should always have a real activity).
2682                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2683                mLruProcesses.add(N-1, app);
2684                // To keep it from spamming the LRU list (by making a bunch of clients),
2685                // we will push down any other entries owned by the app.
2686                final int uid = app.info.uid;
2687                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2688                    ProcessRecord subProc = mLruProcesses.get(i);
2689                    if (subProc.info.uid == uid) {
2690                        // We want to push this one down the list.  If the process after
2691                        // it is for the same uid, however, don't do so, because we don't
2692                        // want them internally to be re-ordered.
2693                        if (mLruProcesses.get(i-1).info.uid != uid) {
2694                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2695                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2696                            ProcessRecord tmp = mLruProcesses.get(i);
2697                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2698                            mLruProcesses.set(i-1, tmp);
2699                            i--;
2700                        }
2701                    } else {
2702                        // A gap, we can stop here.
2703                        break;
2704                    }
2705                }
2706            } else {
2707                // Process has activities, put it at the very tipsy-top.
2708                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2709                mLruProcesses.add(app);
2710            }
2711            nextIndex = mLruProcessServiceStart;
2712        } else if (hasService) {
2713            // Process has services, put it at the top of the service list.
2714            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2715            mLruProcesses.add(mLruProcessActivityStart, app);
2716            nextIndex = mLruProcessServiceStart;
2717            mLruProcessActivityStart++;
2718        } else  {
2719            // Process not otherwise of interest, it goes to the top of the non-service area.
2720            int index = mLruProcessServiceStart;
2721            if (client != null) {
2722                // If there is a client, don't allow the process to be moved up higher
2723                // in the list than that client.
2724                int clientIndex = mLruProcesses.lastIndexOf(client);
2725                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2726                        + " when updating " + app);
2727                if (clientIndex <= lrui) {
2728                    // Don't allow the client index restriction to push it down farther in the
2729                    // list than it already is.
2730                    clientIndex = lrui;
2731                }
2732                if (clientIndex >= 0 && index > clientIndex) {
2733                    index = clientIndex;
2734                }
2735            }
2736            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2737            mLruProcesses.add(index, app);
2738            nextIndex = index-1;
2739            mLruProcessActivityStart++;
2740            mLruProcessServiceStart++;
2741        }
2742
2743        // If the app is currently using a content provider or service,
2744        // bump those processes as well.
2745        for (int j=app.connections.size()-1; j>=0; j--) {
2746            ConnectionRecord cr = app.connections.valueAt(j);
2747            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2748                    && cr.binding.service.app != null
2749                    && cr.binding.service.app.lruSeq != mLruSeq
2750                    && !cr.binding.service.app.persistent) {
2751                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2752                        "service connection", cr, app);
2753            }
2754        }
2755        for (int j=app.conProviders.size()-1; j>=0; j--) {
2756            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2757            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2758                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2759                        "provider reference", cpr, app);
2760            }
2761        }
2762    }
2763
2764    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2765        if (uid == Process.SYSTEM_UID) {
2766            // The system gets to run in any process.  If there are multiple
2767            // processes with the same uid, just pick the first (this
2768            // should never happen).
2769            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2770            if (procs == null) return null;
2771            final int N = procs.size();
2772            for (int i = 0; i < N; i++) {
2773                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2774            }
2775        }
2776        ProcessRecord proc = mProcessNames.get(processName, uid);
2777        if (false && proc != null && !keepIfLarge
2778                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2779                && proc.lastCachedPss >= 4000) {
2780            // Turn this condition on to cause killing to happen regularly, for testing.
2781            if (proc.baseProcessTracker != null) {
2782                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2783            }
2784            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2785                    + "k from cached");
2786        } else if (proc != null && !keepIfLarge
2787                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2788                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2789            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2790            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2791                if (proc.baseProcessTracker != null) {
2792                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2793                }
2794                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2795                        + "k from cached");
2796            }
2797        }
2798        return proc;
2799    }
2800
2801    void ensurePackageDexOpt(String packageName) {
2802        IPackageManager pm = AppGlobals.getPackageManager();
2803        try {
2804            if (pm.performDexOpt(packageName)) {
2805                mDidDexOpt = true;
2806            }
2807        } catch (RemoteException e) {
2808        }
2809    }
2810
2811    boolean isNextTransitionForward() {
2812        int transit = mWindowManager.getPendingAppTransition();
2813        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2814                || transit == AppTransition.TRANSIT_TASK_OPEN
2815                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2816    }
2817
2818    final ProcessRecord startProcessLocked(String processName,
2819            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2820            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2821            boolean isolated, boolean keepIfLarge) {
2822        ProcessRecord app;
2823        if (!isolated) {
2824            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2825        } else {
2826            // If this is an isolated process, it can't re-use an existing process.
2827            app = null;
2828        }
2829        // We don't have to do anything more if:
2830        // (1) There is an existing application record; and
2831        // (2) The caller doesn't think it is dead, OR there is no thread
2832        //     object attached to it so we know it couldn't have crashed; and
2833        // (3) There is a pid assigned to it, so it is either starting or
2834        //     already running.
2835        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2836                + " app=" + app + " knownToBeDead=" + knownToBeDead
2837                + " thread=" + (app != null ? app.thread : null)
2838                + " pid=" + (app != null ? app.pid : -1));
2839        if (app != null && app.pid > 0) {
2840            if (!knownToBeDead || app.thread == null) {
2841                // We already have the app running, or are waiting for it to
2842                // come up (we have a pid but not yet its thread), so keep it.
2843                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2844                // If this is a new package in the process, add the package to the list
2845                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2846                return app;
2847            }
2848
2849            // An application record is attached to a previous process,
2850            // clean it up now.
2851            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2852            Process.killProcessGroup(app.info.uid, app.pid);
2853            handleAppDiedLocked(app, true, true);
2854        }
2855
2856        String hostingNameStr = hostingName != null
2857                ? hostingName.flattenToShortString() : null;
2858
2859        if (!isolated) {
2860            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2861                // If we are in the background, then check to see if this process
2862                // is bad.  If so, we will just silently fail.
2863                if (mBadProcesses.get(info.processName, info.uid) != null) {
2864                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2865                            + "/" + info.processName);
2866                    return null;
2867                }
2868            } else {
2869                // When the user is explicitly starting a process, then clear its
2870                // crash count so that we won't make it bad until they see at
2871                // least one crash dialog again, and make the process good again
2872                // if it had been bad.
2873                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2874                        + "/" + info.processName);
2875                mProcessCrashTimes.remove(info.processName, info.uid);
2876                if (mBadProcesses.get(info.processName, info.uid) != null) {
2877                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2878                            UserHandle.getUserId(info.uid), info.uid,
2879                            info.processName);
2880                    mBadProcesses.remove(info.processName, info.uid);
2881                    if (app != null) {
2882                        app.bad = false;
2883                    }
2884                }
2885            }
2886        }
2887
2888        if (app == null) {
2889            app = newProcessRecordLocked(info, processName, isolated);
2890            if (app == null) {
2891                Slog.w(TAG, "Failed making new process record for "
2892                        + processName + "/" + info.uid + " isolated=" + isolated);
2893                return null;
2894            }
2895            mProcessNames.put(processName, app.uid, app);
2896            if (isolated) {
2897                mIsolatedProcesses.put(app.uid, app);
2898            }
2899        } else {
2900            // If this is a new package in the process, add the package to the list
2901            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2902        }
2903
2904        // If the system is not ready yet, then hold off on starting this
2905        // process until it is.
2906        if (!mProcessesReady
2907                && !isAllowedWhileBooting(info)
2908                && !allowWhileBooting) {
2909            if (!mProcessesOnHold.contains(app)) {
2910                mProcessesOnHold.add(app);
2911            }
2912            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2913            return app;
2914        }
2915
2916        startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */);
2917        return (app.pid != 0) ? app : null;
2918    }
2919
2920    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2921        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2922    }
2923
2924    private final void startProcessLocked(ProcessRecord app,
2925            String hostingType, String hostingNameStr, String abiOverride) {
2926        if (app.pid > 0 && app.pid != MY_PID) {
2927            synchronized (mPidsSelfLocked) {
2928                mPidsSelfLocked.remove(app.pid);
2929                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2930            }
2931            app.setPid(0);
2932        }
2933
2934        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2935                "startProcessLocked removing on hold: " + app);
2936        mProcessesOnHold.remove(app);
2937
2938        updateCpuStats();
2939
2940        try {
2941            int uid = app.uid;
2942
2943            int[] gids = null;
2944            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2945            if (!app.isolated) {
2946                int[] permGids = null;
2947                try {
2948                    final PackageManager pm = mContext.getPackageManager();
2949                    permGids = pm.getPackageGids(app.info.packageName);
2950
2951                    if (Environment.isExternalStorageEmulated()) {
2952                        if (pm.checkPermission(
2953                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2954                                app.info.packageName) == PERMISSION_GRANTED) {
2955                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2956                        } else {
2957                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2958                        }
2959                    }
2960                } catch (PackageManager.NameNotFoundException e) {
2961                    Slog.w(TAG, "Unable to retrieve gids", e);
2962                }
2963
2964                /*
2965                 * Add shared application and profile GIDs so applications can share some
2966                 * resources like shared libraries and access user-wide resources
2967                 */
2968                if (permGids == null) {
2969                    gids = new int[2];
2970                } else {
2971                    gids = new int[permGids.length + 2];
2972                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2973                }
2974                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2975                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2976            }
2977            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2978                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2979                        && mTopComponent != null
2980                        && app.processName.equals(mTopComponent.getPackageName())) {
2981                    uid = 0;
2982                }
2983                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2984                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2985                    uid = 0;
2986                }
2987            }
2988            int debugFlags = 0;
2989            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2990                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2991                // Also turn on CheckJNI for debuggable apps. It's quite
2992                // awkward to turn on otherwise.
2993                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2994            }
2995            // Run the app in safe mode if its manifest requests so or the
2996            // system is booted in safe mode.
2997            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2998                mSafeMode == true) {
2999                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3000            }
3001            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3002                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3003            }
3004            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3005                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3006            }
3007            if ("1".equals(SystemProperties.get("debug.assert"))) {
3008                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3009            }
3010
3011            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3012            if (requiredAbi == null) {
3013                requiredAbi = Build.SUPPORTED_ABIS[0];
3014            }
3015
3016            // Start the process.  It will either succeed and return a result containing
3017            // the PID of the new process, or else throw a RuntimeException.
3018            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
3019                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3020                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
3021
3022            if (app.isolated) {
3023                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3024            }
3025            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3026
3027            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3028                    UserHandle.getUserId(uid), startResult.pid, uid,
3029                    app.processName, hostingType,
3030                    hostingNameStr != null ? hostingNameStr : "");
3031
3032            if (app.persistent) {
3033                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3034            }
3035
3036            StringBuilder buf = mStringBuilder;
3037            buf.setLength(0);
3038            buf.append("Start proc ");
3039            buf.append(app.processName);
3040            buf.append(" for ");
3041            buf.append(hostingType);
3042            if (hostingNameStr != null) {
3043                buf.append(" ");
3044                buf.append(hostingNameStr);
3045            }
3046            buf.append(": pid=");
3047            buf.append(startResult.pid);
3048            buf.append(" uid=");
3049            buf.append(uid);
3050            buf.append(" gids={");
3051            if (gids != null) {
3052                for (int gi=0; gi<gids.length; gi++) {
3053                    if (gi != 0) buf.append(", ");
3054                    buf.append(gids[gi]);
3055
3056                }
3057            }
3058            buf.append("}");
3059            if (requiredAbi != null) {
3060                buf.append(" abi=");
3061                buf.append(requiredAbi);
3062            }
3063            Slog.i(TAG, buf.toString());
3064            app.setPid(startResult.pid);
3065            app.usingWrapper = startResult.usingWrapper;
3066            app.removed = false;
3067            app.killedByAm = false;
3068            synchronized (mPidsSelfLocked) {
3069                this.mPidsSelfLocked.put(startResult.pid, app);
3070                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3071                msg.obj = app;
3072                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3073                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3074            }
3075        } catch (RuntimeException e) {
3076            // XXX do better error recovery.
3077            app.setPid(0);
3078            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3079            if (app.isolated) {
3080                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3081            }
3082            Slog.e(TAG, "Failure starting process " + app.processName, e);
3083        }
3084    }
3085
3086    void updateUsageStats(ActivityRecord component, boolean resumed) {
3087        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3088        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3089        if (resumed) {
3090            mUsageStatsService.noteResumeComponent(component.realActivity);
3091            synchronized (stats) {
3092                stats.noteActivityResumedLocked(component.app.uid);
3093            }
3094        } else {
3095            mUsageStatsService.notePauseComponent(component.realActivity);
3096            synchronized (stats) {
3097                stats.noteActivityPausedLocked(component.app.uid);
3098            }
3099        }
3100    }
3101
3102    Intent getHomeIntent() {
3103        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3104        intent.setComponent(mTopComponent);
3105        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3106            intent.addCategory(Intent.CATEGORY_HOME);
3107        }
3108        return intent;
3109    }
3110
3111    boolean startHomeActivityLocked(int userId) {
3112        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3113                && mTopAction == null) {
3114            // We are running in factory test mode, but unable to find
3115            // the factory test app, so just sit around displaying the
3116            // error message and don't try to start anything.
3117            return false;
3118        }
3119        Intent intent = getHomeIntent();
3120        ActivityInfo aInfo =
3121            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3122        if (aInfo != null) {
3123            intent.setComponent(new ComponentName(
3124                    aInfo.applicationInfo.packageName, aInfo.name));
3125            // Don't do this if the home app is currently being
3126            // instrumented.
3127            aInfo = new ActivityInfo(aInfo);
3128            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3129            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3130                    aInfo.applicationInfo.uid, true);
3131            if (app == null || app.instrumentationClass == null) {
3132                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3133                mStackSupervisor.startHomeActivity(intent, aInfo);
3134            }
3135        }
3136
3137        return true;
3138    }
3139
3140    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3141        ActivityInfo ai = null;
3142        ComponentName comp = intent.getComponent();
3143        try {
3144            if (comp != null) {
3145                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3146            } else {
3147                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3148                        intent,
3149                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3150                            flags, userId);
3151
3152                if (info != null) {
3153                    ai = info.activityInfo;
3154                }
3155            }
3156        } catch (RemoteException e) {
3157            // ignore
3158        }
3159
3160        return ai;
3161    }
3162
3163    /**
3164     * Starts the "new version setup screen" if appropriate.
3165     */
3166    void startSetupActivityLocked() {
3167        // Only do this once per boot.
3168        if (mCheckedForSetup) {
3169            return;
3170        }
3171
3172        // We will show this screen if the current one is a different
3173        // version than the last one shown, and we are not running in
3174        // low-level factory test mode.
3175        final ContentResolver resolver = mContext.getContentResolver();
3176        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3177                Settings.Global.getInt(resolver,
3178                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3179            mCheckedForSetup = true;
3180
3181            // See if we should be showing the platform update setup UI.
3182            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3183            List<ResolveInfo> ris = mContext.getPackageManager()
3184                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3185
3186            // We don't allow third party apps to replace this.
3187            ResolveInfo ri = null;
3188            for (int i=0; ris != null && i<ris.size(); i++) {
3189                if ((ris.get(i).activityInfo.applicationInfo.flags
3190                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3191                    ri = ris.get(i);
3192                    break;
3193                }
3194            }
3195
3196            if (ri != null) {
3197                String vers = ri.activityInfo.metaData != null
3198                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3199                        : null;
3200                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3201                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3202                            Intent.METADATA_SETUP_VERSION);
3203                }
3204                String lastVers = Settings.Secure.getString(
3205                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3206                if (vers != null && !vers.equals(lastVers)) {
3207                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3208                    intent.setComponent(new ComponentName(
3209                            ri.activityInfo.packageName, ri.activityInfo.name));
3210                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3211                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3212                }
3213            }
3214        }
3215    }
3216
3217    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3218        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3219    }
3220
3221    void enforceNotIsolatedCaller(String caller) {
3222        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3223            throw new SecurityException("Isolated process not allowed to call " + caller);
3224        }
3225    }
3226
3227    @Override
3228    public int getFrontActivityScreenCompatMode() {
3229        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3230        synchronized (this) {
3231            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3232        }
3233    }
3234
3235    @Override
3236    public void setFrontActivityScreenCompatMode(int mode) {
3237        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3238                "setFrontActivityScreenCompatMode");
3239        synchronized (this) {
3240            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3241        }
3242    }
3243
3244    @Override
3245    public int getPackageScreenCompatMode(String packageName) {
3246        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3247        synchronized (this) {
3248            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3249        }
3250    }
3251
3252    @Override
3253    public void setPackageScreenCompatMode(String packageName, int mode) {
3254        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3255                "setPackageScreenCompatMode");
3256        synchronized (this) {
3257            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3258        }
3259    }
3260
3261    @Override
3262    public boolean getPackageAskScreenCompat(String packageName) {
3263        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3264        synchronized (this) {
3265            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3266        }
3267    }
3268
3269    @Override
3270    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3271        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3272                "setPackageAskScreenCompat");
3273        synchronized (this) {
3274            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3275        }
3276    }
3277
3278    private void dispatchProcessesChanged() {
3279        int N;
3280        synchronized (this) {
3281            N = mPendingProcessChanges.size();
3282            if (mActiveProcessChanges.length < N) {
3283                mActiveProcessChanges = new ProcessChangeItem[N];
3284            }
3285            mPendingProcessChanges.toArray(mActiveProcessChanges);
3286            mAvailProcessChanges.addAll(mPendingProcessChanges);
3287            mPendingProcessChanges.clear();
3288            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3289        }
3290
3291        int i = mProcessObservers.beginBroadcast();
3292        while (i > 0) {
3293            i--;
3294            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3295            if (observer != null) {
3296                try {
3297                    for (int j=0; j<N; j++) {
3298                        ProcessChangeItem item = mActiveProcessChanges[j];
3299                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3300                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3301                                    + item.pid + " uid=" + item.uid + ": "
3302                                    + item.foregroundActivities);
3303                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3304                                    item.foregroundActivities);
3305                        }
3306                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3307                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3308                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3309                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3310                        }
3311                    }
3312                } catch (RemoteException e) {
3313                }
3314            }
3315        }
3316        mProcessObservers.finishBroadcast();
3317    }
3318
3319    private void dispatchProcessDied(int pid, int uid) {
3320        int i = mProcessObservers.beginBroadcast();
3321        while (i > 0) {
3322            i--;
3323            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3324            if (observer != null) {
3325                try {
3326                    observer.onProcessDied(pid, uid);
3327                } catch (RemoteException e) {
3328                }
3329            }
3330        }
3331        mProcessObservers.finishBroadcast();
3332    }
3333
3334    final void doPendingActivityLaunchesLocked(boolean doResume) {
3335        final int N = mPendingActivityLaunches.size();
3336        if (N <= 0) {
3337            return;
3338        }
3339        for (int i=0; i<N; i++) {
3340            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3341            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3342                    doResume && i == (N-1), null);
3343        }
3344        mPendingActivityLaunches.clear();
3345    }
3346
3347    @Override
3348    public final int startActivity(IApplicationThread caller, String callingPackage,
3349            Intent intent, String resolvedType, IBinder resultTo,
3350            String resultWho, int requestCode, int startFlags,
3351            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3352        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3353                resultWho, requestCode,
3354                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3355    }
3356
3357    @Override
3358    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3359            Intent intent, String resolvedType, IBinder resultTo,
3360            String resultWho, int requestCode, int startFlags,
3361            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3362        enforceNotIsolatedCaller("startActivity");
3363        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3364                false, ALLOW_FULL_ONLY, "startActivity", null);
3365        // TODO: Switch to user app stacks here.
3366        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3367                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3368                null, null, options, userId, null);
3369    }
3370
3371    @Override
3372    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3373            Intent intent, String resolvedType, IBinder resultTo,
3374            String resultWho, int requestCode, int startFlags, String profileFile,
3375            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3376        enforceNotIsolatedCaller("startActivityAndWait");
3377        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3378                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3379        WaitResult res = new WaitResult();
3380        // TODO: Switch to user app stacks here.
3381        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3382                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3383                res, null, options, userId, null);
3384        return res;
3385    }
3386
3387    @Override
3388    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3389            Intent intent, String resolvedType, IBinder resultTo,
3390            String resultWho, int requestCode, int startFlags, Configuration config,
3391            Bundle options, int userId) {
3392        enforceNotIsolatedCaller("startActivityWithConfig");
3393        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3394                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3395        // TODO: Switch to user app stacks here.
3396        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3397                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3398                null, null, null, config, options, userId, null);
3399        return ret;
3400    }
3401
3402    @Override
3403    public int startActivityIntentSender(IApplicationThread caller,
3404            IntentSender intent, Intent fillInIntent, String resolvedType,
3405            IBinder resultTo, String resultWho, int requestCode,
3406            int flagsMask, int flagsValues, Bundle options) {
3407        enforceNotIsolatedCaller("startActivityIntentSender");
3408        // Refuse possible leaked file descriptors
3409        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3410            throw new IllegalArgumentException("File descriptors passed in Intent");
3411        }
3412
3413        IIntentSender sender = intent.getTarget();
3414        if (!(sender instanceof PendingIntentRecord)) {
3415            throw new IllegalArgumentException("Bad PendingIntent object");
3416        }
3417
3418        PendingIntentRecord pir = (PendingIntentRecord)sender;
3419
3420        synchronized (this) {
3421            // If this is coming from the currently resumed activity, it is
3422            // effectively saying that app switches are allowed at this point.
3423            final ActivityStack stack = getFocusedStack();
3424            if (stack.mResumedActivity != null &&
3425                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3426                mAppSwitchesAllowedTime = 0;
3427            }
3428        }
3429        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3430                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3431        return ret;
3432    }
3433
3434    @Override
3435    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3436            Intent intent, String resolvedType, IVoiceInteractionSession session,
3437            IVoiceInteractor interactor, int startFlags, String profileFile,
3438            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3439        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3440                != PackageManager.PERMISSION_GRANTED) {
3441            String msg = "Permission Denial: startVoiceActivity() from pid="
3442                    + Binder.getCallingPid()
3443                    + ", uid=" + Binder.getCallingUid()
3444                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3445            Slog.w(TAG, msg);
3446            throw new SecurityException(msg);
3447        }
3448        if (session == null || interactor == null) {
3449            throw new NullPointerException("null session or interactor");
3450        }
3451        userId = handleIncomingUser(callingPid, callingUid, userId,
3452                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3453        // TODO: Switch to user app stacks here.
3454        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3455                resolvedType, session, interactor, null, null, 0, startFlags,
3456                profileFile, profileFd, null, null, options, userId, null);
3457    }
3458
3459    @Override
3460    public boolean startNextMatchingActivity(IBinder callingActivity,
3461            Intent intent, Bundle options) {
3462        // Refuse possible leaked file descriptors
3463        if (intent != null && intent.hasFileDescriptors() == true) {
3464            throw new IllegalArgumentException("File descriptors passed in Intent");
3465        }
3466
3467        synchronized (this) {
3468            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3469            if (r == null) {
3470                ActivityOptions.abort(options);
3471                return false;
3472            }
3473            if (r.app == null || r.app.thread == null) {
3474                // The caller is not running...  d'oh!
3475                ActivityOptions.abort(options);
3476                return false;
3477            }
3478            intent = new Intent(intent);
3479            // The caller is not allowed to change the data.
3480            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3481            // And we are resetting to find the next component...
3482            intent.setComponent(null);
3483
3484            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3485
3486            ActivityInfo aInfo = null;
3487            try {
3488                List<ResolveInfo> resolves =
3489                    AppGlobals.getPackageManager().queryIntentActivities(
3490                            intent, r.resolvedType,
3491                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3492                            UserHandle.getCallingUserId());
3493
3494                // Look for the original activity in the list...
3495                final int N = resolves != null ? resolves.size() : 0;
3496                for (int i=0; i<N; i++) {
3497                    ResolveInfo rInfo = resolves.get(i);
3498                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3499                            && rInfo.activityInfo.name.equals(r.info.name)) {
3500                        // We found the current one...  the next matching is
3501                        // after it.
3502                        i++;
3503                        if (i<N) {
3504                            aInfo = resolves.get(i).activityInfo;
3505                        }
3506                        if (debug) {
3507                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3508                                    + "/" + r.info.name);
3509                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3510                                    + "/" + aInfo.name);
3511                        }
3512                        break;
3513                    }
3514                }
3515            } catch (RemoteException e) {
3516            }
3517
3518            if (aInfo == null) {
3519                // Nobody who is next!
3520                ActivityOptions.abort(options);
3521                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3522                return false;
3523            }
3524
3525            intent.setComponent(new ComponentName(
3526                    aInfo.applicationInfo.packageName, aInfo.name));
3527            intent.setFlags(intent.getFlags()&~(
3528                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3529                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3530                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3531                    Intent.FLAG_ACTIVITY_NEW_TASK));
3532
3533            // Okay now we need to start the new activity, replacing the
3534            // currently running activity.  This is a little tricky because
3535            // we want to start the new one as if the current one is finished,
3536            // but not finish the current one first so that there is no flicker.
3537            // And thus...
3538            final boolean wasFinishing = r.finishing;
3539            r.finishing = true;
3540
3541            // Propagate reply information over to the new activity.
3542            final ActivityRecord resultTo = r.resultTo;
3543            final String resultWho = r.resultWho;
3544            final int requestCode = r.requestCode;
3545            r.resultTo = null;
3546            if (resultTo != null) {
3547                resultTo.removeResultsLocked(r, resultWho, requestCode);
3548            }
3549
3550            final long origId = Binder.clearCallingIdentity();
3551            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3552                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3553                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3554                    options, false, null, null);
3555            Binder.restoreCallingIdentity(origId);
3556
3557            r.finishing = wasFinishing;
3558            if (res != ActivityManager.START_SUCCESS) {
3559                return false;
3560            }
3561            return true;
3562        }
3563    }
3564
3565    final int startActivityInPackage(int uid, String callingPackage,
3566            Intent intent, String resolvedType, IBinder resultTo,
3567            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3568                    IActivityContainer container) {
3569
3570        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3571                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3572
3573        // TODO: Switch to user app stacks here.
3574        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3575                null, null, resultTo, resultWho, requestCode, startFlags,
3576                null, null, null, null, options, userId, container);
3577        return ret;
3578    }
3579
3580    @Override
3581    public final int startActivities(IApplicationThread caller, String callingPackage,
3582            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3583            int userId) {
3584        enforceNotIsolatedCaller("startActivities");
3585        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3586                false, ALLOW_FULL_ONLY, "startActivity", null);
3587        // TODO: Switch to user app stacks here.
3588        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3589                resolvedTypes, resultTo, options, userId);
3590        return ret;
3591    }
3592
3593    final int startActivitiesInPackage(int uid, String callingPackage,
3594            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3595            Bundle options, int userId) {
3596
3597        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3598                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3599        // TODO: Switch to user app stacks here.
3600        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3601                resultTo, options, userId);
3602        return ret;
3603    }
3604
3605    final void addRecentTaskLocked(TaskRecord task) {
3606        int N = mRecentTasks.size();
3607        // Quick case: check if the top-most recent task is the same.
3608        if (N > 0 && mRecentTasks.get(0) == task) {
3609            return;
3610        }
3611        // Another quick case: never add voice sessions.
3612        if (task.voiceSession != null) {
3613            return;
3614        }
3615        // Remove any existing entries that are the same kind of task.
3616        final Intent intent = task.intent;
3617        final boolean document = intent != null && intent.isDocument();
3618        final ComponentName comp = intent.getComponent();
3619
3620        int maxRecents = task.maxRecents - 1;
3621        for (int i=0; i<N; i++) {
3622            final TaskRecord tr = mRecentTasks.get(i);
3623            if (task != tr) {
3624                if (task.userId != tr.userId) {
3625                    continue;
3626                }
3627                if (i > MAX_RECENT_BITMAPS) {
3628                    tr.freeLastThumbnail();
3629                }
3630                final Intent trIntent = tr.intent;
3631                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3632                    (intent == null || !intent.filterEquals(trIntent))) {
3633                    continue;
3634                }
3635                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3636                if (document && trIsDocument) {
3637                    // These are the same document activity (not necessarily the same doc).
3638                    if (maxRecents > 0) {
3639                        --maxRecents;
3640                        continue;
3641                    }
3642                    // Hit the maximum number of documents for this task. Fall through
3643                    // and remove this document from recents.
3644                } else if (document || trIsDocument) {
3645                    // Only one of these is a document. Not the droid we're looking for.
3646                    continue;
3647                }
3648            }
3649
3650            // Either task and tr are the same or, their affinities match or their intents match
3651            // and neither of them is a document, or they are documents using the same activity
3652            // and their maxRecents has been reached.
3653            tr.disposeThumbnail();
3654            mRecentTasks.remove(i);
3655            if (task != tr) {
3656                tr.closeRecentsChain();
3657            }
3658            i--;
3659            N--;
3660            if (task.intent == null) {
3661                // If the new recent task we are adding is not fully
3662                // specified, then replace it with the existing recent task.
3663                task = tr;
3664            }
3665            mTaskPersister.notify(tr, false);
3666        }
3667        if (N >= MAX_RECENT_TASKS) {
3668            final TaskRecord tr = mRecentTasks.remove(N - 1);
3669            tr.disposeThumbnail();
3670            tr.closeRecentsChain();
3671        }
3672        mRecentTasks.add(0, task);
3673    }
3674
3675    @Override
3676    public void reportActivityFullyDrawn(IBinder token) {
3677        synchronized (this) {
3678            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3679            if (r == null) {
3680                return;
3681            }
3682            r.reportFullyDrawnLocked();
3683        }
3684    }
3685
3686    @Override
3687    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3688        synchronized (this) {
3689            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3690            if (r == null) {
3691                return;
3692            }
3693            final long origId = Binder.clearCallingIdentity();
3694            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3695            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3696                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3697            if (config != null) {
3698                r.frozenBeforeDestroy = true;
3699                if (!updateConfigurationLocked(config, r, false, false)) {
3700                    mStackSupervisor.resumeTopActivitiesLocked();
3701                }
3702            }
3703            Binder.restoreCallingIdentity(origId);
3704        }
3705    }
3706
3707    @Override
3708    public int getRequestedOrientation(IBinder token) {
3709        synchronized (this) {
3710            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3711            if (r == null) {
3712                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3713            }
3714            return mWindowManager.getAppOrientation(r.appToken);
3715        }
3716    }
3717
3718    /**
3719     * This is the internal entry point for handling Activity.finish().
3720     *
3721     * @param token The Binder token referencing the Activity we want to finish.
3722     * @param resultCode Result code, if any, from this Activity.
3723     * @param resultData Result data (Intent), if any, from this Activity.
3724     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3725     *            the root Activity in the task.
3726     *
3727     * @return Returns true if the activity successfully finished, or false if it is still running.
3728     */
3729    @Override
3730    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3731            boolean finishTask) {
3732        // Refuse possible leaked file descriptors
3733        if (resultData != null && resultData.hasFileDescriptors() == true) {
3734            throw new IllegalArgumentException("File descriptors passed in Intent");
3735        }
3736
3737        synchronized(this) {
3738            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3739            if (r == null) {
3740                return true;
3741            }
3742            // Keep track of the root activity of the task before we finish it
3743            TaskRecord tr = r.task;
3744            ActivityRecord rootR = tr.getRootActivity();
3745            // Do not allow task to finish in Lock Task mode.
3746            if (tr == mStackSupervisor.mLockTaskModeTask) {
3747                if (rootR == r) {
3748                    mStackSupervisor.showLockTaskToast();
3749                    return false;
3750                }
3751            }
3752            if (mController != null) {
3753                // Find the first activity that is not finishing.
3754                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3755                if (next != null) {
3756                    // ask watcher if this is allowed
3757                    boolean resumeOK = true;
3758                    try {
3759                        resumeOK = mController.activityResuming(next.packageName);
3760                    } catch (RemoteException e) {
3761                        mController = null;
3762                        Watchdog.getInstance().setActivityController(null);
3763                    }
3764
3765                    if (!resumeOK) {
3766                        return false;
3767                    }
3768                }
3769            }
3770            final long origId = Binder.clearCallingIdentity();
3771            try {
3772                boolean res;
3773                if (finishTask && r == rootR) {
3774                    // If requested, remove the task that is associated to this activity only if it
3775                    // was the root activity in the task.  The result code and data is ignored because
3776                    // we don't support returning them across task boundaries.
3777                    res = removeTaskByIdLocked(tr.taskId, 0);
3778                } else {
3779                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3780                            resultData, "app-request", true);
3781                }
3782                return res;
3783            } finally {
3784                Binder.restoreCallingIdentity(origId);
3785            }
3786        }
3787    }
3788
3789    @Override
3790    public final void finishHeavyWeightApp() {
3791        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3792                != PackageManager.PERMISSION_GRANTED) {
3793            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3794                    + Binder.getCallingPid()
3795                    + ", uid=" + Binder.getCallingUid()
3796                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3797            Slog.w(TAG, msg);
3798            throw new SecurityException(msg);
3799        }
3800
3801        synchronized(this) {
3802            if (mHeavyWeightProcess == null) {
3803                return;
3804            }
3805
3806            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3807                    mHeavyWeightProcess.activities);
3808            for (int i=0; i<activities.size(); i++) {
3809                ActivityRecord r = activities.get(i);
3810                if (!r.finishing) {
3811                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3812                            null, "finish-heavy", true);
3813                }
3814            }
3815
3816            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3817                    mHeavyWeightProcess.userId, 0));
3818            mHeavyWeightProcess = null;
3819        }
3820    }
3821
3822    @Override
3823    public void crashApplication(int uid, int initialPid, String packageName,
3824            String message) {
3825        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3826                != PackageManager.PERMISSION_GRANTED) {
3827            String msg = "Permission Denial: crashApplication() from pid="
3828                    + Binder.getCallingPid()
3829                    + ", uid=" + Binder.getCallingUid()
3830                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3831            Slog.w(TAG, msg);
3832            throw new SecurityException(msg);
3833        }
3834
3835        synchronized(this) {
3836            ProcessRecord proc = null;
3837
3838            // Figure out which process to kill.  We don't trust that initialPid
3839            // still has any relation to current pids, so must scan through the
3840            // list.
3841            synchronized (mPidsSelfLocked) {
3842                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3843                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3844                    if (p.uid != uid) {
3845                        continue;
3846                    }
3847                    if (p.pid == initialPid) {
3848                        proc = p;
3849                        break;
3850                    }
3851                    if (p.pkgList.containsKey(packageName)) {
3852                        proc = p;
3853                    }
3854                }
3855            }
3856
3857            if (proc == null) {
3858                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3859                        + " initialPid=" + initialPid
3860                        + " packageName=" + packageName);
3861                return;
3862            }
3863
3864            if (proc.thread != null) {
3865                if (proc.pid == Process.myPid()) {
3866                    Log.w(TAG, "crashApplication: trying to crash self!");
3867                    return;
3868                }
3869                long ident = Binder.clearCallingIdentity();
3870                try {
3871                    proc.thread.scheduleCrash(message);
3872                } catch (RemoteException e) {
3873                }
3874                Binder.restoreCallingIdentity(ident);
3875            }
3876        }
3877    }
3878
3879    @Override
3880    public final void finishSubActivity(IBinder token, String resultWho,
3881            int requestCode) {
3882        synchronized(this) {
3883            final long origId = Binder.clearCallingIdentity();
3884            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3885            if (r != null) {
3886                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3887            }
3888            Binder.restoreCallingIdentity(origId);
3889        }
3890    }
3891
3892    @Override
3893    public boolean finishActivityAffinity(IBinder token) {
3894        synchronized(this) {
3895            final long origId = Binder.clearCallingIdentity();
3896            try {
3897                ActivityRecord r = ActivityRecord.isInStackLocked(token);
3898
3899                ActivityRecord rootR = r.task.getRootActivity();
3900                // Do not allow task to finish in Lock Task mode.
3901                if (r.task == mStackSupervisor.mLockTaskModeTask) {
3902                    if (rootR == r) {
3903                        mStackSupervisor.showLockTaskToast();
3904                        return false;
3905                    }
3906                }
3907                boolean res = false;
3908                if (r != null) {
3909                    res = r.task.stack.finishActivityAffinityLocked(r);
3910                }
3911                return res;
3912            } finally {
3913                Binder.restoreCallingIdentity(origId);
3914            }
3915        }
3916    }
3917
3918    @Override
3919    public void finishVoiceTask(IVoiceInteractionSession session) {
3920        synchronized(this) {
3921            final long origId = Binder.clearCallingIdentity();
3922            try {
3923                mStackSupervisor.finishVoiceTask(session);
3924            } finally {
3925                Binder.restoreCallingIdentity(origId);
3926            }
3927        }
3928
3929    }
3930
3931    @Override
3932    public boolean willActivityBeVisible(IBinder token) {
3933        synchronized(this) {
3934            ActivityStack stack = ActivityRecord.getStackLocked(token);
3935            if (stack != null) {
3936                return stack.willActivityBeVisibleLocked(token);
3937            }
3938            return false;
3939        }
3940    }
3941
3942    @Override
3943    public void overridePendingTransition(IBinder token, String packageName,
3944            int enterAnim, int exitAnim) {
3945        synchronized(this) {
3946            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3947            if (self == null) {
3948                return;
3949            }
3950
3951            final long origId = Binder.clearCallingIdentity();
3952
3953            if (self.state == ActivityState.RESUMED
3954                    || self.state == ActivityState.PAUSING) {
3955                mWindowManager.overridePendingAppTransition(packageName,
3956                        enterAnim, exitAnim, null);
3957            }
3958
3959            Binder.restoreCallingIdentity(origId);
3960        }
3961    }
3962
3963    /**
3964     * Main function for removing an existing process from the activity manager
3965     * as a result of that process going away.  Clears out all connections
3966     * to the process.
3967     */
3968    private final void handleAppDiedLocked(ProcessRecord app,
3969            boolean restarting, boolean allowRestart) {
3970        int pid = app.pid;
3971        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3972        if (!restarting) {
3973            removeLruProcessLocked(app);
3974            if (pid > 0) {
3975                ProcessList.remove(pid);
3976            }
3977        }
3978
3979        if (mProfileProc == app) {
3980            clearProfilerLocked();
3981        }
3982
3983        // Remove this application's activities from active lists.
3984        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3985
3986        app.activities.clear();
3987
3988        if (app.instrumentationClass != null) {
3989            Slog.w(TAG, "Crash of app " + app.processName
3990                  + " running instrumentation " + app.instrumentationClass);
3991            Bundle info = new Bundle();
3992            info.putString("shortMsg", "Process crashed.");
3993            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3994        }
3995
3996        if (!restarting) {
3997            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3998                // If there was nothing to resume, and we are not already
3999                // restarting this process, but there is a visible activity that
4000                // is hosted by the process...  then make sure all visible
4001                // activities are running, taking care of restarting this
4002                // process.
4003                if (hasVisibleActivities) {
4004                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4005                }
4006            }
4007        }
4008    }
4009
4010    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4011        IBinder threadBinder = thread.asBinder();
4012        // Find the application record.
4013        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4014            ProcessRecord rec = mLruProcesses.get(i);
4015            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4016                return i;
4017            }
4018        }
4019        return -1;
4020    }
4021
4022    final ProcessRecord getRecordForAppLocked(
4023            IApplicationThread thread) {
4024        if (thread == null) {
4025            return null;
4026        }
4027
4028        int appIndex = getLRURecordIndexForAppLocked(thread);
4029        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4030    }
4031
4032    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4033        // If there are no longer any background processes running,
4034        // and the app that died was not running instrumentation,
4035        // then tell everyone we are now low on memory.
4036        boolean haveBg = false;
4037        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4038            ProcessRecord rec = mLruProcesses.get(i);
4039            if (rec.thread != null
4040                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4041                haveBg = true;
4042                break;
4043            }
4044        }
4045
4046        if (!haveBg) {
4047            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4048            if (doReport) {
4049                long now = SystemClock.uptimeMillis();
4050                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4051                    doReport = false;
4052                } else {
4053                    mLastMemUsageReportTime = now;
4054                }
4055            }
4056            final ArrayList<ProcessMemInfo> memInfos
4057                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4058            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4059            long now = SystemClock.uptimeMillis();
4060            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4061                ProcessRecord rec = mLruProcesses.get(i);
4062                if (rec == dyingProc || rec.thread == null) {
4063                    continue;
4064                }
4065                if (doReport) {
4066                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4067                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4068                }
4069                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4070                    // The low memory report is overriding any current
4071                    // state for a GC request.  Make sure to do
4072                    // heavy/important/visible/foreground processes first.
4073                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4074                        rec.lastRequestedGc = 0;
4075                    } else {
4076                        rec.lastRequestedGc = rec.lastLowMemory;
4077                    }
4078                    rec.reportLowMemory = true;
4079                    rec.lastLowMemory = now;
4080                    mProcessesToGc.remove(rec);
4081                    addProcessToGcListLocked(rec);
4082                }
4083            }
4084            if (doReport) {
4085                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4086                mHandler.sendMessage(msg);
4087            }
4088            scheduleAppGcsLocked();
4089        }
4090    }
4091
4092    final void appDiedLocked(ProcessRecord app, int pid,
4093            IApplicationThread thread) {
4094
4095        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4096        synchronized (stats) {
4097            stats.noteProcessDiedLocked(app.info.uid, pid);
4098        }
4099
4100        Process.killProcessGroup(app.info.uid, pid);
4101
4102        // Clean up already done if the process has been re-started.
4103        if (app.pid == pid && app.thread != null &&
4104                app.thread.asBinder() == thread.asBinder()) {
4105            boolean doLowMem = app.instrumentationClass == null;
4106            boolean doOomAdj = doLowMem;
4107            if (!app.killedByAm) {
4108                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4109                        + ") has died.");
4110                mAllowLowerMemLevel = true;
4111            } else {
4112                // Note that we always want to do oom adj to update our state with the
4113                // new number of procs.
4114                mAllowLowerMemLevel = false;
4115                doLowMem = false;
4116            }
4117            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4118            if (DEBUG_CLEANUP) Slog.v(
4119                TAG, "Dying app: " + app + ", pid: " + pid
4120                + ", thread: " + thread.asBinder());
4121            handleAppDiedLocked(app, false, true);
4122
4123            if (doOomAdj) {
4124                updateOomAdjLocked();
4125            }
4126            if (doLowMem) {
4127                doLowMemReportIfNeededLocked(app);
4128            }
4129        } else if (app.pid != pid) {
4130            // A new process has already been started.
4131            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4132                    + ") has died and restarted (pid " + app.pid + ").");
4133            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4134        } else if (DEBUG_PROCESSES) {
4135            Slog.d(TAG, "Received spurious death notification for thread "
4136                    + thread.asBinder());
4137        }
4138    }
4139
4140    /**
4141     * If a stack trace dump file is configured, dump process stack traces.
4142     * @param clearTraces causes the dump file to be erased prior to the new
4143     *    traces being written, if true; when false, the new traces will be
4144     *    appended to any existing file content.
4145     * @param firstPids of dalvik VM processes to dump stack traces for first
4146     * @param lastPids of dalvik VM processes to dump stack traces for last
4147     * @param nativeProcs optional list of native process names to dump stack crawls
4148     * @return file containing stack traces, or null if no dump file is configured
4149     */
4150    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4151            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4152        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4153        if (tracesPath == null || tracesPath.length() == 0) {
4154            return null;
4155        }
4156
4157        File tracesFile = new File(tracesPath);
4158        try {
4159            File tracesDir = tracesFile.getParentFile();
4160            if (!tracesDir.exists()) {
4161                tracesFile.mkdirs();
4162                if (!SELinux.restorecon(tracesDir)) {
4163                    return null;
4164                }
4165            }
4166            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4167
4168            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4169            tracesFile.createNewFile();
4170            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4171        } catch (IOException e) {
4172            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4173            return null;
4174        }
4175
4176        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4177        return tracesFile;
4178    }
4179
4180    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4181            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4182        // Use a FileObserver to detect when traces finish writing.
4183        // The order of traces is considered important to maintain for legibility.
4184        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4185            @Override
4186            public synchronized void onEvent(int event, String path) { notify(); }
4187        };
4188
4189        try {
4190            observer.startWatching();
4191
4192            // First collect all of the stacks of the most important pids.
4193            if (firstPids != null) {
4194                try {
4195                    int num = firstPids.size();
4196                    for (int i = 0; i < num; i++) {
4197                        synchronized (observer) {
4198                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4199                            observer.wait(200);  // Wait for write-close, give up after 200msec
4200                        }
4201                    }
4202                } catch (InterruptedException e) {
4203                    Log.wtf(TAG, e);
4204                }
4205            }
4206
4207            // Next collect the stacks of the native pids
4208            if (nativeProcs != null) {
4209                int[] pids = Process.getPidsForCommands(nativeProcs);
4210                if (pids != null) {
4211                    for (int pid : pids) {
4212                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4213                    }
4214                }
4215            }
4216
4217            // Lastly, measure CPU usage.
4218            if (processCpuTracker != null) {
4219                processCpuTracker.init();
4220                System.gc();
4221                processCpuTracker.update();
4222                try {
4223                    synchronized (processCpuTracker) {
4224                        processCpuTracker.wait(500); // measure over 1/2 second.
4225                    }
4226                } catch (InterruptedException e) {
4227                }
4228                processCpuTracker.update();
4229
4230                // We'll take the stack crawls of just the top apps using CPU.
4231                final int N = processCpuTracker.countWorkingStats();
4232                int numProcs = 0;
4233                for (int i=0; i<N && numProcs<5; i++) {
4234                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4235                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4236                        numProcs++;
4237                        try {
4238                            synchronized (observer) {
4239                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4240                                observer.wait(200);  // Wait for write-close, give up after 200msec
4241                            }
4242                        } catch (InterruptedException e) {
4243                            Log.wtf(TAG, e);
4244                        }
4245
4246                    }
4247                }
4248            }
4249        } finally {
4250            observer.stopWatching();
4251        }
4252    }
4253
4254    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4255        if (true || IS_USER_BUILD) {
4256            return;
4257        }
4258        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4259        if (tracesPath == null || tracesPath.length() == 0) {
4260            return;
4261        }
4262
4263        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4264        StrictMode.allowThreadDiskWrites();
4265        try {
4266            final File tracesFile = new File(tracesPath);
4267            final File tracesDir = tracesFile.getParentFile();
4268            final File tracesTmp = new File(tracesDir, "__tmp__");
4269            try {
4270                if (!tracesDir.exists()) {
4271                    tracesFile.mkdirs();
4272                    if (!SELinux.restorecon(tracesDir.getPath())) {
4273                        return;
4274                    }
4275                }
4276                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4277
4278                if (tracesFile.exists()) {
4279                    tracesTmp.delete();
4280                    tracesFile.renameTo(tracesTmp);
4281                }
4282                StringBuilder sb = new StringBuilder();
4283                Time tobj = new Time();
4284                tobj.set(System.currentTimeMillis());
4285                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4286                sb.append(": ");
4287                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4288                sb.append(" since ");
4289                sb.append(msg);
4290                FileOutputStream fos = new FileOutputStream(tracesFile);
4291                fos.write(sb.toString().getBytes());
4292                if (app == null) {
4293                    fos.write("\n*** No application process!".getBytes());
4294                }
4295                fos.close();
4296                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4297            } catch (IOException e) {
4298                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4299                return;
4300            }
4301
4302            if (app != null) {
4303                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4304                firstPids.add(app.pid);
4305                dumpStackTraces(tracesPath, firstPids, null, null, null);
4306            }
4307
4308            File lastTracesFile = null;
4309            File curTracesFile = null;
4310            for (int i=9; i>=0; i--) {
4311                String name = String.format(Locale.US, "slow%02d.txt", i);
4312                curTracesFile = new File(tracesDir, name);
4313                if (curTracesFile.exists()) {
4314                    if (lastTracesFile != null) {
4315                        curTracesFile.renameTo(lastTracesFile);
4316                    } else {
4317                        curTracesFile.delete();
4318                    }
4319                }
4320                lastTracesFile = curTracesFile;
4321            }
4322            tracesFile.renameTo(curTracesFile);
4323            if (tracesTmp.exists()) {
4324                tracesTmp.renameTo(tracesFile);
4325            }
4326        } finally {
4327            StrictMode.setThreadPolicy(oldPolicy);
4328        }
4329    }
4330
4331    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4332            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4333        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4334        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4335
4336        if (mController != null) {
4337            try {
4338                // 0 == continue, -1 = kill process immediately
4339                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4340                if (res < 0 && app.pid != MY_PID) {
4341                    Process.killProcess(app.pid);
4342                    Process.killProcessGroup(app.info.uid, app.pid);
4343                }
4344            } catch (RemoteException e) {
4345                mController = null;
4346                Watchdog.getInstance().setActivityController(null);
4347            }
4348        }
4349
4350        long anrTime = SystemClock.uptimeMillis();
4351        if (MONITOR_CPU_USAGE) {
4352            updateCpuStatsNow();
4353        }
4354
4355        synchronized (this) {
4356            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4357            if (mShuttingDown) {
4358                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4359                return;
4360            } else if (app.notResponding) {
4361                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4362                return;
4363            } else if (app.crashing) {
4364                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4365                return;
4366            }
4367
4368            // In case we come through here for the same app before completing
4369            // this one, mark as anring now so we will bail out.
4370            app.notResponding = true;
4371
4372            // Log the ANR to the event log.
4373            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4374                    app.processName, app.info.flags, annotation);
4375
4376            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4377            firstPids.add(app.pid);
4378
4379            int parentPid = app.pid;
4380            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4381            if (parentPid != app.pid) firstPids.add(parentPid);
4382
4383            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4384
4385            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4386                ProcessRecord r = mLruProcesses.get(i);
4387                if (r != null && r.thread != null) {
4388                    int pid = r.pid;
4389                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4390                        if (r.persistent) {
4391                            firstPids.add(pid);
4392                        } else {
4393                            lastPids.put(pid, Boolean.TRUE);
4394                        }
4395                    }
4396                }
4397            }
4398        }
4399
4400        // Log the ANR to the main log.
4401        StringBuilder info = new StringBuilder();
4402        info.setLength(0);
4403        info.append("ANR in ").append(app.processName);
4404        if (activity != null && activity.shortComponentName != null) {
4405            info.append(" (").append(activity.shortComponentName).append(")");
4406        }
4407        info.append("\n");
4408        info.append("PID: ").append(app.pid).append("\n");
4409        if (annotation != null) {
4410            info.append("Reason: ").append(annotation).append("\n");
4411        }
4412        if (parent != null && parent != activity) {
4413            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4414        }
4415
4416        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4417
4418        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4419                NATIVE_STACKS_OF_INTEREST);
4420
4421        String cpuInfo = null;
4422        if (MONITOR_CPU_USAGE) {
4423            updateCpuStatsNow();
4424            synchronized (mProcessCpuThread) {
4425                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4426            }
4427            info.append(processCpuTracker.printCurrentLoad());
4428            info.append(cpuInfo);
4429        }
4430
4431        info.append(processCpuTracker.printCurrentState(anrTime));
4432
4433        Slog.e(TAG, info.toString());
4434        if (tracesFile == null) {
4435            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4436            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4437        }
4438
4439        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4440                cpuInfo, tracesFile, null);
4441
4442        if (mController != null) {
4443            try {
4444                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4445                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4446                if (res != 0) {
4447                    if (res < 0 && app.pid != MY_PID) {
4448                        Process.killProcess(app.pid);
4449                        Process.killProcessGroup(app.info.uid, app.pid);
4450                    } else {
4451                        synchronized (this) {
4452                            mServices.scheduleServiceTimeoutLocked(app);
4453                        }
4454                    }
4455                    return;
4456                }
4457            } catch (RemoteException e) {
4458                mController = null;
4459                Watchdog.getInstance().setActivityController(null);
4460            }
4461        }
4462
4463        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4464        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4465                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4466
4467        synchronized (this) {
4468            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4469                killUnneededProcessLocked(app, "background ANR");
4470                return;
4471            }
4472
4473            // Set the app's notResponding state, and look up the errorReportReceiver
4474            makeAppNotRespondingLocked(app,
4475                    activity != null ? activity.shortComponentName : null,
4476                    annotation != null ? "ANR " + annotation : "ANR",
4477                    info.toString());
4478
4479            // Bring up the infamous App Not Responding dialog
4480            Message msg = Message.obtain();
4481            HashMap<String, Object> map = new HashMap<String, Object>();
4482            msg.what = SHOW_NOT_RESPONDING_MSG;
4483            msg.obj = map;
4484            msg.arg1 = aboveSystem ? 1 : 0;
4485            map.put("app", app);
4486            if (activity != null) {
4487                map.put("activity", activity);
4488            }
4489
4490            mHandler.sendMessage(msg);
4491        }
4492    }
4493
4494    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4495        if (!mLaunchWarningShown) {
4496            mLaunchWarningShown = true;
4497            mHandler.post(new Runnable() {
4498                @Override
4499                public void run() {
4500                    synchronized (ActivityManagerService.this) {
4501                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4502                        d.show();
4503                        mHandler.postDelayed(new Runnable() {
4504                            @Override
4505                            public void run() {
4506                                synchronized (ActivityManagerService.this) {
4507                                    d.dismiss();
4508                                    mLaunchWarningShown = false;
4509                                }
4510                            }
4511                        }, 4000);
4512                    }
4513                }
4514            });
4515        }
4516    }
4517
4518    @Override
4519    public boolean clearApplicationUserData(final String packageName,
4520            final IPackageDataObserver observer, int userId) {
4521        enforceNotIsolatedCaller("clearApplicationUserData");
4522        int uid = Binder.getCallingUid();
4523        int pid = Binder.getCallingPid();
4524        userId = handleIncomingUser(pid, uid,
4525                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4526        long callingId = Binder.clearCallingIdentity();
4527        try {
4528            IPackageManager pm = AppGlobals.getPackageManager();
4529            int pkgUid = -1;
4530            synchronized(this) {
4531                try {
4532                    pkgUid = pm.getPackageUid(packageName, userId);
4533                } catch (RemoteException e) {
4534                }
4535                if (pkgUid == -1) {
4536                    Slog.w(TAG, "Invalid packageName: " + packageName);
4537                    if (observer != null) {
4538                        try {
4539                            observer.onRemoveCompleted(packageName, false);
4540                        } catch (RemoteException e) {
4541                            Slog.i(TAG, "Observer no longer exists.");
4542                        }
4543                    }
4544                    return false;
4545                }
4546                if (uid == pkgUid || checkComponentPermission(
4547                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4548                        pid, uid, -1, true)
4549                        == PackageManager.PERMISSION_GRANTED) {
4550                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4551                } else {
4552                    throw new SecurityException("PID " + pid + " does not have permission "
4553                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4554                                    + " of package " + packageName);
4555                }
4556            }
4557
4558            try {
4559                // Clear application user data
4560                pm.clearApplicationUserData(packageName, observer, userId);
4561
4562                // Remove all permissions granted from/to this package
4563                removeUriPermissionsForPackageLocked(packageName, userId, true);
4564
4565                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4566                        Uri.fromParts("package", packageName, null));
4567                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4568                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4569                        null, null, 0, null, null, null, false, false, userId);
4570            } catch (RemoteException e) {
4571            }
4572        } finally {
4573            Binder.restoreCallingIdentity(callingId);
4574        }
4575        return true;
4576    }
4577
4578    @Override
4579    public void killBackgroundProcesses(final String packageName, int userId) {
4580        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4581                != PackageManager.PERMISSION_GRANTED &&
4582                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4583                        != PackageManager.PERMISSION_GRANTED) {
4584            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4585                    + Binder.getCallingPid()
4586                    + ", uid=" + Binder.getCallingUid()
4587                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4588            Slog.w(TAG, msg);
4589            throw new SecurityException(msg);
4590        }
4591
4592        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4593                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4594        long callingId = Binder.clearCallingIdentity();
4595        try {
4596            IPackageManager pm = AppGlobals.getPackageManager();
4597            synchronized(this) {
4598                int appId = -1;
4599                try {
4600                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4601                } catch (RemoteException e) {
4602                }
4603                if (appId == -1) {
4604                    Slog.w(TAG, "Invalid packageName: " + packageName);
4605                    return;
4606                }
4607                killPackageProcessesLocked(packageName, appId, userId,
4608                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4609            }
4610        } finally {
4611            Binder.restoreCallingIdentity(callingId);
4612        }
4613    }
4614
4615    @Override
4616    public void killAllBackgroundProcesses() {
4617        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4618                != PackageManager.PERMISSION_GRANTED) {
4619            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4620                    + Binder.getCallingPid()
4621                    + ", uid=" + Binder.getCallingUid()
4622                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4623            Slog.w(TAG, msg);
4624            throw new SecurityException(msg);
4625        }
4626
4627        long callingId = Binder.clearCallingIdentity();
4628        try {
4629            synchronized(this) {
4630                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4631                final int NP = mProcessNames.getMap().size();
4632                for (int ip=0; ip<NP; ip++) {
4633                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4634                    final int NA = apps.size();
4635                    for (int ia=0; ia<NA; ia++) {
4636                        ProcessRecord app = apps.valueAt(ia);
4637                        if (app.persistent) {
4638                            // we don't kill persistent processes
4639                            continue;
4640                        }
4641                        if (app.removed) {
4642                            procs.add(app);
4643                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4644                            app.removed = true;
4645                            procs.add(app);
4646                        }
4647                    }
4648                }
4649
4650                int N = procs.size();
4651                for (int i=0; i<N; i++) {
4652                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4653                }
4654                mAllowLowerMemLevel = true;
4655                updateOomAdjLocked();
4656                doLowMemReportIfNeededLocked(null);
4657            }
4658        } finally {
4659            Binder.restoreCallingIdentity(callingId);
4660        }
4661    }
4662
4663    @Override
4664    public void forceStopPackage(final String packageName, int userId) {
4665        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4666                != PackageManager.PERMISSION_GRANTED) {
4667            String msg = "Permission Denial: forceStopPackage() from pid="
4668                    + Binder.getCallingPid()
4669                    + ", uid=" + Binder.getCallingUid()
4670                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4671            Slog.w(TAG, msg);
4672            throw new SecurityException(msg);
4673        }
4674        final int callingPid = Binder.getCallingPid();
4675        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4676                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4677        long callingId = Binder.clearCallingIdentity();
4678        try {
4679            IPackageManager pm = AppGlobals.getPackageManager();
4680            synchronized(this) {
4681                int[] users = userId == UserHandle.USER_ALL
4682                        ? getUsersLocked() : new int[] { userId };
4683                for (int user : users) {
4684                    int pkgUid = -1;
4685                    try {
4686                        pkgUid = pm.getPackageUid(packageName, user);
4687                    } catch (RemoteException e) {
4688                    }
4689                    if (pkgUid == -1) {
4690                        Slog.w(TAG, "Invalid packageName: " + packageName);
4691                        continue;
4692                    }
4693                    try {
4694                        pm.setPackageStoppedState(packageName, true, user);
4695                    } catch (RemoteException e) {
4696                    } catch (IllegalArgumentException e) {
4697                        Slog.w(TAG, "Failed trying to unstop package "
4698                                + packageName + ": " + e);
4699                    }
4700                    if (isUserRunningLocked(user, false)) {
4701                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4702                    }
4703                }
4704            }
4705        } finally {
4706            Binder.restoreCallingIdentity(callingId);
4707        }
4708    }
4709
4710    /*
4711     * The pkg name and app id have to be specified.
4712     */
4713    @Override
4714    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4715        if (pkg == null) {
4716            return;
4717        }
4718        // Make sure the uid is valid.
4719        if (appid < 0) {
4720            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4721            return;
4722        }
4723        int callerUid = Binder.getCallingUid();
4724        // Only the system server can kill an application
4725        if (callerUid == Process.SYSTEM_UID) {
4726            // Post an aysnc message to kill the application
4727            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4728            msg.arg1 = appid;
4729            msg.arg2 = 0;
4730            Bundle bundle = new Bundle();
4731            bundle.putString("pkg", pkg);
4732            bundle.putString("reason", reason);
4733            msg.obj = bundle;
4734            mHandler.sendMessage(msg);
4735        } else {
4736            throw new SecurityException(callerUid + " cannot kill pkg: " +
4737                    pkg);
4738        }
4739    }
4740
4741    @Override
4742    public void closeSystemDialogs(String reason) {
4743        enforceNotIsolatedCaller("closeSystemDialogs");
4744
4745        final int pid = Binder.getCallingPid();
4746        final int uid = Binder.getCallingUid();
4747        final long origId = Binder.clearCallingIdentity();
4748        try {
4749            synchronized (this) {
4750                // Only allow this from foreground processes, so that background
4751                // applications can't abuse it to prevent system UI from being shown.
4752                if (uid >= Process.FIRST_APPLICATION_UID) {
4753                    ProcessRecord proc;
4754                    synchronized (mPidsSelfLocked) {
4755                        proc = mPidsSelfLocked.get(pid);
4756                    }
4757                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4758                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4759                                + " from background process " + proc);
4760                        return;
4761                    }
4762                }
4763                closeSystemDialogsLocked(reason);
4764            }
4765        } finally {
4766            Binder.restoreCallingIdentity(origId);
4767        }
4768    }
4769
4770    void closeSystemDialogsLocked(String reason) {
4771        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4772        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4773                | Intent.FLAG_RECEIVER_FOREGROUND);
4774        if (reason != null) {
4775            intent.putExtra("reason", reason);
4776        }
4777        mWindowManager.closeSystemDialogs(reason);
4778
4779        mStackSupervisor.closeSystemDialogsLocked();
4780
4781        broadcastIntentLocked(null, null, intent, null,
4782                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4783                Process.SYSTEM_UID, UserHandle.USER_ALL);
4784    }
4785
4786    @Override
4787    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4788        enforceNotIsolatedCaller("getProcessMemoryInfo");
4789        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4790        for (int i=pids.length-1; i>=0; i--) {
4791            ProcessRecord proc;
4792            int oomAdj;
4793            synchronized (this) {
4794                synchronized (mPidsSelfLocked) {
4795                    proc = mPidsSelfLocked.get(pids[i]);
4796                    oomAdj = proc != null ? proc.setAdj : 0;
4797                }
4798            }
4799            infos[i] = new Debug.MemoryInfo();
4800            Debug.getMemoryInfo(pids[i], infos[i]);
4801            if (proc != null) {
4802                synchronized (this) {
4803                    if (proc.thread != null && proc.setAdj == oomAdj) {
4804                        // Record this for posterity if the process has been stable.
4805                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4806                                infos[i].getTotalUss(), false, proc.pkgList);
4807                    }
4808                }
4809            }
4810        }
4811        return infos;
4812    }
4813
4814    @Override
4815    public long[] getProcessPss(int[] pids) {
4816        enforceNotIsolatedCaller("getProcessPss");
4817        long[] pss = new long[pids.length];
4818        for (int i=pids.length-1; i>=0; i--) {
4819            ProcessRecord proc;
4820            int oomAdj;
4821            synchronized (this) {
4822                synchronized (mPidsSelfLocked) {
4823                    proc = mPidsSelfLocked.get(pids[i]);
4824                    oomAdj = proc != null ? proc.setAdj : 0;
4825                }
4826            }
4827            long[] tmpUss = new long[1];
4828            pss[i] = Debug.getPss(pids[i], tmpUss);
4829            if (proc != null) {
4830                synchronized (this) {
4831                    if (proc.thread != null && proc.setAdj == oomAdj) {
4832                        // Record this for posterity if the process has been stable.
4833                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4834                    }
4835                }
4836            }
4837        }
4838        return pss;
4839    }
4840
4841    @Override
4842    public void killApplicationProcess(String processName, int uid) {
4843        if (processName == null) {
4844            return;
4845        }
4846
4847        int callerUid = Binder.getCallingUid();
4848        // Only the system server can kill an application
4849        if (callerUid == Process.SYSTEM_UID) {
4850            synchronized (this) {
4851                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4852                if (app != null && app.thread != null) {
4853                    try {
4854                        app.thread.scheduleSuicide();
4855                    } catch (RemoteException e) {
4856                        // If the other end already died, then our work here is done.
4857                    }
4858                } else {
4859                    Slog.w(TAG, "Process/uid not found attempting kill of "
4860                            + processName + " / " + uid);
4861                }
4862            }
4863        } else {
4864            throw new SecurityException(callerUid + " cannot kill app process: " +
4865                    processName);
4866        }
4867    }
4868
4869    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4870        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4871                false, true, false, false, UserHandle.getUserId(uid), reason);
4872        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4873                Uri.fromParts("package", packageName, null));
4874        if (!mProcessesReady) {
4875            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4876                    | Intent.FLAG_RECEIVER_FOREGROUND);
4877        }
4878        intent.putExtra(Intent.EXTRA_UID, uid);
4879        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4880        broadcastIntentLocked(null, null, intent,
4881                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4882                false, false,
4883                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4884    }
4885
4886    private void forceStopUserLocked(int userId, String reason) {
4887        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4888        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4889        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4890                | Intent.FLAG_RECEIVER_FOREGROUND);
4891        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4892        broadcastIntentLocked(null, null, intent,
4893                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4894                false, false,
4895                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4896    }
4897
4898    private final boolean killPackageProcessesLocked(String packageName, int appId,
4899            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4900            boolean doit, boolean evenPersistent, String reason) {
4901        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4902
4903        // Remove all processes this package may have touched: all with the
4904        // same UID (except for the system or root user), and all whose name
4905        // matches the package name.
4906        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4907        final int NP = mProcessNames.getMap().size();
4908        for (int ip=0; ip<NP; ip++) {
4909            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4910            final int NA = apps.size();
4911            for (int ia=0; ia<NA; ia++) {
4912                ProcessRecord app = apps.valueAt(ia);
4913                if (app.persistent && !evenPersistent) {
4914                    // we don't kill persistent processes
4915                    continue;
4916                }
4917                if (app.removed) {
4918                    if (doit) {
4919                        procs.add(app);
4920                    }
4921                    continue;
4922                }
4923
4924                // Skip process if it doesn't meet our oom adj requirement.
4925                if (app.setAdj < minOomAdj) {
4926                    continue;
4927                }
4928
4929                // If no package is specified, we call all processes under the
4930                // give user id.
4931                if (packageName == null) {
4932                    if (app.userId != userId) {
4933                        continue;
4934                    }
4935                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4936                        continue;
4937                    }
4938                // Package has been specified, we want to hit all processes
4939                // that match it.  We need to qualify this by the processes
4940                // that are running under the specified app and user ID.
4941                } else {
4942                    if (UserHandle.getAppId(app.uid) != appId) {
4943                        continue;
4944                    }
4945                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4946                        continue;
4947                    }
4948                    if (!app.pkgList.containsKey(packageName)) {
4949                        continue;
4950                    }
4951                }
4952
4953                // Process has passed all conditions, kill it!
4954                if (!doit) {
4955                    return true;
4956                }
4957                app.removed = true;
4958                procs.add(app);
4959            }
4960        }
4961
4962        int N = procs.size();
4963        for (int i=0; i<N; i++) {
4964            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4965        }
4966        updateOomAdjLocked();
4967        return N > 0;
4968    }
4969
4970    private final boolean forceStopPackageLocked(String name, int appId,
4971            boolean callerWillRestart, boolean purgeCache, boolean doit,
4972            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4973        int i;
4974        int N;
4975
4976        if (userId == UserHandle.USER_ALL && name == null) {
4977            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4978        }
4979
4980        if (appId < 0 && name != null) {
4981            try {
4982                appId = UserHandle.getAppId(
4983                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4984            } catch (RemoteException e) {
4985            }
4986        }
4987
4988        if (doit) {
4989            if (name != null) {
4990                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4991                        + " user=" + userId + ": " + reason);
4992            } else {
4993                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4994            }
4995
4996            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4997            for (int ip=pmap.size()-1; ip>=0; ip--) {
4998                SparseArray<Long> ba = pmap.valueAt(ip);
4999                for (i=ba.size()-1; i>=0; i--) {
5000                    boolean remove = false;
5001                    final int entUid = ba.keyAt(i);
5002                    if (name != null) {
5003                        if (userId == UserHandle.USER_ALL) {
5004                            if (UserHandle.getAppId(entUid) == appId) {
5005                                remove = true;
5006                            }
5007                        } else {
5008                            if (entUid == UserHandle.getUid(userId, appId)) {
5009                                remove = true;
5010                            }
5011                        }
5012                    } else if (UserHandle.getUserId(entUid) == userId) {
5013                        remove = true;
5014                    }
5015                    if (remove) {
5016                        ba.removeAt(i);
5017                    }
5018                }
5019                if (ba.size() == 0) {
5020                    pmap.removeAt(ip);
5021                }
5022            }
5023        }
5024
5025        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5026                -100, callerWillRestart, true, doit, evenPersistent,
5027                name == null ? ("stop user " + userId) : ("stop " + name));
5028
5029        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5030            if (!doit) {
5031                return true;
5032            }
5033            didSomething = true;
5034        }
5035
5036        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5037            if (!doit) {
5038                return true;
5039            }
5040            didSomething = true;
5041        }
5042
5043        if (name == null) {
5044            // Remove all sticky broadcasts from this user.
5045            mStickyBroadcasts.remove(userId);
5046        }
5047
5048        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5049        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5050                userId, providers)) {
5051            if (!doit) {
5052                return true;
5053            }
5054            didSomething = true;
5055        }
5056        N = providers.size();
5057        for (i=0; i<N; i++) {
5058            removeDyingProviderLocked(null, providers.get(i), true);
5059        }
5060
5061        // Remove transient permissions granted from/to this package/user
5062        removeUriPermissionsForPackageLocked(name, userId, false);
5063
5064        if (name == null || uninstalling) {
5065            // Remove pending intents.  For now we only do this when force
5066            // stopping users, because we have some problems when doing this
5067            // for packages -- app widgets are not currently cleaned up for
5068            // such packages, so they can be left with bad pending intents.
5069            if (mIntentSenderRecords.size() > 0) {
5070                Iterator<WeakReference<PendingIntentRecord>> it
5071                        = mIntentSenderRecords.values().iterator();
5072                while (it.hasNext()) {
5073                    WeakReference<PendingIntentRecord> wpir = it.next();
5074                    if (wpir == null) {
5075                        it.remove();
5076                        continue;
5077                    }
5078                    PendingIntentRecord pir = wpir.get();
5079                    if (pir == null) {
5080                        it.remove();
5081                        continue;
5082                    }
5083                    if (name == null) {
5084                        // Stopping user, remove all objects for the user.
5085                        if (pir.key.userId != userId) {
5086                            // Not the same user, skip it.
5087                            continue;
5088                        }
5089                    } else {
5090                        if (UserHandle.getAppId(pir.uid) != appId) {
5091                            // Different app id, skip it.
5092                            continue;
5093                        }
5094                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5095                            // Different user, skip it.
5096                            continue;
5097                        }
5098                        if (!pir.key.packageName.equals(name)) {
5099                            // Different package, skip it.
5100                            continue;
5101                        }
5102                    }
5103                    if (!doit) {
5104                        return true;
5105                    }
5106                    didSomething = true;
5107                    it.remove();
5108                    pir.canceled = true;
5109                    if (pir.key.activity != null) {
5110                        pir.key.activity.pendingResults.remove(pir.ref);
5111                    }
5112                }
5113            }
5114        }
5115
5116        if (doit) {
5117            if (purgeCache && name != null) {
5118                AttributeCache ac = AttributeCache.instance();
5119                if (ac != null) {
5120                    ac.removePackage(name);
5121                }
5122            }
5123            if (mBooted) {
5124                mStackSupervisor.resumeTopActivitiesLocked();
5125                mStackSupervisor.scheduleIdleLocked();
5126            }
5127        }
5128
5129        return didSomething;
5130    }
5131
5132    private final boolean removeProcessLocked(ProcessRecord app,
5133            boolean callerWillRestart, boolean allowRestart, String reason) {
5134        final String name = app.processName;
5135        final int uid = app.uid;
5136        if (DEBUG_PROCESSES) Slog.d(
5137            TAG, "Force removing proc " + app.toShortString() + " (" + name
5138            + "/" + uid + ")");
5139
5140        mProcessNames.remove(name, uid);
5141        mIsolatedProcesses.remove(app.uid);
5142        if (mHeavyWeightProcess == app) {
5143            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5144                    mHeavyWeightProcess.userId, 0));
5145            mHeavyWeightProcess = null;
5146        }
5147        boolean needRestart = false;
5148        if (app.pid > 0 && app.pid != MY_PID) {
5149            int pid = app.pid;
5150            synchronized (mPidsSelfLocked) {
5151                mPidsSelfLocked.remove(pid);
5152                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5153            }
5154            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5155            if (app.isolated) {
5156                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5157            }
5158            killUnneededProcessLocked(app, reason);
5159            Process.killProcessGroup(app.info.uid, app.pid);
5160            handleAppDiedLocked(app, true, allowRestart);
5161            removeLruProcessLocked(app);
5162
5163            if (app.persistent && !app.isolated) {
5164                if (!callerWillRestart) {
5165                    addAppLocked(app.info, false, null /* ABI override */);
5166                } else {
5167                    needRestart = true;
5168                }
5169            }
5170        } else {
5171            mRemovedProcesses.add(app);
5172        }
5173
5174        return needRestart;
5175    }
5176
5177    private final void processStartTimedOutLocked(ProcessRecord app) {
5178        final int pid = app.pid;
5179        boolean gone = false;
5180        synchronized (mPidsSelfLocked) {
5181            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5182            if (knownApp != null && knownApp.thread == null) {
5183                mPidsSelfLocked.remove(pid);
5184                gone = true;
5185            }
5186        }
5187
5188        if (gone) {
5189            Slog.w(TAG, "Process " + app + " failed to attach");
5190            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5191                    pid, app.uid, app.processName);
5192            mProcessNames.remove(app.processName, app.uid);
5193            mIsolatedProcesses.remove(app.uid);
5194            if (mHeavyWeightProcess == app) {
5195                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5196                        mHeavyWeightProcess.userId, 0));
5197                mHeavyWeightProcess = null;
5198            }
5199            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5200            if (app.isolated) {
5201                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5202            }
5203            // Take care of any launching providers waiting for this process.
5204            checkAppInLaunchingProvidersLocked(app, true);
5205            // Take care of any services that are waiting for the process.
5206            mServices.processStartTimedOutLocked(app);
5207            killUnneededProcessLocked(app, "start timeout");
5208            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5209                Slog.w(TAG, "Unattached app died before backup, skipping");
5210                try {
5211                    IBackupManager bm = IBackupManager.Stub.asInterface(
5212                            ServiceManager.getService(Context.BACKUP_SERVICE));
5213                    bm.agentDisconnected(app.info.packageName);
5214                } catch (RemoteException e) {
5215                    // Can't happen; the backup manager is local
5216                }
5217            }
5218            if (isPendingBroadcastProcessLocked(pid)) {
5219                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5220                skipPendingBroadcastLocked(pid);
5221            }
5222        } else {
5223            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5224        }
5225    }
5226
5227    private final boolean attachApplicationLocked(IApplicationThread thread,
5228            int pid) {
5229
5230        // Find the application record that is being attached...  either via
5231        // the pid if we are running in multiple processes, or just pull the
5232        // next app record if we are emulating process with anonymous threads.
5233        ProcessRecord app;
5234        if (pid != MY_PID && pid >= 0) {
5235            synchronized (mPidsSelfLocked) {
5236                app = mPidsSelfLocked.get(pid);
5237            }
5238        } else {
5239            app = null;
5240        }
5241
5242        if (app == null) {
5243            Slog.w(TAG, "No pending application record for pid " + pid
5244                    + " (IApplicationThread " + thread + "); dropping process");
5245            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5246            if (pid > 0 && pid != MY_PID) {
5247                Process.killProcessQuiet(pid);
5248                //TODO: Process.killProcessGroup(app.info.uid, pid);
5249            } else {
5250                try {
5251                    thread.scheduleExit();
5252                } catch (Exception e) {
5253                    // Ignore exceptions.
5254                }
5255            }
5256            return false;
5257        }
5258
5259        // If this application record is still attached to a previous
5260        // process, clean it up now.
5261        if (app.thread != null) {
5262            handleAppDiedLocked(app, true, true);
5263        }
5264
5265        // Tell the process all about itself.
5266
5267        if (localLOGV) Slog.v(
5268                TAG, "Binding process pid " + pid + " to record " + app);
5269
5270        final String processName = app.processName;
5271        try {
5272            AppDeathRecipient adr = new AppDeathRecipient(
5273                    app, pid, thread);
5274            thread.asBinder().linkToDeath(adr, 0);
5275            app.deathRecipient = adr;
5276        } catch (RemoteException e) {
5277            app.resetPackageList(mProcessStats);
5278            startProcessLocked(app, "link fail", processName, null /* ABI override */);
5279            return false;
5280        }
5281
5282        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5283
5284        app.makeActive(thread, mProcessStats);
5285        app.curAdj = app.setAdj = -100;
5286        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5287        app.forcingToForeground = null;
5288        updateProcessForegroundLocked(app, false, false);
5289        app.hasShownUi = false;
5290        app.debugging = false;
5291        app.cached = false;
5292
5293        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5294
5295        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5296        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5297
5298        if (!normalMode) {
5299            Slog.i(TAG, "Launching preboot mode app: " + app);
5300        }
5301
5302        if (localLOGV) Slog.v(
5303            TAG, "New app record " + app
5304            + " thread=" + thread.asBinder() + " pid=" + pid);
5305        try {
5306            int testMode = IApplicationThread.DEBUG_OFF;
5307            if (mDebugApp != null && mDebugApp.equals(processName)) {
5308                testMode = mWaitForDebugger
5309                    ? IApplicationThread.DEBUG_WAIT
5310                    : IApplicationThread.DEBUG_ON;
5311                app.debugging = true;
5312                if (mDebugTransient) {
5313                    mDebugApp = mOrigDebugApp;
5314                    mWaitForDebugger = mOrigWaitForDebugger;
5315                }
5316            }
5317            String profileFile = app.instrumentationProfileFile;
5318            ParcelFileDescriptor profileFd = null;
5319            boolean profileAutoStop = false;
5320            if (mProfileApp != null && mProfileApp.equals(processName)) {
5321                mProfileProc = app;
5322                profileFile = mProfileFile;
5323                profileFd = mProfileFd;
5324                profileAutoStop = mAutoStopProfiler;
5325            }
5326            boolean enableOpenGlTrace = false;
5327            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5328                enableOpenGlTrace = true;
5329                mOpenGlTraceApp = null;
5330            }
5331
5332            // If the app is being launched for restore or full backup, set it up specially
5333            boolean isRestrictedBackupMode = false;
5334            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5335                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5336                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5337                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5338            }
5339
5340            ensurePackageDexOpt(app.instrumentationInfo != null
5341                    ? app.instrumentationInfo.packageName
5342                    : app.info.packageName);
5343            if (app.instrumentationClass != null) {
5344                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5345            }
5346            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5347                    + processName + " with config " + mConfiguration);
5348            ApplicationInfo appInfo = app.instrumentationInfo != null
5349                    ? app.instrumentationInfo : app.info;
5350            app.compat = compatibilityInfoForPackageLocked(appInfo);
5351            if (profileFd != null) {
5352                profileFd = profileFd.dup();
5353            }
5354            thread.bindApplication(processName, appInfo, providers,
5355                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5356                    app.instrumentationArguments, app.instrumentationWatcher,
5357                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5358                    isRestrictedBackupMode || !normalMode, app.persistent,
5359                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5360                    mCoreSettingsObserver.getCoreSettingsLocked());
5361            updateLruProcessLocked(app, false, null);
5362            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5363        } catch (Exception e) {
5364            // todo: Yikes!  What should we do?  For now we will try to
5365            // start another process, but that could easily get us in
5366            // an infinite loop of restarting processes...
5367            Slog.w(TAG, "Exception thrown during bind!", e);
5368
5369            app.resetPackageList(mProcessStats);
5370            app.unlinkDeathRecipient();
5371            startProcessLocked(app, "bind fail", processName, null /* ABI override */);
5372            return false;
5373        }
5374
5375        // Remove this record from the list of starting applications.
5376        mPersistentStartingProcesses.remove(app);
5377        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5378                "Attach application locked removing on hold: " + app);
5379        mProcessesOnHold.remove(app);
5380
5381        boolean badApp = false;
5382        boolean didSomething = false;
5383
5384        // See if the top visible activity is waiting to run in this process...
5385        if (normalMode) {
5386            try {
5387                if (mStackSupervisor.attachApplicationLocked(app)) {
5388                    didSomething = true;
5389                }
5390            } catch (Exception e) {
5391                badApp = true;
5392            }
5393        }
5394
5395        // Find any services that should be running in this process...
5396        if (!badApp) {
5397            try {
5398                didSomething |= mServices.attachApplicationLocked(app, processName);
5399            } catch (Exception e) {
5400                badApp = true;
5401            }
5402        }
5403
5404        // Check if a next-broadcast receiver is in this process...
5405        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5406            try {
5407                didSomething |= sendPendingBroadcastsLocked(app);
5408            } catch (Exception e) {
5409                // If the app died trying to launch the receiver we declare it 'bad'
5410                badApp = true;
5411            }
5412        }
5413
5414        // Check whether the next backup agent is in this process...
5415        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5416            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5417            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5418            try {
5419                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5420                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5421                        mBackupTarget.backupMode);
5422            } catch (Exception e) {
5423                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5424                e.printStackTrace();
5425            }
5426        }
5427
5428        if (badApp) {
5429            // todo: Also need to kill application to deal with all
5430            // kinds of exceptions.
5431            handleAppDiedLocked(app, false, true);
5432            return false;
5433        }
5434
5435        if (!didSomething) {
5436            updateOomAdjLocked();
5437        }
5438
5439        return true;
5440    }
5441
5442    @Override
5443    public final void attachApplication(IApplicationThread thread) {
5444        synchronized (this) {
5445            int callingPid = Binder.getCallingPid();
5446            final long origId = Binder.clearCallingIdentity();
5447            attachApplicationLocked(thread, callingPid);
5448            Binder.restoreCallingIdentity(origId);
5449        }
5450    }
5451
5452    @Override
5453    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5454        final long origId = Binder.clearCallingIdentity();
5455        synchronized (this) {
5456            ActivityStack stack = ActivityRecord.getStackLocked(token);
5457            if (stack != null) {
5458                ActivityRecord r =
5459                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5460                if (stopProfiling) {
5461                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5462                        try {
5463                            mProfileFd.close();
5464                        } catch (IOException e) {
5465                        }
5466                        clearProfilerLocked();
5467                    }
5468                }
5469            }
5470        }
5471        Binder.restoreCallingIdentity(origId);
5472    }
5473
5474    void enableScreenAfterBoot() {
5475        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5476                SystemClock.uptimeMillis());
5477        mWindowManager.enableScreenAfterBoot();
5478
5479        synchronized (this) {
5480            updateEventDispatchingLocked();
5481        }
5482    }
5483
5484    @Override
5485    public void showBootMessage(final CharSequence msg, final boolean always) {
5486        enforceNotIsolatedCaller("showBootMessage");
5487        mWindowManager.showBootMessage(msg, always);
5488    }
5489
5490    @Override
5491    public void dismissKeyguardOnNextActivity() {
5492        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5493        final long token = Binder.clearCallingIdentity();
5494        try {
5495            synchronized (this) {
5496                if (DEBUG_LOCKSCREEN) logLockScreen("");
5497                if (mLockScreenShown) {
5498                    mLockScreenShown = false;
5499                    comeOutOfSleepIfNeededLocked();
5500                }
5501                mStackSupervisor.setDismissKeyguard(true);
5502            }
5503        } finally {
5504            Binder.restoreCallingIdentity(token);
5505        }
5506    }
5507
5508    final void finishBooting() {
5509        // Register receivers to handle package update events
5510        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5511
5512        synchronized (this) {
5513            // Ensure that any processes we had put on hold are now started
5514            // up.
5515            final int NP = mProcessesOnHold.size();
5516            if (NP > 0) {
5517                ArrayList<ProcessRecord> procs =
5518                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5519                for (int ip=0; ip<NP; ip++) {
5520                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5521                            + procs.get(ip));
5522                    startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */);
5523                }
5524            }
5525
5526            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5527                // Start looking for apps that are abusing wake locks.
5528                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5529                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5530                // Tell anyone interested that we are done booting!
5531                SystemProperties.set("sys.boot_completed", "1");
5532                SystemProperties.set("dev.bootcomplete", "1");
5533                for (int i=0; i<mStartedUsers.size(); i++) {
5534                    UserStartedState uss = mStartedUsers.valueAt(i);
5535                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5536                        uss.mState = UserStartedState.STATE_RUNNING;
5537                        final int userId = mStartedUsers.keyAt(i);
5538                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5539                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5540                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5541                        broadcastIntentLocked(null, null, intent, null,
5542                                new IIntentReceiver.Stub() {
5543                                    @Override
5544                                    public void performReceive(Intent intent, int resultCode,
5545                                            String data, Bundle extras, boolean ordered,
5546                                            boolean sticky, int sendingUser) {
5547                                        synchronized (ActivityManagerService.this) {
5548                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5549                                                    true, false);
5550                                        }
5551                                    }
5552                                },
5553                                0, null, null,
5554                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5555                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5556                                userId);
5557                    }
5558                }
5559                scheduleStartProfilesLocked();
5560            }
5561        }
5562    }
5563
5564    final void ensureBootCompleted() {
5565        boolean booting;
5566        boolean enableScreen;
5567        synchronized (this) {
5568            booting = mBooting;
5569            mBooting = false;
5570            enableScreen = !mBooted;
5571            mBooted = true;
5572        }
5573
5574        if (booting) {
5575            finishBooting();
5576        }
5577
5578        if (enableScreen) {
5579            enableScreenAfterBoot();
5580        }
5581    }
5582
5583    @Override
5584    public final void activityResumed(IBinder token) {
5585        final long origId = Binder.clearCallingIdentity();
5586        synchronized(this) {
5587            ActivityStack stack = ActivityRecord.getStackLocked(token);
5588            if (stack != null) {
5589                ActivityRecord.activityResumedLocked(token);
5590            }
5591        }
5592        Binder.restoreCallingIdentity(origId);
5593    }
5594
5595    @Override
5596    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5597        final long origId = Binder.clearCallingIdentity();
5598        synchronized(this) {
5599            ActivityStack stack = ActivityRecord.getStackLocked(token);
5600            if (stack != null) {
5601                stack.activityPausedLocked(token, false, persistentState);
5602            }
5603        }
5604        Binder.restoreCallingIdentity(origId);
5605    }
5606
5607    @Override
5608    public final void activityStopped(IBinder token, Bundle icicle,
5609            PersistableBundle persistentState, CharSequence description) {
5610        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5611
5612        // Refuse possible leaked file descriptors
5613        if (icicle != null && icicle.hasFileDescriptors()) {
5614            throw new IllegalArgumentException("File descriptors passed in Bundle");
5615        }
5616
5617        final long origId = Binder.clearCallingIdentity();
5618
5619        synchronized (this) {
5620            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5621            if (r != null) {
5622                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5623            }
5624        }
5625
5626        trimApplications();
5627
5628        Binder.restoreCallingIdentity(origId);
5629    }
5630
5631    @Override
5632    public final void activityDestroyed(IBinder token) {
5633        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5634        synchronized (this) {
5635            ActivityStack stack = ActivityRecord.getStackLocked(token);
5636            if (stack != null) {
5637                stack.activityDestroyedLocked(token);
5638            }
5639        }
5640    }
5641
5642    @Override
5643    public final void mediaResourcesReleased(IBinder token) {
5644        final long origId = Binder.clearCallingIdentity();
5645        try {
5646            synchronized (this) {
5647                ActivityStack stack = ActivityRecord.getStackLocked(token);
5648                if (stack != null) {
5649                    stack.mediaResourcesReleased(token);
5650                }
5651            }
5652        } finally {
5653            Binder.restoreCallingIdentity(origId);
5654        }
5655    }
5656
5657    @Override
5658    public final void notifyLaunchTaskBehindComplete(IBinder token) {
5659        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
5660    }
5661
5662    @Override
5663    public String getCallingPackage(IBinder token) {
5664        synchronized (this) {
5665            ActivityRecord r = getCallingRecordLocked(token);
5666            return r != null ? r.info.packageName : null;
5667        }
5668    }
5669
5670    @Override
5671    public ComponentName getCallingActivity(IBinder token) {
5672        synchronized (this) {
5673            ActivityRecord r = getCallingRecordLocked(token);
5674            return r != null ? r.intent.getComponent() : null;
5675        }
5676    }
5677
5678    private ActivityRecord getCallingRecordLocked(IBinder token) {
5679        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5680        if (r == null) {
5681            return null;
5682        }
5683        return r.resultTo;
5684    }
5685
5686    @Override
5687    public ComponentName getActivityClassForToken(IBinder token) {
5688        synchronized(this) {
5689            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5690            if (r == null) {
5691                return null;
5692            }
5693            return r.intent.getComponent();
5694        }
5695    }
5696
5697    @Override
5698    public String getPackageForToken(IBinder token) {
5699        synchronized(this) {
5700            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5701            if (r == null) {
5702                return null;
5703            }
5704            return r.packageName;
5705        }
5706    }
5707
5708    @Override
5709    public IIntentSender getIntentSender(int type,
5710            String packageName, IBinder token, String resultWho,
5711            int requestCode, Intent[] intents, String[] resolvedTypes,
5712            int flags, Bundle options, int userId) {
5713        enforceNotIsolatedCaller("getIntentSender");
5714        // Refuse possible leaked file descriptors
5715        if (intents != null) {
5716            if (intents.length < 1) {
5717                throw new IllegalArgumentException("Intents array length must be >= 1");
5718            }
5719            for (int i=0; i<intents.length; i++) {
5720                Intent intent = intents[i];
5721                if (intent != null) {
5722                    if (intent.hasFileDescriptors()) {
5723                        throw new IllegalArgumentException("File descriptors passed in Intent");
5724                    }
5725                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5726                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5727                        throw new IllegalArgumentException(
5728                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5729                    }
5730                    intents[i] = new Intent(intent);
5731                }
5732            }
5733            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5734                throw new IllegalArgumentException(
5735                        "Intent array length does not match resolvedTypes length");
5736            }
5737        }
5738        if (options != null) {
5739            if (options.hasFileDescriptors()) {
5740                throw new IllegalArgumentException("File descriptors passed in options");
5741            }
5742        }
5743
5744        synchronized(this) {
5745            int callingUid = Binder.getCallingUid();
5746            int origUserId = userId;
5747            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5748                    type == ActivityManager.INTENT_SENDER_BROADCAST,
5749                    ALLOW_NON_FULL, "getIntentSender", null);
5750            if (origUserId == UserHandle.USER_CURRENT) {
5751                // We don't want to evaluate this until the pending intent is
5752                // actually executed.  However, we do want to always do the
5753                // security checking for it above.
5754                userId = UserHandle.USER_CURRENT;
5755            }
5756            try {
5757                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5758                    int uid = AppGlobals.getPackageManager()
5759                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5760                    if (!UserHandle.isSameApp(callingUid, uid)) {
5761                        String msg = "Permission Denial: getIntentSender() from pid="
5762                            + Binder.getCallingPid()
5763                            + ", uid=" + Binder.getCallingUid()
5764                            + ", (need uid=" + uid + ")"
5765                            + " is not allowed to send as package " + packageName;
5766                        Slog.w(TAG, msg);
5767                        throw new SecurityException(msg);
5768                    }
5769                }
5770
5771                return getIntentSenderLocked(type, packageName, callingUid, userId,
5772                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5773
5774            } catch (RemoteException e) {
5775                throw new SecurityException(e);
5776            }
5777        }
5778    }
5779
5780    IIntentSender getIntentSenderLocked(int type, String packageName,
5781            int callingUid, int userId, IBinder token, String resultWho,
5782            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5783            Bundle options) {
5784        if (DEBUG_MU)
5785            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5786        ActivityRecord activity = null;
5787        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5788            activity = ActivityRecord.isInStackLocked(token);
5789            if (activity == null) {
5790                return null;
5791            }
5792            if (activity.finishing) {
5793                return null;
5794            }
5795        }
5796
5797        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5798        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5799        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5800        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5801                |PendingIntent.FLAG_UPDATE_CURRENT);
5802
5803        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5804                type, packageName, activity, resultWho,
5805                requestCode, intents, resolvedTypes, flags, options, userId);
5806        WeakReference<PendingIntentRecord> ref;
5807        ref = mIntentSenderRecords.get(key);
5808        PendingIntentRecord rec = ref != null ? ref.get() : null;
5809        if (rec != null) {
5810            if (!cancelCurrent) {
5811                if (updateCurrent) {
5812                    if (rec.key.requestIntent != null) {
5813                        rec.key.requestIntent.replaceExtras(intents != null ?
5814                                intents[intents.length - 1] : null);
5815                    }
5816                    if (intents != null) {
5817                        intents[intents.length-1] = rec.key.requestIntent;
5818                        rec.key.allIntents = intents;
5819                        rec.key.allResolvedTypes = resolvedTypes;
5820                    } else {
5821                        rec.key.allIntents = null;
5822                        rec.key.allResolvedTypes = null;
5823                    }
5824                }
5825                return rec;
5826            }
5827            rec.canceled = true;
5828            mIntentSenderRecords.remove(key);
5829        }
5830        if (noCreate) {
5831            return rec;
5832        }
5833        rec = new PendingIntentRecord(this, key, callingUid);
5834        mIntentSenderRecords.put(key, rec.ref);
5835        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5836            if (activity.pendingResults == null) {
5837                activity.pendingResults
5838                        = new HashSet<WeakReference<PendingIntentRecord>>();
5839            }
5840            activity.pendingResults.add(rec.ref);
5841        }
5842        return rec;
5843    }
5844
5845    @Override
5846    public void cancelIntentSender(IIntentSender sender) {
5847        if (!(sender instanceof PendingIntentRecord)) {
5848            return;
5849        }
5850        synchronized(this) {
5851            PendingIntentRecord rec = (PendingIntentRecord)sender;
5852            try {
5853                int uid = AppGlobals.getPackageManager()
5854                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5855                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5856                    String msg = "Permission Denial: cancelIntentSender() from pid="
5857                        + Binder.getCallingPid()
5858                        + ", uid=" + Binder.getCallingUid()
5859                        + " is not allowed to cancel packges "
5860                        + rec.key.packageName;
5861                    Slog.w(TAG, msg);
5862                    throw new SecurityException(msg);
5863                }
5864            } catch (RemoteException e) {
5865                throw new SecurityException(e);
5866            }
5867            cancelIntentSenderLocked(rec, true);
5868        }
5869    }
5870
5871    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5872        rec.canceled = true;
5873        mIntentSenderRecords.remove(rec.key);
5874        if (cleanActivity && rec.key.activity != null) {
5875            rec.key.activity.pendingResults.remove(rec.ref);
5876        }
5877    }
5878
5879    @Override
5880    public String getPackageForIntentSender(IIntentSender pendingResult) {
5881        if (!(pendingResult instanceof PendingIntentRecord)) {
5882            return null;
5883        }
5884        try {
5885            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5886            return res.key.packageName;
5887        } catch (ClassCastException e) {
5888        }
5889        return null;
5890    }
5891
5892    @Override
5893    public int getUidForIntentSender(IIntentSender sender) {
5894        if (sender instanceof PendingIntentRecord) {
5895            try {
5896                PendingIntentRecord res = (PendingIntentRecord)sender;
5897                return res.uid;
5898            } catch (ClassCastException e) {
5899            }
5900        }
5901        return -1;
5902    }
5903
5904    @Override
5905    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5906        if (!(pendingResult instanceof PendingIntentRecord)) {
5907            return false;
5908        }
5909        try {
5910            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5911            if (res.key.allIntents == null) {
5912                return false;
5913            }
5914            for (int i=0; i<res.key.allIntents.length; i++) {
5915                Intent intent = res.key.allIntents[i];
5916                if (intent.getPackage() != null && intent.getComponent() != null) {
5917                    return false;
5918                }
5919            }
5920            return true;
5921        } catch (ClassCastException e) {
5922        }
5923        return false;
5924    }
5925
5926    @Override
5927    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5928        if (!(pendingResult instanceof PendingIntentRecord)) {
5929            return false;
5930        }
5931        try {
5932            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5933            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5934                return true;
5935            }
5936            return false;
5937        } catch (ClassCastException e) {
5938        }
5939        return false;
5940    }
5941
5942    @Override
5943    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5944        if (!(pendingResult instanceof PendingIntentRecord)) {
5945            return null;
5946        }
5947        try {
5948            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5949            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5950        } catch (ClassCastException e) {
5951        }
5952        return null;
5953    }
5954
5955    @Override
5956    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5957        if (!(pendingResult instanceof PendingIntentRecord)) {
5958            return null;
5959        }
5960        try {
5961            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5962            Intent intent = res.key.requestIntent;
5963            if (intent != null) {
5964                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5965                        || res.lastTagPrefix.equals(prefix))) {
5966                    return res.lastTag;
5967                }
5968                res.lastTagPrefix = prefix;
5969                StringBuilder sb = new StringBuilder(128);
5970                if (prefix != null) {
5971                    sb.append(prefix);
5972                }
5973                if (intent.getAction() != null) {
5974                    sb.append(intent.getAction());
5975                } else if (intent.getComponent() != null) {
5976                    intent.getComponent().appendShortString(sb);
5977                } else {
5978                    sb.append("?");
5979                }
5980                return res.lastTag = sb.toString();
5981            }
5982        } catch (ClassCastException e) {
5983        }
5984        return null;
5985    }
5986
5987    @Override
5988    public void setProcessLimit(int max) {
5989        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5990                "setProcessLimit()");
5991        synchronized (this) {
5992            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5993            mProcessLimitOverride = max;
5994        }
5995        trimApplications();
5996    }
5997
5998    @Override
5999    public int getProcessLimit() {
6000        synchronized (this) {
6001            return mProcessLimitOverride;
6002        }
6003    }
6004
6005    void foregroundTokenDied(ForegroundToken token) {
6006        synchronized (ActivityManagerService.this) {
6007            synchronized (mPidsSelfLocked) {
6008                ForegroundToken cur
6009                    = mForegroundProcesses.get(token.pid);
6010                if (cur != token) {
6011                    return;
6012                }
6013                mForegroundProcesses.remove(token.pid);
6014                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6015                if (pr == null) {
6016                    return;
6017                }
6018                pr.forcingToForeground = null;
6019                updateProcessForegroundLocked(pr, false, false);
6020            }
6021            updateOomAdjLocked();
6022        }
6023    }
6024
6025    @Override
6026    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6027        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6028                "setProcessForeground()");
6029        synchronized(this) {
6030            boolean changed = false;
6031
6032            synchronized (mPidsSelfLocked) {
6033                ProcessRecord pr = mPidsSelfLocked.get(pid);
6034                if (pr == null && isForeground) {
6035                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6036                    return;
6037                }
6038                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6039                if (oldToken != null) {
6040                    oldToken.token.unlinkToDeath(oldToken, 0);
6041                    mForegroundProcesses.remove(pid);
6042                    if (pr != null) {
6043                        pr.forcingToForeground = null;
6044                    }
6045                    changed = true;
6046                }
6047                if (isForeground && token != null) {
6048                    ForegroundToken newToken = new ForegroundToken() {
6049                        @Override
6050                        public void binderDied() {
6051                            foregroundTokenDied(this);
6052                        }
6053                    };
6054                    newToken.pid = pid;
6055                    newToken.token = token;
6056                    try {
6057                        token.linkToDeath(newToken, 0);
6058                        mForegroundProcesses.put(pid, newToken);
6059                        pr.forcingToForeground = token;
6060                        changed = true;
6061                    } catch (RemoteException e) {
6062                        // If the process died while doing this, we will later
6063                        // do the cleanup with the process death link.
6064                    }
6065                }
6066            }
6067
6068            if (changed) {
6069                updateOomAdjLocked();
6070            }
6071        }
6072    }
6073
6074    // =========================================================
6075    // PERMISSIONS
6076    // =========================================================
6077
6078    static class PermissionController extends IPermissionController.Stub {
6079        ActivityManagerService mActivityManagerService;
6080        PermissionController(ActivityManagerService activityManagerService) {
6081            mActivityManagerService = activityManagerService;
6082        }
6083
6084        @Override
6085        public boolean checkPermission(String permission, int pid, int uid) {
6086            return mActivityManagerService.checkPermission(permission, pid,
6087                    uid) == PackageManager.PERMISSION_GRANTED;
6088        }
6089    }
6090
6091    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6092        @Override
6093        public int checkComponentPermission(String permission, int pid, int uid,
6094                int owningUid, boolean exported) {
6095            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6096                    owningUid, exported);
6097        }
6098
6099        @Override
6100        public Object getAMSLock() {
6101            return ActivityManagerService.this;
6102        }
6103    }
6104
6105    /**
6106     * This can be called with or without the global lock held.
6107     */
6108    int checkComponentPermission(String permission, int pid, int uid,
6109            int owningUid, boolean exported) {
6110        // We might be performing an operation on behalf of an indirect binder
6111        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6112        // client identity accordingly before proceeding.
6113        Identity tlsIdentity = sCallerIdentity.get();
6114        if (tlsIdentity != null) {
6115            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6116                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6117            uid = tlsIdentity.uid;
6118            pid = tlsIdentity.pid;
6119        }
6120
6121        if (pid == MY_PID) {
6122            return PackageManager.PERMISSION_GRANTED;
6123        }
6124
6125        return ActivityManager.checkComponentPermission(permission, uid,
6126                owningUid, exported);
6127    }
6128
6129    /**
6130     * As the only public entry point for permissions checking, this method
6131     * can enforce the semantic that requesting a check on a null global
6132     * permission is automatically denied.  (Internally a null permission
6133     * string is used when calling {@link #checkComponentPermission} in cases
6134     * when only uid-based security is needed.)
6135     *
6136     * This can be called with or without the global lock held.
6137     */
6138    @Override
6139    public int checkPermission(String permission, int pid, int uid) {
6140        if (permission == null) {
6141            return PackageManager.PERMISSION_DENIED;
6142        }
6143        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6144    }
6145
6146    /**
6147     * Binder IPC calls go through the public entry point.
6148     * This can be called with or without the global lock held.
6149     */
6150    int checkCallingPermission(String permission) {
6151        return checkPermission(permission,
6152                Binder.getCallingPid(),
6153                UserHandle.getAppId(Binder.getCallingUid()));
6154    }
6155
6156    /**
6157     * This can be called with or without the global lock held.
6158     */
6159    void enforceCallingPermission(String permission, String func) {
6160        if (checkCallingPermission(permission)
6161                == PackageManager.PERMISSION_GRANTED) {
6162            return;
6163        }
6164
6165        String msg = "Permission Denial: " + func + " from pid="
6166                + Binder.getCallingPid()
6167                + ", uid=" + Binder.getCallingUid()
6168                + " requires " + permission;
6169        Slog.w(TAG, msg);
6170        throw new SecurityException(msg);
6171    }
6172
6173    /**
6174     * Determine if UID is holding permissions required to access {@link Uri} in
6175     * the given {@link ProviderInfo}. Final permission checking is always done
6176     * in {@link ContentProvider}.
6177     */
6178    private final boolean checkHoldingPermissionsLocked(
6179            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6180        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6181                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6182        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6183            return false;
6184        }
6185        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6186    }
6187
6188    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6189            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6190        if (pi.applicationInfo.uid == uid) {
6191            return true;
6192        } else if (!pi.exported) {
6193            return false;
6194        }
6195
6196        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6197        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6198        try {
6199            // check if target holds top-level <provider> permissions
6200            if (!readMet && pi.readPermission != null && considerUidPermissions
6201                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6202                readMet = true;
6203            }
6204            if (!writeMet && pi.writePermission != null && considerUidPermissions
6205                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6206                writeMet = true;
6207            }
6208
6209            // track if unprotected read/write is allowed; any denied
6210            // <path-permission> below removes this ability
6211            boolean allowDefaultRead = pi.readPermission == null;
6212            boolean allowDefaultWrite = pi.writePermission == null;
6213
6214            // check if target holds any <path-permission> that match uri
6215            final PathPermission[] pps = pi.pathPermissions;
6216            if (pps != null) {
6217                final String path = grantUri.uri.getPath();
6218                int i = pps.length;
6219                while (i > 0 && (!readMet || !writeMet)) {
6220                    i--;
6221                    PathPermission pp = pps[i];
6222                    if (pp.match(path)) {
6223                        if (!readMet) {
6224                            final String pprperm = pp.getReadPermission();
6225                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6226                                    + pprperm + " for " + pp.getPath()
6227                                    + ": match=" + pp.match(path)
6228                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6229                            if (pprperm != null) {
6230                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6231                                        == PERMISSION_GRANTED) {
6232                                    readMet = true;
6233                                } else {
6234                                    allowDefaultRead = false;
6235                                }
6236                            }
6237                        }
6238                        if (!writeMet) {
6239                            final String ppwperm = pp.getWritePermission();
6240                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6241                                    + ppwperm + " for " + pp.getPath()
6242                                    + ": match=" + pp.match(path)
6243                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6244                            if (ppwperm != null) {
6245                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6246                                        == PERMISSION_GRANTED) {
6247                                    writeMet = true;
6248                                } else {
6249                                    allowDefaultWrite = false;
6250                                }
6251                            }
6252                        }
6253                    }
6254                }
6255            }
6256
6257            // grant unprotected <provider> read/write, if not blocked by
6258            // <path-permission> above
6259            if (allowDefaultRead) readMet = true;
6260            if (allowDefaultWrite) writeMet = true;
6261
6262        } catch (RemoteException e) {
6263            return false;
6264        }
6265
6266        return readMet && writeMet;
6267    }
6268
6269    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6270        ProviderInfo pi = null;
6271        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6272        if (cpr != null) {
6273            pi = cpr.info;
6274        } else {
6275            try {
6276                pi = AppGlobals.getPackageManager().resolveContentProvider(
6277                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6278            } catch (RemoteException ex) {
6279            }
6280        }
6281        return pi;
6282    }
6283
6284    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6285        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6286        if (targetUris != null) {
6287            return targetUris.get(grantUri);
6288        }
6289        return null;
6290    }
6291
6292    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6293            String targetPkg, int targetUid, GrantUri grantUri) {
6294        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6295        if (targetUris == null) {
6296            targetUris = Maps.newArrayMap();
6297            mGrantedUriPermissions.put(targetUid, targetUris);
6298        }
6299
6300        UriPermission perm = targetUris.get(grantUri);
6301        if (perm == null) {
6302            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6303            targetUris.put(grantUri, perm);
6304        }
6305
6306        return perm;
6307    }
6308
6309    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6310            final int modeFlags) {
6311        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6312        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6313                : UriPermission.STRENGTH_OWNED;
6314
6315        // Root gets to do everything.
6316        if (uid == 0) {
6317            return true;
6318        }
6319
6320        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6321        if (perms == null) return false;
6322
6323        // First look for exact match
6324        final UriPermission exactPerm = perms.get(grantUri);
6325        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6326            return true;
6327        }
6328
6329        // No exact match, look for prefixes
6330        final int N = perms.size();
6331        for (int i = 0; i < N; i++) {
6332            final UriPermission perm = perms.valueAt(i);
6333            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6334                    && perm.getStrength(modeFlags) >= minStrength) {
6335                return true;
6336            }
6337        }
6338
6339        return false;
6340    }
6341
6342    @Override
6343    public int checkUriPermission(Uri uri, int pid, int uid,
6344            final int modeFlags, int userId) {
6345        enforceNotIsolatedCaller("checkUriPermission");
6346
6347        // Another redirected-binder-call permissions check as in
6348        // {@link checkComponentPermission}.
6349        Identity tlsIdentity = sCallerIdentity.get();
6350        if (tlsIdentity != null) {
6351            uid = tlsIdentity.uid;
6352            pid = tlsIdentity.pid;
6353        }
6354
6355        // Our own process gets to do everything.
6356        if (pid == MY_PID) {
6357            return PackageManager.PERMISSION_GRANTED;
6358        }
6359        synchronized (this) {
6360            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6361                    ? PackageManager.PERMISSION_GRANTED
6362                    : PackageManager.PERMISSION_DENIED;
6363        }
6364    }
6365
6366    /**
6367     * Check if the targetPkg can be granted permission to access uri by
6368     * the callingUid using the given modeFlags.  Throws a security exception
6369     * if callingUid is not allowed to do this.  Returns the uid of the target
6370     * if the URI permission grant should be performed; returns -1 if it is not
6371     * needed (for example targetPkg already has permission to access the URI).
6372     * If you already know the uid of the target, you can supply it in
6373     * lastTargetUid else set that to -1.
6374     */
6375    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6376            final int modeFlags, int lastTargetUid) {
6377        if (!Intent.isAccessUriMode(modeFlags)) {
6378            return -1;
6379        }
6380
6381        if (targetPkg != null) {
6382            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6383                    "Checking grant " + targetPkg + " permission to " + grantUri);
6384        }
6385
6386        final IPackageManager pm = AppGlobals.getPackageManager();
6387
6388        // If this is not a content: uri, we can't do anything with it.
6389        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6390            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6391                    "Can't grant URI permission for non-content URI: " + grantUri);
6392            return -1;
6393        }
6394
6395        final String authority = grantUri.uri.getAuthority();
6396        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6397        if (pi == null) {
6398            Slog.w(TAG, "No content provider found for permission check: " +
6399                    grantUri.uri.toSafeString());
6400            return -1;
6401        }
6402
6403        int targetUid = lastTargetUid;
6404        if (targetUid < 0 && targetPkg != null) {
6405            try {
6406                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6407                if (targetUid < 0) {
6408                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6409                            "Can't grant URI permission no uid for: " + targetPkg);
6410                    return -1;
6411                }
6412            } catch (RemoteException ex) {
6413                return -1;
6414            }
6415        }
6416
6417        if (targetUid >= 0) {
6418            // First...  does the target actually need this permission?
6419            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6420                // No need to grant the target this permission.
6421                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6422                        "Target " + targetPkg + " already has full permission to " + grantUri);
6423                return -1;
6424            }
6425        } else {
6426            // First...  there is no target package, so can anyone access it?
6427            boolean allowed = pi.exported;
6428            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6429                if (pi.readPermission != null) {
6430                    allowed = false;
6431                }
6432            }
6433            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6434                if (pi.writePermission != null) {
6435                    allowed = false;
6436                }
6437            }
6438            if (allowed) {
6439                return -1;
6440            }
6441        }
6442
6443        /* There is a special cross user grant if:
6444         * - The target is on another user.
6445         * - Apps on the current user can access the uri without any uid permissions.
6446         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6447         * grant uri permissions.
6448         */
6449        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6450                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6451                modeFlags, false /*without considering the uid permissions*/);
6452
6453        // Second...  is the provider allowing granting of URI permissions?
6454        if (!specialCrossUserGrant) {
6455            if (!pi.grantUriPermissions) {
6456                throw new SecurityException("Provider " + pi.packageName
6457                        + "/" + pi.name
6458                        + " does not allow granting of Uri permissions (uri "
6459                        + grantUri + ")");
6460            }
6461            if (pi.uriPermissionPatterns != null) {
6462                final int N = pi.uriPermissionPatterns.length;
6463                boolean allowed = false;
6464                for (int i=0; i<N; i++) {
6465                    if (pi.uriPermissionPatterns[i] != null
6466                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6467                        allowed = true;
6468                        break;
6469                    }
6470                }
6471                if (!allowed) {
6472                    throw new SecurityException("Provider " + pi.packageName
6473                            + "/" + pi.name
6474                            + " does not allow granting of permission to path of Uri "
6475                            + grantUri);
6476                }
6477            }
6478        }
6479
6480        // Third...  does the caller itself have permission to access
6481        // this uri?
6482        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6483            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6484                // Require they hold a strong enough Uri permission
6485                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6486                    throw new SecurityException("Uid " + callingUid
6487                            + " does not have permission to uri " + grantUri);
6488                }
6489            }
6490        }
6491        return targetUid;
6492    }
6493
6494    @Override
6495    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6496            final int modeFlags, int userId) {
6497        enforceNotIsolatedCaller("checkGrantUriPermission");
6498        synchronized(this) {
6499            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6500                    new GrantUri(userId, uri, false), modeFlags, -1);
6501        }
6502    }
6503
6504    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6505            final int modeFlags, UriPermissionOwner owner) {
6506        if (!Intent.isAccessUriMode(modeFlags)) {
6507            return;
6508        }
6509
6510        // So here we are: the caller has the assumed permission
6511        // to the uri, and the target doesn't.  Let's now give this to
6512        // the target.
6513
6514        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6515                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6516
6517        final String authority = grantUri.uri.getAuthority();
6518        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6519        if (pi == null) {
6520            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6521            return;
6522        }
6523
6524        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6525            grantUri.prefix = true;
6526        }
6527        final UriPermission perm = findOrCreateUriPermissionLocked(
6528                pi.packageName, targetPkg, targetUid, grantUri);
6529        perm.grantModes(modeFlags, owner);
6530    }
6531
6532    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6533            final int modeFlags, UriPermissionOwner owner) {
6534        if (targetPkg == null) {
6535            throw new NullPointerException("targetPkg");
6536        }
6537
6538        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6539                -1);
6540        if (targetUid < 0) {
6541            return;
6542        }
6543
6544        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6545                owner);
6546    }
6547
6548    static class NeededUriGrants extends ArrayList<GrantUri> {
6549        final String targetPkg;
6550        final int targetUid;
6551        final int flags;
6552
6553        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6554            this.targetPkg = targetPkg;
6555            this.targetUid = targetUid;
6556            this.flags = flags;
6557        }
6558    }
6559
6560    /**
6561     * Like checkGrantUriPermissionLocked, but takes an Intent.
6562     */
6563    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6564            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6565        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6566                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6567                + " clip=" + (intent != null ? intent.getClipData() : null)
6568                + " from " + intent + "; flags=0x"
6569                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6570
6571        if (targetPkg == null) {
6572            throw new NullPointerException("targetPkg");
6573        }
6574
6575        if (intent == null) {
6576            return null;
6577        }
6578        Uri data = intent.getData();
6579        ClipData clip = intent.getClipData();
6580        if (data == null && clip == null) {
6581            return null;
6582        }
6583        final IPackageManager pm = AppGlobals.getPackageManager();
6584        int targetUid;
6585        if (needed != null) {
6586            targetUid = needed.targetUid;
6587        } else {
6588            try {
6589                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6590            } catch (RemoteException ex) {
6591                return null;
6592            }
6593            if (targetUid < 0) {
6594                if (DEBUG_URI_PERMISSION) {
6595                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6596                            + " on user " + targetUserId);
6597                }
6598                return null;
6599            }
6600        }
6601        if (data != null) {
6602            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6603            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6604                    targetUid);
6605            if (targetUid > 0) {
6606                if (needed == null) {
6607                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6608                }
6609                needed.add(grantUri);
6610            }
6611        }
6612        if (clip != null) {
6613            for (int i=0; i<clip.getItemCount(); i++) {
6614                Uri uri = clip.getItemAt(i).getUri();
6615                if (uri != null) {
6616                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6617                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6618                            targetUid);
6619                    if (targetUid > 0) {
6620                        if (needed == null) {
6621                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6622                        }
6623                        needed.add(grantUri);
6624                    }
6625                } else {
6626                    Intent clipIntent = clip.getItemAt(i).getIntent();
6627                    if (clipIntent != null) {
6628                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6629                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6630                        if (newNeeded != null) {
6631                            needed = newNeeded;
6632                        }
6633                    }
6634                }
6635            }
6636        }
6637
6638        return needed;
6639    }
6640
6641    /**
6642     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6643     */
6644    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6645            UriPermissionOwner owner) {
6646        if (needed != null) {
6647            for (int i=0; i<needed.size(); i++) {
6648                GrantUri grantUri = needed.get(i);
6649                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6650                        grantUri, needed.flags, owner);
6651            }
6652        }
6653    }
6654
6655    void grantUriPermissionFromIntentLocked(int callingUid,
6656            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6657        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6658                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6659        if (needed == null) {
6660            return;
6661        }
6662
6663        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6664    }
6665
6666    @Override
6667    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6668            final int modeFlags, int userId) {
6669        enforceNotIsolatedCaller("grantUriPermission");
6670        GrantUri grantUri = new GrantUri(userId, uri, false);
6671        synchronized(this) {
6672            final ProcessRecord r = getRecordForAppLocked(caller);
6673            if (r == null) {
6674                throw new SecurityException("Unable to find app for caller "
6675                        + caller
6676                        + " when granting permission to uri " + grantUri);
6677            }
6678            if (targetPkg == null) {
6679                throw new IllegalArgumentException("null target");
6680            }
6681            if (grantUri == null) {
6682                throw new IllegalArgumentException("null uri");
6683            }
6684
6685            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6686                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6687                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6688                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6689
6690            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null);
6691        }
6692    }
6693
6694    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6695        if (perm.modeFlags == 0) {
6696            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6697                    perm.targetUid);
6698            if (perms != null) {
6699                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6700                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6701
6702                perms.remove(perm.uri);
6703                if (perms.isEmpty()) {
6704                    mGrantedUriPermissions.remove(perm.targetUid);
6705                }
6706            }
6707        }
6708    }
6709
6710    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6711        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6712
6713        final IPackageManager pm = AppGlobals.getPackageManager();
6714        final String authority = grantUri.uri.getAuthority();
6715        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6716        if (pi == null) {
6717            Slog.w(TAG, "No content provider found for permission revoke: "
6718                    + grantUri.toSafeString());
6719            return;
6720        }
6721
6722        // Does the caller have this permission on the URI?
6723        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6724            // Right now, if you are not the original owner of the permission,
6725            // you are not allowed to revoke it.
6726            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6727                throw new SecurityException("Uid " + callingUid
6728                        + " does not have permission to uri " + grantUri);
6729            //}
6730        }
6731
6732        boolean persistChanged = false;
6733
6734        // Go through all of the permissions and remove any that match.
6735        int N = mGrantedUriPermissions.size();
6736        for (int i = 0; i < N; i++) {
6737            final int targetUid = mGrantedUriPermissions.keyAt(i);
6738            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6739
6740            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6741                final UriPermission perm = it.next();
6742                if (perm.uri.sourceUserId == grantUri.sourceUserId
6743                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6744                    if (DEBUG_URI_PERMISSION)
6745                        Slog.v(TAG,
6746                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6747                    persistChanged |= perm.revokeModes(
6748                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6749                    if (perm.modeFlags == 0) {
6750                        it.remove();
6751                    }
6752                }
6753            }
6754
6755            if (perms.isEmpty()) {
6756                mGrantedUriPermissions.remove(targetUid);
6757                N--;
6758                i--;
6759            }
6760        }
6761
6762        if (persistChanged) {
6763            schedulePersistUriGrants();
6764        }
6765    }
6766
6767    @Override
6768    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6769            int userId) {
6770        enforceNotIsolatedCaller("revokeUriPermission");
6771        synchronized(this) {
6772            final ProcessRecord r = getRecordForAppLocked(caller);
6773            if (r == null) {
6774                throw new SecurityException("Unable to find app for caller "
6775                        + caller
6776                        + " when revoking permission to uri " + uri);
6777            }
6778            if (uri == null) {
6779                Slog.w(TAG, "revokeUriPermission: null uri");
6780                return;
6781            }
6782
6783            if (!Intent.isAccessUriMode(modeFlags)) {
6784                return;
6785            }
6786
6787            final IPackageManager pm = AppGlobals.getPackageManager();
6788            final String authority = uri.getAuthority();
6789            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6790            if (pi == null) {
6791                Slog.w(TAG, "No content provider found for permission revoke: "
6792                        + uri.toSafeString());
6793                return;
6794            }
6795
6796            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6797        }
6798    }
6799
6800    /**
6801     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6802     * given package.
6803     *
6804     * @param packageName Package name to match, or {@code null} to apply to all
6805     *            packages.
6806     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6807     *            to all users.
6808     * @param persistable If persistable grants should be removed.
6809     */
6810    private void removeUriPermissionsForPackageLocked(
6811            String packageName, int userHandle, boolean persistable) {
6812        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6813            throw new IllegalArgumentException("Must narrow by either package or user");
6814        }
6815
6816        boolean persistChanged = false;
6817
6818        int N = mGrantedUriPermissions.size();
6819        for (int i = 0; i < N; i++) {
6820            final int targetUid = mGrantedUriPermissions.keyAt(i);
6821            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6822
6823            // Only inspect grants matching user
6824            if (userHandle == UserHandle.USER_ALL
6825                    || userHandle == UserHandle.getUserId(targetUid)) {
6826                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6827                    final UriPermission perm = it.next();
6828
6829                    // Only inspect grants matching package
6830                    if (packageName == null || perm.sourcePkg.equals(packageName)
6831                            || perm.targetPkg.equals(packageName)) {
6832                        persistChanged |= perm.revokeModes(
6833                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6834
6835                        // Only remove when no modes remain; any persisted grants
6836                        // will keep this alive.
6837                        if (perm.modeFlags == 0) {
6838                            it.remove();
6839                        }
6840                    }
6841                }
6842
6843                if (perms.isEmpty()) {
6844                    mGrantedUriPermissions.remove(targetUid);
6845                    N--;
6846                    i--;
6847                }
6848            }
6849        }
6850
6851        if (persistChanged) {
6852            schedulePersistUriGrants();
6853        }
6854    }
6855
6856    @Override
6857    public IBinder newUriPermissionOwner(String name) {
6858        enforceNotIsolatedCaller("newUriPermissionOwner");
6859        synchronized(this) {
6860            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6861            return owner.getExternalTokenLocked();
6862        }
6863    }
6864
6865    @Override
6866    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6867            final int modeFlags, int userId) {
6868        synchronized(this) {
6869            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6870            if (owner == null) {
6871                throw new IllegalArgumentException("Unknown owner: " + token);
6872            }
6873            if (fromUid != Binder.getCallingUid()) {
6874                if (Binder.getCallingUid() != Process.myUid()) {
6875                    // Only system code can grant URI permissions on behalf
6876                    // of other users.
6877                    throw new SecurityException("nice try");
6878                }
6879            }
6880            if (targetPkg == null) {
6881                throw new IllegalArgumentException("null target");
6882            }
6883            if (uri == null) {
6884                throw new IllegalArgumentException("null uri");
6885            }
6886
6887            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false),
6888                    modeFlags, owner);
6889        }
6890    }
6891
6892    @Override
6893    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6894        synchronized(this) {
6895            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6896            if (owner == null) {
6897                throw new IllegalArgumentException("Unknown owner: " + token);
6898            }
6899
6900            if (uri == null) {
6901                owner.removeUriPermissionsLocked(mode);
6902            } else {
6903                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6904            }
6905        }
6906    }
6907
6908    private void schedulePersistUriGrants() {
6909        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6910            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6911                    10 * DateUtils.SECOND_IN_MILLIS);
6912        }
6913    }
6914
6915    private void writeGrantedUriPermissions() {
6916        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6917
6918        // Snapshot permissions so we can persist without lock
6919        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6920        synchronized (this) {
6921            final int size = mGrantedUriPermissions.size();
6922            for (int i = 0; i < size; i++) {
6923                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6924                for (UriPermission perm : perms.values()) {
6925                    if (perm.persistedModeFlags != 0) {
6926                        persist.add(perm.snapshot());
6927                    }
6928                }
6929            }
6930        }
6931
6932        FileOutputStream fos = null;
6933        try {
6934            fos = mGrantFile.startWrite();
6935
6936            XmlSerializer out = new FastXmlSerializer();
6937            out.setOutput(fos, "utf-8");
6938            out.startDocument(null, true);
6939            out.startTag(null, TAG_URI_GRANTS);
6940            for (UriPermission.Snapshot perm : persist) {
6941                out.startTag(null, TAG_URI_GRANT);
6942                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6943                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6944                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6945                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6946                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6947                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6948                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6949                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6950                out.endTag(null, TAG_URI_GRANT);
6951            }
6952            out.endTag(null, TAG_URI_GRANTS);
6953            out.endDocument();
6954
6955            mGrantFile.finishWrite(fos);
6956        } catch (IOException e) {
6957            if (fos != null) {
6958                mGrantFile.failWrite(fos);
6959            }
6960        }
6961    }
6962
6963    private void readGrantedUriPermissionsLocked() {
6964        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6965
6966        final long now = System.currentTimeMillis();
6967
6968        FileInputStream fis = null;
6969        try {
6970            fis = mGrantFile.openRead();
6971            final XmlPullParser in = Xml.newPullParser();
6972            in.setInput(fis, null);
6973
6974            int type;
6975            while ((type = in.next()) != END_DOCUMENT) {
6976                final String tag = in.getName();
6977                if (type == START_TAG) {
6978                    if (TAG_URI_GRANT.equals(tag)) {
6979                        final int sourceUserId;
6980                        final int targetUserId;
6981                        final int userHandle = readIntAttribute(in,
6982                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
6983                        if (userHandle != UserHandle.USER_NULL) {
6984                            // For backwards compatibility.
6985                            sourceUserId = userHandle;
6986                            targetUserId = userHandle;
6987                        } else {
6988                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
6989                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
6990                        }
6991                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6992                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6993                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6994                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6995                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6996                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6997
6998                        // Sanity check that provider still belongs to source package
6999                        final ProviderInfo pi = getProviderInfoLocked(
7000                                uri.getAuthority(), sourceUserId);
7001                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7002                            int targetUid = -1;
7003                            try {
7004                                targetUid = AppGlobals.getPackageManager()
7005                                        .getPackageUid(targetPkg, targetUserId);
7006                            } catch (RemoteException e) {
7007                            }
7008                            if (targetUid != -1) {
7009                                final UriPermission perm = findOrCreateUriPermissionLocked(
7010                                        sourcePkg, targetPkg, targetUid,
7011                                        new GrantUri(sourceUserId, uri, prefix));
7012                                perm.initPersistedModes(modeFlags, createdTime);
7013                            }
7014                        } else {
7015                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7016                                    + " but instead found " + pi);
7017                        }
7018                    }
7019                }
7020            }
7021        } catch (FileNotFoundException e) {
7022            // Missing grants is okay
7023        } catch (IOException e) {
7024            Log.wtf(TAG, "Failed reading Uri grants", e);
7025        } catch (XmlPullParserException e) {
7026            Log.wtf(TAG, "Failed reading Uri grants", e);
7027        } finally {
7028            IoUtils.closeQuietly(fis);
7029        }
7030    }
7031
7032    @Override
7033    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7034        enforceNotIsolatedCaller("takePersistableUriPermission");
7035
7036        Preconditions.checkFlagsArgument(modeFlags,
7037                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7038
7039        synchronized (this) {
7040            final int callingUid = Binder.getCallingUid();
7041            boolean persistChanged = false;
7042            GrantUri grantUri = new GrantUri(userId, uri, false);
7043
7044            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7045                    new GrantUri(userId, uri, false));
7046            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7047                    new GrantUri(userId, uri, true));
7048
7049            final boolean exactValid = (exactPerm != null)
7050                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7051            final boolean prefixValid = (prefixPerm != null)
7052                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7053
7054            if (!(exactValid || prefixValid)) {
7055                throw new SecurityException("No persistable permission grants found for UID "
7056                        + callingUid + " and Uri " + grantUri.toSafeString());
7057            }
7058
7059            if (exactValid) {
7060                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7061            }
7062            if (prefixValid) {
7063                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7064            }
7065
7066            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7067
7068            if (persistChanged) {
7069                schedulePersistUriGrants();
7070            }
7071        }
7072    }
7073
7074    @Override
7075    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7076        enforceNotIsolatedCaller("releasePersistableUriPermission");
7077
7078        Preconditions.checkFlagsArgument(modeFlags,
7079                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7080
7081        synchronized (this) {
7082            final int callingUid = Binder.getCallingUid();
7083            boolean persistChanged = false;
7084
7085            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7086                    new GrantUri(userId, uri, false));
7087            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7088                    new GrantUri(userId, uri, true));
7089            if (exactPerm == null && prefixPerm == null) {
7090                throw new SecurityException("No permission grants found for UID " + callingUid
7091                        + " and Uri " + uri.toSafeString());
7092            }
7093
7094            if (exactPerm != null) {
7095                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7096                removeUriPermissionIfNeededLocked(exactPerm);
7097            }
7098            if (prefixPerm != null) {
7099                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7100                removeUriPermissionIfNeededLocked(prefixPerm);
7101            }
7102
7103            if (persistChanged) {
7104                schedulePersistUriGrants();
7105            }
7106        }
7107    }
7108
7109    /**
7110     * Prune any older {@link UriPermission} for the given UID until outstanding
7111     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7112     *
7113     * @return if any mutations occured that require persisting.
7114     */
7115    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7116        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7117        if (perms == null) return false;
7118        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7119
7120        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7121        for (UriPermission perm : perms.values()) {
7122            if (perm.persistedModeFlags != 0) {
7123                persisted.add(perm);
7124            }
7125        }
7126
7127        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7128        if (trimCount <= 0) return false;
7129
7130        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7131        for (int i = 0; i < trimCount; i++) {
7132            final UriPermission perm = persisted.get(i);
7133
7134            if (DEBUG_URI_PERMISSION) {
7135                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7136            }
7137
7138            perm.releasePersistableModes(~0);
7139            removeUriPermissionIfNeededLocked(perm);
7140        }
7141
7142        return true;
7143    }
7144
7145    @Override
7146    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7147            String packageName, boolean incoming) {
7148        enforceNotIsolatedCaller("getPersistedUriPermissions");
7149        Preconditions.checkNotNull(packageName, "packageName");
7150
7151        final int callingUid = Binder.getCallingUid();
7152        final IPackageManager pm = AppGlobals.getPackageManager();
7153        try {
7154            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7155            if (packageUid != callingUid) {
7156                throw new SecurityException(
7157                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7158            }
7159        } catch (RemoteException e) {
7160            throw new SecurityException("Failed to verify package name ownership");
7161        }
7162
7163        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7164        synchronized (this) {
7165            if (incoming) {
7166                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7167                        callingUid);
7168                if (perms == null) {
7169                    Slog.w(TAG, "No permission grants found for " + packageName);
7170                } else {
7171                    for (UriPermission perm : perms.values()) {
7172                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7173                            result.add(perm.buildPersistedPublicApiObject());
7174                        }
7175                    }
7176                }
7177            } else {
7178                final int size = mGrantedUriPermissions.size();
7179                for (int i = 0; i < size; i++) {
7180                    final ArrayMap<GrantUri, UriPermission> perms =
7181                            mGrantedUriPermissions.valueAt(i);
7182                    for (UriPermission perm : perms.values()) {
7183                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7184                            result.add(perm.buildPersistedPublicApiObject());
7185                        }
7186                    }
7187                }
7188            }
7189        }
7190        return new ParceledListSlice<android.content.UriPermission>(result);
7191    }
7192
7193    @Override
7194    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7195        synchronized (this) {
7196            ProcessRecord app =
7197                who != null ? getRecordForAppLocked(who) : null;
7198            if (app == null) return;
7199
7200            Message msg = Message.obtain();
7201            msg.what = WAIT_FOR_DEBUGGER_MSG;
7202            msg.obj = app;
7203            msg.arg1 = waiting ? 1 : 0;
7204            mHandler.sendMessage(msg);
7205        }
7206    }
7207
7208    @Override
7209    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7210        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7211        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7212        outInfo.availMem = Process.getFreeMemory();
7213        outInfo.totalMem = Process.getTotalMemory();
7214        outInfo.threshold = homeAppMem;
7215        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7216        outInfo.hiddenAppThreshold = cachedAppMem;
7217        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7218                ProcessList.SERVICE_ADJ);
7219        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7220                ProcessList.VISIBLE_APP_ADJ);
7221        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7222                ProcessList.FOREGROUND_APP_ADJ);
7223    }
7224
7225    // =========================================================
7226    // TASK MANAGEMENT
7227    // =========================================================
7228
7229    @Override
7230    public List<IAppTask> getAppTasks() {
7231        final PackageManager pm = mContext.getPackageManager();
7232        int callingUid = Binder.getCallingUid();
7233        long ident = Binder.clearCallingIdentity();
7234
7235        // Compose the list of packages for this id to test against
7236        HashSet<String> packages = new HashSet<String>();
7237        String[] uidPackages = pm.getPackagesForUid(callingUid);
7238        for (int i = 0; i < uidPackages.length; i++) {
7239            packages.add(uidPackages[i]);
7240        }
7241
7242        synchronized(this) {
7243            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7244            try {
7245                if (localLOGV) Slog.v(TAG, "getAppTasks");
7246
7247                final int N = mRecentTasks.size();
7248                for (int i = 0; i < N; i++) {
7249                    TaskRecord tr = mRecentTasks.get(i);
7250                    // Skip tasks that are not created by the caller
7251                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
7252                        ActivityManager.RecentTaskInfo taskInfo =
7253                                createRecentTaskInfoFromTaskRecord(tr);
7254                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7255                        list.add(taskImpl);
7256                    }
7257                }
7258            } finally {
7259                Binder.restoreCallingIdentity(ident);
7260            }
7261            return list;
7262        }
7263    }
7264
7265    @Override
7266    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7267        final int callingUid = Binder.getCallingUid();
7268        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7269
7270        synchronized(this) {
7271            if (localLOGV) Slog.v(
7272                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7273
7274            final boolean allowed = checkCallingPermission(
7275                    android.Manifest.permission.GET_TASKS)
7276                    == PackageManager.PERMISSION_GRANTED;
7277            if (!allowed) {
7278                Slog.w(TAG, "getTasks: caller " + callingUid
7279                        + " does not hold GET_TASKS; limiting output");
7280            }
7281
7282            // TODO: Improve with MRU list from all ActivityStacks.
7283            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7284        }
7285
7286        return list;
7287    }
7288
7289    TaskRecord getMostRecentTask() {
7290        return mRecentTasks.get(0);
7291    }
7292
7293    /**
7294     * Creates a new RecentTaskInfo from a TaskRecord.
7295     */
7296    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7297        // Update the task description to reflect any changes in the task stack
7298        tr.updateTaskDescription();
7299
7300        // Compose the recent task info
7301        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7302        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7303        rti.persistentId = tr.taskId;
7304        rti.baseIntent = new Intent(tr.getBaseIntent());
7305        rti.origActivity = tr.origActivity;
7306        rti.description = tr.lastDescription;
7307        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7308        rti.userId = tr.userId;
7309        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7310        rti.firstActiveTime = tr.firstActiveTime;
7311        rti.lastActiveTime = tr.lastActiveTime;
7312        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7313        return rti;
7314    }
7315
7316    @Override
7317    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7318        final int callingUid = Binder.getCallingUid();
7319        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7320                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7321
7322        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7323        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7324        synchronized (this) {
7325            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
7326                    == PackageManager.PERMISSION_GRANTED;
7327            if (!allowed) {
7328                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7329                        + " does not hold GET_TASKS; limiting output");
7330            }
7331            final boolean detailed = checkCallingPermission(
7332                    android.Manifest.permission.GET_DETAILED_TASKS)
7333                    == PackageManager.PERMISSION_GRANTED;
7334
7335            IPackageManager pm = AppGlobals.getPackageManager();
7336
7337            final int N = mRecentTasks.size();
7338            ArrayList<ActivityManager.RecentTaskInfo> res
7339                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7340                            maxNum < N ? maxNum : N);
7341
7342            final Set<Integer> includedUsers;
7343            if (includeProfiles) {
7344                includedUsers = getProfileIdsLocked(userId);
7345            } else {
7346                includedUsers = new HashSet<Integer>();
7347            }
7348            includedUsers.add(Integer.valueOf(userId));
7349
7350            // Regroup affiliated tasks together.
7351            for (int i = 0; i < N; ) {
7352                TaskRecord task = mRecentTasks.remove(i);
7353                if (mTmpRecents.contains(task)) {
7354                    continue;
7355                }
7356                int affiliatedTaskId = task.mAffiliatedTaskId;
7357                while (true) {
7358                    TaskRecord next = task.mNextAffiliate;
7359                    if (next == null) {
7360                        break;
7361                    }
7362                    if (next.mAffiliatedTaskId != affiliatedTaskId) {
7363                        Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
7364                                next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
7365                        task.setNextAffiliate(null);
7366                        if (next.mPrevAffiliate == task) {
7367                            next.setPrevAffiliate(null);
7368                        }
7369                        break;
7370                    }
7371                    if (next.mPrevAffiliate != task) {
7372                        Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
7373                                next.mPrevAffiliate + " task=" + task);
7374                        next.setPrevAffiliate(null);
7375                        break;
7376                    }
7377                    if (!mRecentTasks.contains(next)) {
7378                        Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
7379                        task.setNextAffiliate(null);
7380                        if (next.mPrevAffiliate == task) {
7381                            next.setPrevAffiliate(null);
7382                        }
7383                        break;
7384                    }
7385                    task = next;
7386                }
7387                // task is now the end of the list
7388                do {
7389                    mRecentTasks.remove(task);
7390                    mRecentTasks.add(i++, task);
7391                    mTmpRecents.add(task);
7392                } while ((task = task.mPrevAffiliate) != null);
7393            }
7394            mTmpRecents.clear();
7395            // mRecentTasks is now in sorted, affiliated order.
7396
7397            for (int i=0; i<N && maxNum > 0; i++) {
7398                TaskRecord tr = mRecentTasks.get(i);
7399                // Only add calling user or related users recent tasks
7400                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7401
7402                // Return the entry if desired by the caller.  We always return
7403                // the first entry, because callers always expect this to be the
7404                // foreground app.  We may filter others if the caller has
7405                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7406                // we should exclude the entry.
7407
7408                if (i == 0
7409                        || withExcluded
7410                        || (tr.intent == null)
7411                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7412                                == 0)) {
7413                    if (!allowed) {
7414                        // If the caller doesn't have the GET_TASKS permission, then only
7415                        // allow them to see a small subset of tasks -- their own and home.
7416                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7417                            continue;
7418                        }
7419                    }
7420                    if (tr.intent != null &&
7421                            (tr.intent.getFlags() & Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS)
7422                            != 0 && tr.getTopActivity() == null) {
7423                        // Don't include auto remove tasks that are finished or finishing.
7424                        continue;
7425                    }
7426
7427                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7428                    if (!detailed) {
7429                        rti.baseIntent.replaceExtras((Bundle)null);
7430                    }
7431
7432                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7433                        // Check whether this activity is currently available.
7434                        try {
7435                            if (rti.origActivity != null) {
7436                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7437                                        == null) {
7438                                    continue;
7439                                }
7440                            } else if (rti.baseIntent != null) {
7441                                if (pm.queryIntentActivities(rti.baseIntent,
7442                                        null, 0, userId) == null) {
7443                                    continue;
7444                                }
7445                            }
7446                        } catch (RemoteException e) {
7447                            // Will never happen.
7448                        }
7449                    }
7450
7451                    res.add(rti);
7452                    maxNum--;
7453                }
7454            }
7455            return res;
7456        }
7457    }
7458
7459    private TaskRecord recentTaskForIdLocked(int id) {
7460        final int N = mRecentTasks.size();
7461            for (int i=0; i<N; i++) {
7462                TaskRecord tr = mRecentTasks.get(i);
7463                if (tr.taskId == id) {
7464                    return tr;
7465                }
7466            }
7467            return null;
7468    }
7469
7470    @Override
7471    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7472        synchronized (this) {
7473            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7474                    "getTaskThumbnail()");
7475            TaskRecord tr = recentTaskForIdLocked(id);
7476            if (tr != null) {
7477                return tr.getTaskThumbnailLocked();
7478            }
7479        }
7480        return null;
7481    }
7482
7483    @Override
7484    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7485        synchronized (this) {
7486            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7487            if (r != null) {
7488                r.taskDescription = td;
7489                r.task.updateTaskDescription();
7490            }
7491        }
7492    }
7493
7494    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7495        if (!pr.killedByAm) {
7496            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7497            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7498                    pr.processName, pr.setAdj, reason);
7499            pr.killedByAm = true;
7500            Process.killProcessQuiet(pr.pid);
7501            Process.killProcessGroup(pr.info.uid, pr.pid);
7502        }
7503    }
7504
7505    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7506        tr.disposeThumbnail();
7507        mRecentTasks.remove(tr);
7508        tr.closeRecentsChain();
7509        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7510        Intent baseIntent = new Intent(
7511                tr.intent != null ? tr.intent : tr.affinityIntent);
7512        ComponentName component = baseIntent.getComponent();
7513        if (component == null) {
7514            Slog.w(TAG, "Now component for base intent of task: " + tr);
7515            return;
7516        }
7517
7518        // Find any running services associated with this app.
7519        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7520
7521        if (killProcesses) {
7522            // Find any running processes associated with this app.
7523            final String pkg = component.getPackageName();
7524            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7525            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7526            for (int i=0; i<pmap.size(); i++) {
7527                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7528                for (int j=0; j<uids.size(); j++) {
7529                    ProcessRecord proc = uids.valueAt(j);
7530                    if (proc.userId != tr.userId) {
7531                        continue;
7532                    }
7533                    if (!proc.pkgList.containsKey(pkg)) {
7534                        continue;
7535                    }
7536                    procs.add(proc);
7537                }
7538            }
7539
7540            // Kill the running processes.
7541            for (int i=0; i<procs.size(); i++) {
7542                ProcessRecord pr = procs.get(i);
7543                if (pr == mHomeProcess) {
7544                    // Don't kill the home process along with tasks from the same package.
7545                    continue;
7546                }
7547                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7548                    killUnneededProcessLocked(pr, "remove task");
7549                } else {
7550                    pr.waitingToKill = "remove task";
7551                }
7552            }
7553        }
7554    }
7555
7556    /**
7557     * Removes the task with the specified task id.
7558     *
7559     * @param taskId Identifier of the task to be removed.
7560     * @param flags Additional operational flags.  May be 0 or
7561     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7562     * @return Returns true if the given task was found and removed.
7563     */
7564    private boolean removeTaskByIdLocked(int taskId, int flags) {
7565        TaskRecord tr = recentTaskForIdLocked(taskId);
7566        if (tr != null) {
7567            tr.removeTaskActivitiesLocked();
7568            cleanUpRemovedTaskLocked(tr, flags);
7569            if (tr.isPersistable) {
7570                notifyTaskPersisterLocked(tr, true);
7571            }
7572            return true;
7573        }
7574        return false;
7575    }
7576
7577    @Override
7578    public boolean removeTask(int taskId, int flags) {
7579        synchronized (this) {
7580            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7581                    "removeTask()");
7582            long ident = Binder.clearCallingIdentity();
7583            try {
7584                return removeTaskByIdLocked(taskId, flags);
7585            } finally {
7586                Binder.restoreCallingIdentity(ident);
7587            }
7588        }
7589    }
7590
7591    /**
7592     * TODO: Add mController hook
7593     */
7594    @Override
7595    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7596        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7597                "moveTaskToFront()");
7598
7599        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7600        synchronized(this) {
7601            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7602                    Binder.getCallingUid(), "Task to front")) {
7603                ActivityOptions.abort(options);
7604                return;
7605            }
7606            final long origId = Binder.clearCallingIdentity();
7607            try {
7608                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7609                if (task == null) {
7610                    return;
7611                }
7612                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7613                    mStackSupervisor.showLockTaskToast();
7614                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7615                    return;
7616                }
7617                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7618                if (prev != null && prev.isRecentsActivity()) {
7619                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7620                }
7621                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7622            } finally {
7623                Binder.restoreCallingIdentity(origId);
7624            }
7625            ActivityOptions.abort(options);
7626        }
7627    }
7628
7629    @Override
7630    public void moveTaskToBack(int taskId) {
7631        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7632                "moveTaskToBack()");
7633
7634        synchronized(this) {
7635            TaskRecord tr = recentTaskForIdLocked(taskId);
7636            if (tr != null) {
7637                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7638                ActivityStack stack = tr.stack;
7639                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7640                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7641                            Binder.getCallingUid(), "Task to back")) {
7642                        return;
7643                    }
7644                }
7645                final long origId = Binder.clearCallingIdentity();
7646                try {
7647                    stack.moveTaskToBackLocked(taskId, null);
7648                } finally {
7649                    Binder.restoreCallingIdentity(origId);
7650                }
7651            }
7652        }
7653    }
7654
7655    /**
7656     * Moves an activity, and all of the other activities within the same task, to the bottom
7657     * of the history stack.  The activity's order within the task is unchanged.
7658     *
7659     * @param token A reference to the activity we wish to move
7660     * @param nonRoot If false then this only works if the activity is the root
7661     *                of a task; if true it will work for any activity in a task.
7662     * @return Returns true if the move completed, false if not.
7663     */
7664    @Override
7665    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7666        enforceNotIsolatedCaller("moveActivityTaskToBack");
7667        synchronized(this) {
7668            final long origId = Binder.clearCallingIdentity();
7669            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7670            if (taskId >= 0) {
7671                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7672            }
7673            Binder.restoreCallingIdentity(origId);
7674        }
7675        return false;
7676    }
7677
7678    @Override
7679    public void moveTaskBackwards(int task) {
7680        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7681                "moveTaskBackwards()");
7682
7683        synchronized(this) {
7684            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7685                    Binder.getCallingUid(), "Task backwards")) {
7686                return;
7687            }
7688            final long origId = Binder.clearCallingIdentity();
7689            moveTaskBackwardsLocked(task);
7690            Binder.restoreCallingIdentity(origId);
7691        }
7692    }
7693
7694    private final void moveTaskBackwardsLocked(int task) {
7695        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7696    }
7697
7698    @Override
7699    public IBinder getHomeActivityToken() throws RemoteException {
7700        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7701                "getHomeActivityToken()");
7702        synchronized (this) {
7703            return mStackSupervisor.getHomeActivityToken();
7704        }
7705    }
7706
7707    @Override
7708    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7709            IActivityContainerCallback callback) throws RemoteException {
7710        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7711                "createActivityContainer()");
7712        synchronized (this) {
7713            if (parentActivityToken == null) {
7714                throw new IllegalArgumentException("parent token must not be null");
7715            }
7716            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7717            if (r == null) {
7718                return null;
7719            }
7720            if (callback == null) {
7721                throw new IllegalArgumentException("callback must not be null");
7722            }
7723            return mStackSupervisor.createActivityContainer(r, callback);
7724        }
7725    }
7726
7727    @Override
7728    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7729        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7730                "deleteActivityContainer()");
7731        synchronized (this) {
7732            mStackSupervisor.deleteActivityContainer(container);
7733        }
7734    }
7735
7736    @Override
7737    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7738            throws RemoteException {
7739        synchronized (this) {
7740            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7741            if (stack != null) {
7742                return stack.mActivityContainer;
7743            }
7744            return null;
7745        }
7746    }
7747
7748    @Override
7749    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7750        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7751                "moveTaskToStack()");
7752        if (stackId == HOME_STACK_ID) {
7753            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7754                    new RuntimeException("here").fillInStackTrace());
7755        }
7756        synchronized (this) {
7757            long ident = Binder.clearCallingIdentity();
7758            try {
7759                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7760                        + stackId + " toTop=" + toTop);
7761                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7762            } finally {
7763                Binder.restoreCallingIdentity(ident);
7764            }
7765        }
7766    }
7767
7768    @Override
7769    public void resizeStack(int stackBoxId, Rect bounds) {
7770        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7771                "resizeStackBox()");
7772        long ident = Binder.clearCallingIdentity();
7773        try {
7774            mWindowManager.resizeStack(stackBoxId, bounds);
7775        } finally {
7776            Binder.restoreCallingIdentity(ident);
7777        }
7778    }
7779
7780    @Override
7781    public List<StackInfo> getAllStackInfos() {
7782        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7783                "getAllStackInfos()");
7784        long ident = Binder.clearCallingIdentity();
7785        try {
7786            synchronized (this) {
7787                return mStackSupervisor.getAllStackInfosLocked();
7788            }
7789        } finally {
7790            Binder.restoreCallingIdentity(ident);
7791        }
7792    }
7793
7794    @Override
7795    public StackInfo getStackInfo(int stackId) {
7796        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7797                "getStackInfo()");
7798        long ident = Binder.clearCallingIdentity();
7799        try {
7800            synchronized (this) {
7801                return mStackSupervisor.getStackInfoLocked(stackId);
7802            }
7803        } finally {
7804            Binder.restoreCallingIdentity(ident);
7805        }
7806    }
7807
7808    @Override
7809    public boolean isInHomeStack(int taskId) {
7810        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7811                "getStackInfo()");
7812        long ident = Binder.clearCallingIdentity();
7813        try {
7814            synchronized (this) {
7815                TaskRecord tr = recentTaskForIdLocked(taskId);
7816                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7817            }
7818        } finally {
7819            Binder.restoreCallingIdentity(ident);
7820        }
7821    }
7822
7823    @Override
7824    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7825        synchronized(this) {
7826            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7827        }
7828    }
7829
7830    private boolean isLockTaskAuthorized(String pkg) {
7831        final DevicePolicyManager dpm = (DevicePolicyManager)
7832                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7833        try {
7834            int uid = mContext.getPackageManager().getPackageUid(pkg,
7835                    Binder.getCallingUserHandle().getIdentifier());
7836            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7837        } catch (NameNotFoundException e) {
7838            return false;
7839        }
7840    }
7841
7842    void startLockTaskMode(TaskRecord task) {
7843        final String pkg;
7844        synchronized (this) {
7845            pkg = task.intent.getComponent().getPackageName();
7846        }
7847        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
7848        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
7849            final TaskRecord taskRecord = task;
7850            mHandler.post(new Runnable() {
7851                @Override
7852                public void run() {
7853                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
7854                }
7855            });
7856            return;
7857        }
7858        long ident = Binder.clearCallingIdentity();
7859        try {
7860            synchronized (this) {
7861                // Since we lost lock on task, make sure it is still there.
7862                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7863                if (task != null) {
7864                    if (!isSystemInitiated
7865                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
7866                        throw new IllegalArgumentException("Invalid task, not in foreground");
7867                    }
7868                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
7869                }
7870            }
7871        } finally {
7872            Binder.restoreCallingIdentity(ident);
7873        }
7874    }
7875
7876    @Override
7877    public void startLockTaskMode(int taskId) {
7878        final TaskRecord task;
7879        long ident = Binder.clearCallingIdentity();
7880        try {
7881            synchronized (this) {
7882                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7883            }
7884        } finally {
7885            Binder.restoreCallingIdentity(ident);
7886        }
7887        if (task != null) {
7888            startLockTaskMode(task);
7889        }
7890    }
7891
7892    @Override
7893    public void startLockTaskMode(IBinder token) {
7894        final TaskRecord task;
7895        long ident = Binder.clearCallingIdentity();
7896        try {
7897            synchronized (this) {
7898                final ActivityRecord r = ActivityRecord.forToken(token);
7899                if (r == null) {
7900                    return;
7901                }
7902                task = r.task;
7903            }
7904        } finally {
7905            Binder.restoreCallingIdentity(ident);
7906        }
7907        if (task != null) {
7908            startLockTaskMode(task);
7909        }
7910    }
7911
7912    @Override
7913    public void startLockTaskModeOnCurrent() throws RemoteException {
7914        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7915        ActivityRecord r = null;
7916        synchronized (this) {
7917            r = mStackSupervisor.topRunningActivityLocked();
7918        }
7919        startLockTaskMode(r.task);
7920    }
7921
7922    @Override
7923    public void stopLockTaskMode() {
7924        // Verify that the user matches the package of the intent for the TaskRecord
7925        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
7926        // and stopLockTaskMode.
7927        final int callingUid = Binder.getCallingUid();
7928        if (callingUid != Process.SYSTEM_UID) {
7929            try {
7930                String pkg =
7931                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
7932                int uid = mContext.getPackageManager().getPackageUid(pkg,
7933                        Binder.getCallingUserHandle().getIdentifier());
7934                if (uid != callingUid) {
7935                    throw new SecurityException("Invalid uid, expected " + uid);
7936                }
7937            } catch (NameNotFoundException e) {
7938                Log.d(TAG, "stopLockTaskMode " + e);
7939                return;
7940            }
7941        }
7942        long ident = Binder.clearCallingIdentity();
7943        try {
7944            Log.d(TAG, "stopLockTaskMode");
7945            // Stop lock task
7946            synchronized (this) {
7947                mStackSupervisor.setLockTaskModeLocked(null, false);
7948            }
7949        } finally {
7950            Binder.restoreCallingIdentity(ident);
7951        }
7952    }
7953
7954    @Override
7955    public void stopLockTaskModeOnCurrent() throws RemoteException {
7956        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7957        long ident = Binder.clearCallingIdentity();
7958        try {
7959            stopLockTaskMode();
7960        } finally {
7961            Binder.restoreCallingIdentity(ident);
7962        }
7963    }
7964
7965    @Override
7966    public boolean isInLockTaskMode() {
7967        synchronized (this) {
7968            return mStackSupervisor.isInLockTaskMode();
7969        }
7970    }
7971
7972    // =========================================================
7973    // CONTENT PROVIDERS
7974    // =========================================================
7975
7976    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7977        List<ProviderInfo> providers = null;
7978        try {
7979            providers = AppGlobals.getPackageManager().
7980                queryContentProviders(app.processName, app.uid,
7981                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7982        } catch (RemoteException ex) {
7983        }
7984        if (DEBUG_MU)
7985            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7986        int userId = app.userId;
7987        if (providers != null) {
7988            int N = providers.size();
7989            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7990            for (int i=0; i<N; i++) {
7991                ProviderInfo cpi =
7992                    (ProviderInfo)providers.get(i);
7993                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7994                        cpi.name, cpi.flags);
7995                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7996                    // This is a singleton provider, but a user besides the
7997                    // default user is asking to initialize a process it runs
7998                    // in...  well, no, it doesn't actually run in this process,
7999                    // it runs in the process of the default user.  Get rid of it.
8000                    providers.remove(i);
8001                    N--;
8002                    i--;
8003                    continue;
8004                }
8005
8006                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8007                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8008                if (cpr == null) {
8009                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8010                    mProviderMap.putProviderByClass(comp, cpr);
8011                }
8012                if (DEBUG_MU)
8013                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8014                app.pubProviders.put(cpi.name, cpr);
8015                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8016                    // Don't add this if it is a platform component that is marked
8017                    // to run in multiple processes, because this is actually
8018                    // part of the framework so doesn't make sense to track as a
8019                    // separate apk in the process.
8020                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8021                            mProcessStats);
8022                }
8023                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8024            }
8025        }
8026        return providers;
8027    }
8028
8029    /**
8030     * Check if {@link ProcessRecord} has a possible chance at accessing the
8031     * given {@link ProviderInfo}. Final permission checking is always done
8032     * in {@link ContentProvider}.
8033     */
8034    private final String checkContentProviderPermissionLocked(
8035            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8036        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8037        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8038        boolean checkedGrants = false;
8039        if (checkUser) {
8040            // Looking for cross-user grants before enforcing the typical cross-users permissions
8041            int tmpTargetUserId = unsafeConvertIncomingUser(UserHandle.getUserId(callingUid));
8042            if (tmpTargetUserId != userId) {
8043                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8044                    return null;
8045                }
8046                checkedGrants = true;
8047            }
8048            userId = handleIncomingUser(callingPid, callingUid, userId,
8049                    false, ALLOW_NON_FULL_IN_PROFILE,
8050                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8051            if (userId != tmpTargetUserId) {
8052                // When we actually went to determine the final targer user ID, this ended
8053                // up different than our initial check for the authority.  This is because
8054                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8055                // SELF.  So we need to re-check the grants again.
8056                checkedGrants = false;
8057            }
8058        }
8059        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8060                cpi.applicationInfo.uid, cpi.exported)
8061                == PackageManager.PERMISSION_GRANTED) {
8062            return null;
8063        }
8064        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8065                cpi.applicationInfo.uid, cpi.exported)
8066                == PackageManager.PERMISSION_GRANTED) {
8067            return null;
8068        }
8069
8070        PathPermission[] pps = cpi.pathPermissions;
8071        if (pps != null) {
8072            int i = pps.length;
8073            while (i > 0) {
8074                i--;
8075                PathPermission pp = pps[i];
8076                String pprperm = pp.getReadPermission();
8077                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8078                        cpi.applicationInfo.uid, cpi.exported)
8079                        == PackageManager.PERMISSION_GRANTED) {
8080                    return null;
8081                }
8082                String ppwperm = pp.getWritePermission();
8083                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8084                        cpi.applicationInfo.uid, cpi.exported)
8085                        == PackageManager.PERMISSION_GRANTED) {
8086                    return null;
8087                }
8088            }
8089        }
8090        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8091            return null;
8092        }
8093
8094        String msg;
8095        if (!cpi.exported) {
8096            msg = "Permission Denial: opening provider " + cpi.name
8097                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8098                    + ", uid=" + callingUid + ") that is not exported from uid "
8099                    + cpi.applicationInfo.uid;
8100        } else {
8101            msg = "Permission Denial: opening provider " + cpi.name
8102                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8103                    + ", uid=" + callingUid + ") requires "
8104                    + cpi.readPermission + " or " + cpi.writePermission;
8105        }
8106        Slog.w(TAG, msg);
8107        return msg;
8108    }
8109
8110    /**
8111     * Returns if the ContentProvider has granted a uri to callingUid
8112     */
8113    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8114        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8115        if (perms != null) {
8116            for (int i=perms.size()-1; i>=0; i--) {
8117                GrantUri grantUri = perms.keyAt(i);
8118                if (grantUri.sourceUserId == userId || !checkUser) {
8119                    if (matchesProvider(grantUri.uri, cpi)) {
8120                        return true;
8121                    }
8122                }
8123            }
8124        }
8125        return false;
8126    }
8127
8128    /**
8129     * Returns true if the uri authority is one of the authorities specified in the provider.
8130     */
8131    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8132        String uriAuth = uri.getAuthority();
8133        String cpiAuth = cpi.authority;
8134        if (cpiAuth.indexOf(';') == -1) {
8135            return cpiAuth.equals(uriAuth);
8136        }
8137        String[] cpiAuths = cpiAuth.split(";");
8138        int length = cpiAuths.length;
8139        for (int i = 0; i < length; i++) {
8140            if (cpiAuths[i].equals(uriAuth)) return true;
8141        }
8142        return false;
8143    }
8144
8145    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8146            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8147        if (r != null) {
8148            for (int i=0; i<r.conProviders.size(); i++) {
8149                ContentProviderConnection conn = r.conProviders.get(i);
8150                if (conn.provider == cpr) {
8151                    if (DEBUG_PROVIDER) Slog.v(TAG,
8152                            "Adding provider requested by "
8153                            + r.processName + " from process "
8154                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8155                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8156                    if (stable) {
8157                        conn.stableCount++;
8158                        conn.numStableIncs++;
8159                    } else {
8160                        conn.unstableCount++;
8161                        conn.numUnstableIncs++;
8162                    }
8163                    return conn;
8164                }
8165            }
8166            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8167            if (stable) {
8168                conn.stableCount = 1;
8169                conn.numStableIncs = 1;
8170            } else {
8171                conn.unstableCount = 1;
8172                conn.numUnstableIncs = 1;
8173            }
8174            cpr.connections.add(conn);
8175            r.conProviders.add(conn);
8176            return conn;
8177        }
8178        cpr.addExternalProcessHandleLocked(externalProcessToken);
8179        return null;
8180    }
8181
8182    boolean decProviderCountLocked(ContentProviderConnection conn,
8183            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8184        if (conn != null) {
8185            cpr = conn.provider;
8186            if (DEBUG_PROVIDER) Slog.v(TAG,
8187                    "Removing provider requested by "
8188                    + conn.client.processName + " from process "
8189                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8190                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8191            if (stable) {
8192                conn.stableCount--;
8193            } else {
8194                conn.unstableCount--;
8195            }
8196            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8197                cpr.connections.remove(conn);
8198                conn.client.conProviders.remove(conn);
8199                return true;
8200            }
8201            return false;
8202        }
8203        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8204        return false;
8205    }
8206
8207    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8208            String name, IBinder token, boolean stable, int userId) {
8209        ContentProviderRecord cpr;
8210        ContentProviderConnection conn = null;
8211        ProviderInfo cpi = null;
8212
8213        synchronized(this) {
8214            ProcessRecord r = null;
8215            if (caller != null) {
8216                r = getRecordForAppLocked(caller);
8217                if (r == null) {
8218                    throw new SecurityException(
8219                            "Unable to find app for caller " + caller
8220                          + " (pid=" + Binder.getCallingPid()
8221                          + ") when getting content provider " + name);
8222                }
8223            }
8224
8225            boolean checkCrossUser = true;
8226
8227            // First check if this content provider has been published...
8228            cpr = mProviderMap.getProviderByName(name, userId);
8229            // If that didn't work, check if it exists for user 0 and then
8230            // verify that it's a singleton provider before using it.
8231            if (cpr == null && userId != UserHandle.USER_OWNER) {
8232                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8233                if (cpr != null) {
8234                    cpi = cpr.info;
8235                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8236                            cpi.name, cpi.flags)
8237                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8238                        userId = UserHandle.USER_OWNER;
8239                        checkCrossUser = false;
8240                    } else {
8241                        cpr = null;
8242                        cpi = null;
8243                    }
8244                }
8245            }
8246
8247            boolean providerRunning = cpr != null;
8248            if (providerRunning) {
8249                cpi = cpr.info;
8250                String msg;
8251                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8252                        != null) {
8253                    throw new SecurityException(msg);
8254                }
8255
8256                if (r != null && cpr.canRunHere(r)) {
8257                    // This provider has been published or is in the process
8258                    // of being published...  but it is also allowed to run
8259                    // in the caller's process, so don't make a connection
8260                    // and just let the caller instantiate its own instance.
8261                    ContentProviderHolder holder = cpr.newHolder(null);
8262                    // don't give caller the provider object, it needs
8263                    // to make its own.
8264                    holder.provider = null;
8265                    return holder;
8266                }
8267
8268                final long origId = Binder.clearCallingIdentity();
8269
8270                // In this case the provider instance already exists, so we can
8271                // return it right away.
8272                conn = incProviderCountLocked(r, cpr, token, stable);
8273                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8274                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8275                        // If this is a perceptible app accessing the provider,
8276                        // make sure to count it as being accessed and thus
8277                        // back up on the LRU list.  This is good because
8278                        // content providers are often expensive to start.
8279                        updateLruProcessLocked(cpr.proc, false, null);
8280                    }
8281                }
8282
8283                if (cpr.proc != null) {
8284                    if (false) {
8285                        if (cpr.name.flattenToShortString().equals(
8286                                "com.android.providers.calendar/.CalendarProvider2")) {
8287                            Slog.v(TAG, "****************** KILLING "
8288                                + cpr.name.flattenToShortString());
8289                            Process.killProcess(cpr.proc.pid);
8290                        }
8291                    }
8292                    boolean success = updateOomAdjLocked(cpr.proc);
8293                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8294                    // NOTE: there is still a race here where a signal could be
8295                    // pending on the process even though we managed to update its
8296                    // adj level.  Not sure what to do about this, but at least
8297                    // the race is now smaller.
8298                    if (!success) {
8299                        // Uh oh...  it looks like the provider's process
8300                        // has been killed on us.  We need to wait for a new
8301                        // process to be started, and make sure its death
8302                        // doesn't kill our process.
8303                        Slog.i(TAG,
8304                                "Existing provider " + cpr.name.flattenToShortString()
8305                                + " is crashing; detaching " + r);
8306                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8307                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8308                        if (!lastRef) {
8309                            // This wasn't the last ref our process had on
8310                            // the provider...  we have now been killed, bail.
8311                            return null;
8312                        }
8313                        providerRunning = false;
8314                        conn = null;
8315                    }
8316                }
8317
8318                Binder.restoreCallingIdentity(origId);
8319            }
8320
8321            boolean singleton;
8322            if (!providerRunning) {
8323                try {
8324                    cpi = AppGlobals.getPackageManager().
8325                        resolveContentProvider(name,
8326                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8327                } catch (RemoteException ex) {
8328                }
8329                if (cpi == null) {
8330                    return null;
8331                }
8332                // If the provider is a singleton AND
8333                // (it's a call within the same user || the provider is a
8334                // privileged app)
8335                // Then allow connecting to the singleton provider
8336                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8337                        cpi.name, cpi.flags)
8338                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8339                if (singleton) {
8340                    userId = UserHandle.USER_OWNER;
8341                }
8342                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8343
8344                String msg;
8345                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8346                        != null) {
8347                    throw new SecurityException(msg);
8348                }
8349
8350                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8351                        && !cpi.processName.equals("system")) {
8352                    // If this content provider does not run in the system
8353                    // process, and the system is not yet ready to run other
8354                    // processes, then fail fast instead of hanging.
8355                    throw new IllegalArgumentException(
8356                            "Attempt to launch content provider before system ready");
8357                }
8358
8359                // Make sure that the user who owns this provider is started.  If not,
8360                // we don't want to allow it to run.
8361                if (mStartedUsers.get(userId) == null) {
8362                    Slog.w(TAG, "Unable to launch app "
8363                            + cpi.applicationInfo.packageName + "/"
8364                            + cpi.applicationInfo.uid + " for provider "
8365                            + name + ": user " + userId + " is stopped");
8366                    return null;
8367                }
8368
8369                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8370                cpr = mProviderMap.getProviderByClass(comp, userId);
8371                final boolean firstClass = cpr == null;
8372                if (firstClass) {
8373                    try {
8374                        ApplicationInfo ai =
8375                            AppGlobals.getPackageManager().
8376                                getApplicationInfo(
8377                                        cpi.applicationInfo.packageName,
8378                                        STOCK_PM_FLAGS, userId);
8379                        if (ai == null) {
8380                            Slog.w(TAG, "No package info for content provider "
8381                                    + cpi.name);
8382                            return null;
8383                        }
8384                        ai = getAppInfoForUser(ai, userId);
8385                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8386                    } catch (RemoteException ex) {
8387                        // pm is in same process, this will never happen.
8388                    }
8389                }
8390
8391                if (r != null && cpr.canRunHere(r)) {
8392                    // If this is a multiprocess provider, then just return its
8393                    // info and allow the caller to instantiate it.  Only do
8394                    // this if the provider is the same user as the caller's
8395                    // process, or can run as root (so can be in any process).
8396                    return cpr.newHolder(null);
8397                }
8398
8399                if (DEBUG_PROVIDER) {
8400                    RuntimeException e = new RuntimeException("here");
8401                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8402                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8403                }
8404
8405                // This is single process, and our app is now connecting to it.
8406                // See if we are already in the process of launching this
8407                // provider.
8408                final int N = mLaunchingProviders.size();
8409                int i;
8410                for (i=0; i<N; i++) {
8411                    if (mLaunchingProviders.get(i) == cpr) {
8412                        break;
8413                    }
8414                }
8415
8416                // If the provider is not already being launched, then get it
8417                // started.
8418                if (i >= N) {
8419                    final long origId = Binder.clearCallingIdentity();
8420
8421                    try {
8422                        // Content provider is now in use, its package can't be stopped.
8423                        try {
8424                            AppGlobals.getPackageManager().setPackageStoppedState(
8425                                    cpr.appInfo.packageName, false, userId);
8426                        } catch (RemoteException e) {
8427                        } catch (IllegalArgumentException e) {
8428                            Slog.w(TAG, "Failed trying to unstop package "
8429                                    + cpr.appInfo.packageName + ": " + e);
8430                        }
8431
8432                        // Use existing process if already started
8433                        ProcessRecord proc = getProcessRecordLocked(
8434                                cpi.processName, cpr.appInfo.uid, false);
8435                        if (proc != null && proc.thread != null) {
8436                            if (DEBUG_PROVIDER) {
8437                                Slog.d(TAG, "Installing in existing process " + proc);
8438                            }
8439                            proc.pubProviders.put(cpi.name, cpr);
8440                            try {
8441                                proc.thread.scheduleInstallProvider(cpi);
8442                            } catch (RemoteException e) {
8443                            }
8444                        } else {
8445                            proc = startProcessLocked(cpi.processName,
8446                                    cpr.appInfo, false, 0, "content provider",
8447                                    new ComponentName(cpi.applicationInfo.packageName,
8448                                            cpi.name), false, false, false);
8449                            if (proc == null) {
8450                                Slog.w(TAG, "Unable to launch app "
8451                                        + cpi.applicationInfo.packageName + "/"
8452                                        + cpi.applicationInfo.uid + " for provider "
8453                                        + name + ": process is bad");
8454                                return null;
8455                            }
8456                        }
8457                        cpr.launchingApp = proc;
8458                        mLaunchingProviders.add(cpr);
8459                    } finally {
8460                        Binder.restoreCallingIdentity(origId);
8461                    }
8462                }
8463
8464                // Make sure the provider is published (the same provider class
8465                // may be published under multiple names).
8466                if (firstClass) {
8467                    mProviderMap.putProviderByClass(comp, cpr);
8468                }
8469
8470                mProviderMap.putProviderByName(name, cpr);
8471                conn = incProviderCountLocked(r, cpr, token, stable);
8472                if (conn != null) {
8473                    conn.waiting = true;
8474                }
8475            }
8476        }
8477
8478        // Wait for the provider to be published...
8479        synchronized (cpr) {
8480            while (cpr.provider == null) {
8481                if (cpr.launchingApp == null) {
8482                    Slog.w(TAG, "Unable to launch app "
8483                            + cpi.applicationInfo.packageName + "/"
8484                            + cpi.applicationInfo.uid + " for provider "
8485                            + name + ": launching app became null");
8486                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8487                            UserHandle.getUserId(cpi.applicationInfo.uid),
8488                            cpi.applicationInfo.packageName,
8489                            cpi.applicationInfo.uid, name);
8490                    return null;
8491                }
8492                try {
8493                    if (DEBUG_MU) {
8494                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8495                                + cpr.launchingApp);
8496                    }
8497                    if (conn != null) {
8498                        conn.waiting = true;
8499                    }
8500                    cpr.wait();
8501                } catch (InterruptedException ex) {
8502                } finally {
8503                    if (conn != null) {
8504                        conn.waiting = false;
8505                    }
8506                }
8507            }
8508        }
8509        return cpr != null ? cpr.newHolder(conn) : null;
8510    }
8511
8512    @Override
8513    public final ContentProviderHolder getContentProvider(
8514            IApplicationThread caller, String name, int userId, boolean stable) {
8515        enforceNotIsolatedCaller("getContentProvider");
8516        if (caller == null) {
8517            String msg = "null IApplicationThread when getting content provider "
8518                    + name;
8519            Slog.w(TAG, msg);
8520            throw new SecurityException(msg);
8521        }
8522        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8523        // with cross-user grant.
8524        return getContentProviderImpl(caller, name, null, stable, userId);
8525    }
8526
8527    public ContentProviderHolder getContentProviderExternal(
8528            String name, int userId, IBinder token) {
8529        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8530            "Do not have permission in call getContentProviderExternal()");
8531        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8532                false, ALLOW_FULL_ONLY, "getContentProvider", null);
8533        return getContentProviderExternalUnchecked(name, token, userId);
8534    }
8535
8536    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8537            IBinder token, int userId) {
8538        return getContentProviderImpl(null, name, token, true, userId);
8539    }
8540
8541    /**
8542     * Drop a content provider from a ProcessRecord's bookkeeping
8543     */
8544    public void removeContentProvider(IBinder connection, boolean stable) {
8545        enforceNotIsolatedCaller("removeContentProvider");
8546        long ident = Binder.clearCallingIdentity();
8547        try {
8548            synchronized (this) {
8549                ContentProviderConnection conn;
8550                try {
8551                    conn = (ContentProviderConnection)connection;
8552                } catch (ClassCastException e) {
8553                    String msg ="removeContentProvider: " + connection
8554                            + " not a ContentProviderConnection";
8555                    Slog.w(TAG, msg);
8556                    throw new IllegalArgumentException(msg);
8557                }
8558                if (conn == null) {
8559                    throw new NullPointerException("connection is null");
8560                }
8561                if (decProviderCountLocked(conn, null, null, stable)) {
8562                    updateOomAdjLocked();
8563                }
8564            }
8565        } finally {
8566            Binder.restoreCallingIdentity(ident);
8567        }
8568    }
8569
8570    public void removeContentProviderExternal(String name, IBinder token) {
8571        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8572            "Do not have permission in call removeContentProviderExternal()");
8573        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8574    }
8575
8576    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8577        synchronized (this) {
8578            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8579            if(cpr == null) {
8580                //remove from mProvidersByClass
8581                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8582                return;
8583            }
8584
8585            //update content provider record entry info
8586            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8587            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8588            if (localCpr.hasExternalProcessHandles()) {
8589                if (localCpr.removeExternalProcessHandleLocked(token)) {
8590                    updateOomAdjLocked();
8591                } else {
8592                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8593                            + " with no external reference for token: "
8594                            + token + ".");
8595                }
8596            } else {
8597                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8598                        + " with no external references.");
8599            }
8600        }
8601    }
8602
8603    public final void publishContentProviders(IApplicationThread caller,
8604            List<ContentProviderHolder> providers) {
8605        if (providers == null) {
8606            return;
8607        }
8608
8609        enforceNotIsolatedCaller("publishContentProviders");
8610        synchronized (this) {
8611            final ProcessRecord r = getRecordForAppLocked(caller);
8612            if (DEBUG_MU)
8613                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8614            if (r == null) {
8615                throw new SecurityException(
8616                        "Unable to find app for caller " + caller
8617                      + " (pid=" + Binder.getCallingPid()
8618                      + ") when publishing content providers");
8619            }
8620
8621            final long origId = Binder.clearCallingIdentity();
8622
8623            final int N = providers.size();
8624            for (int i=0; i<N; i++) {
8625                ContentProviderHolder src = providers.get(i);
8626                if (src == null || src.info == null || src.provider == null) {
8627                    continue;
8628                }
8629                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8630                if (DEBUG_MU)
8631                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8632                if (dst != null) {
8633                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8634                    mProviderMap.putProviderByClass(comp, dst);
8635                    String names[] = dst.info.authority.split(";");
8636                    for (int j = 0; j < names.length; j++) {
8637                        mProviderMap.putProviderByName(names[j], dst);
8638                    }
8639
8640                    int NL = mLaunchingProviders.size();
8641                    int j;
8642                    for (j=0; j<NL; j++) {
8643                        if (mLaunchingProviders.get(j) == dst) {
8644                            mLaunchingProviders.remove(j);
8645                            j--;
8646                            NL--;
8647                        }
8648                    }
8649                    synchronized (dst) {
8650                        dst.provider = src.provider;
8651                        dst.proc = r;
8652                        dst.notifyAll();
8653                    }
8654                    updateOomAdjLocked(r);
8655                }
8656            }
8657
8658            Binder.restoreCallingIdentity(origId);
8659        }
8660    }
8661
8662    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8663        ContentProviderConnection conn;
8664        try {
8665            conn = (ContentProviderConnection)connection;
8666        } catch (ClassCastException e) {
8667            String msg ="refContentProvider: " + connection
8668                    + " not a ContentProviderConnection";
8669            Slog.w(TAG, msg);
8670            throw new IllegalArgumentException(msg);
8671        }
8672        if (conn == null) {
8673            throw new NullPointerException("connection is null");
8674        }
8675
8676        synchronized (this) {
8677            if (stable > 0) {
8678                conn.numStableIncs += stable;
8679            }
8680            stable = conn.stableCount + stable;
8681            if (stable < 0) {
8682                throw new IllegalStateException("stableCount < 0: " + stable);
8683            }
8684
8685            if (unstable > 0) {
8686                conn.numUnstableIncs += unstable;
8687            }
8688            unstable = conn.unstableCount + unstable;
8689            if (unstable < 0) {
8690                throw new IllegalStateException("unstableCount < 0: " + unstable);
8691            }
8692
8693            if ((stable+unstable) <= 0) {
8694                throw new IllegalStateException("ref counts can't go to zero here: stable="
8695                        + stable + " unstable=" + unstable);
8696            }
8697            conn.stableCount = stable;
8698            conn.unstableCount = unstable;
8699            return !conn.dead;
8700        }
8701    }
8702
8703    public void unstableProviderDied(IBinder connection) {
8704        ContentProviderConnection conn;
8705        try {
8706            conn = (ContentProviderConnection)connection;
8707        } catch (ClassCastException e) {
8708            String msg ="refContentProvider: " + connection
8709                    + " not a ContentProviderConnection";
8710            Slog.w(TAG, msg);
8711            throw new IllegalArgumentException(msg);
8712        }
8713        if (conn == null) {
8714            throw new NullPointerException("connection is null");
8715        }
8716
8717        // Safely retrieve the content provider associated with the connection.
8718        IContentProvider provider;
8719        synchronized (this) {
8720            provider = conn.provider.provider;
8721        }
8722
8723        if (provider == null) {
8724            // Um, yeah, we're way ahead of you.
8725            return;
8726        }
8727
8728        // Make sure the caller is being honest with us.
8729        if (provider.asBinder().pingBinder()) {
8730            // Er, no, still looks good to us.
8731            synchronized (this) {
8732                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8733                        + " says " + conn + " died, but we don't agree");
8734                return;
8735            }
8736        }
8737
8738        // Well look at that!  It's dead!
8739        synchronized (this) {
8740            if (conn.provider.provider != provider) {
8741                // But something changed...  good enough.
8742                return;
8743            }
8744
8745            ProcessRecord proc = conn.provider.proc;
8746            if (proc == null || proc.thread == null) {
8747                // Seems like the process is already cleaned up.
8748                return;
8749            }
8750
8751            // As far as we're concerned, this is just like receiving a
8752            // death notification...  just a bit prematurely.
8753            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8754                    + ") early provider death");
8755            final long ident = Binder.clearCallingIdentity();
8756            try {
8757                appDiedLocked(proc, proc.pid, proc.thread);
8758            } finally {
8759                Binder.restoreCallingIdentity(ident);
8760            }
8761        }
8762    }
8763
8764    @Override
8765    public void appNotRespondingViaProvider(IBinder connection) {
8766        enforceCallingPermission(
8767                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8768
8769        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8770        if (conn == null) {
8771            Slog.w(TAG, "ContentProviderConnection is null");
8772            return;
8773        }
8774
8775        final ProcessRecord host = conn.provider.proc;
8776        if (host == null) {
8777            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8778            return;
8779        }
8780
8781        final long token = Binder.clearCallingIdentity();
8782        try {
8783            appNotResponding(host, null, null, false, "ContentProvider not responding");
8784        } finally {
8785            Binder.restoreCallingIdentity(token);
8786        }
8787    }
8788
8789    public final void installSystemProviders() {
8790        List<ProviderInfo> providers;
8791        synchronized (this) {
8792            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8793            providers = generateApplicationProvidersLocked(app);
8794            if (providers != null) {
8795                for (int i=providers.size()-1; i>=0; i--) {
8796                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8797                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8798                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8799                                + ": not system .apk");
8800                        providers.remove(i);
8801                    }
8802                }
8803            }
8804        }
8805        if (providers != null) {
8806            mSystemThread.installSystemProviders(providers);
8807        }
8808
8809        mCoreSettingsObserver = new CoreSettingsObserver(this);
8810
8811        mUsageStatsService.monitorPackages();
8812    }
8813
8814    /**
8815     * Allows app to retrieve the MIME type of a URI without having permission
8816     * to access its content provider.
8817     *
8818     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8819     *
8820     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8821     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8822     */
8823    public String getProviderMimeType(Uri uri, int userId) {
8824        enforceNotIsolatedCaller("getProviderMimeType");
8825        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8826                userId, false, ALLOW_NON_FULL_IN_PROFILE, "getProviderMimeType", null);
8827        final String name = uri.getAuthority();
8828        final long ident = Binder.clearCallingIdentity();
8829        ContentProviderHolder holder = null;
8830
8831        try {
8832            holder = getContentProviderExternalUnchecked(name, null, userId);
8833            if (holder != null) {
8834                return holder.provider.getType(uri);
8835            }
8836        } catch (RemoteException e) {
8837            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8838            return null;
8839        } finally {
8840            if (holder != null) {
8841                removeContentProviderExternalUnchecked(name, null, userId);
8842            }
8843            Binder.restoreCallingIdentity(ident);
8844        }
8845
8846        return null;
8847    }
8848
8849    // =========================================================
8850    // GLOBAL MANAGEMENT
8851    // =========================================================
8852
8853    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8854            boolean isolated) {
8855        String proc = customProcess != null ? customProcess : info.processName;
8856        BatteryStatsImpl.Uid.Proc ps = null;
8857        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8858        int uid = info.uid;
8859        if (isolated) {
8860            int userId = UserHandle.getUserId(uid);
8861            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8862            while (true) {
8863                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8864                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8865                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8866                }
8867                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8868                mNextIsolatedProcessUid++;
8869                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8870                    // No process for this uid, use it.
8871                    break;
8872                }
8873                stepsLeft--;
8874                if (stepsLeft <= 0) {
8875                    return null;
8876                }
8877            }
8878        }
8879        return new ProcessRecord(stats, info, proc, uid);
8880    }
8881
8882    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8883            String abiOverride) {
8884        ProcessRecord app;
8885        if (!isolated) {
8886            app = getProcessRecordLocked(info.processName, info.uid, true);
8887        } else {
8888            app = null;
8889        }
8890
8891        if (app == null) {
8892            app = newProcessRecordLocked(info, null, isolated);
8893            mProcessNames.put(info.processName, app.uid, app);
8894            if (isolated) {
8895                mIsolatedProcesses.put(app.uid, app);
8896            }
8897            updateLruProcessLocked(app, false, null);
8898            updateOomAdjLocked();
8899        }
8900
8901        // This package really, really can not be stopped.
8902        try {
8903            AppGlobals.getPackageManager().setPackageStoppedState(
8904                    info.packageName, false, UserHandle.getUserId(app.uid));
8905        } catch (RemoteException e) {
8906        } catch (IllegalArgumentException e) {
8907            Slog.w(TAG, "Failed trying to unstop package "
8908                    + info.packageName + ": " + e);
8909        }
8910
8911        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8912                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8913            app.persistent = true;
8914            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8915        }
8916        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8917            mPersistentStartingProcesses.add(app);
8918            startProcessLocked(app, "added application", app.processName,
8919                    abiOverride);
8920        }
8921
8922        return app;
8923    }
8924
8925    public void unhandledBack() {
8926        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8927                "unhandledBack()");
8928
8929        synchronized(this) {
8930            final long origId = Binder.clearCallingIdentity();
8931            try {
8932                getFocusedStack().unhandledBackLocked();
8933            } finally {
8934                Binder.restoreCallingIdentity(origId);
8935            }
8936        }
8937    }
8938
8939    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8940        enforceNotIsolatedCaller("openContentUri");
8941        final int userId = UserHandle.getCallingUserId();
8942        String name = uri.getAuthority();
8943        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8944        ParcelFileDescriptor pfd = null;
8945        if (cph != null) {
8946            // We record the binder invoker's uid in thread-local storage before
8947            // going to the content provider to open the file.  Later, in the code
8948            // that handles all permissions checks, we look for this uid and use
8949            // that rather than the Activity Manager's own uid.  The effect is that
8950            // we do the check against the caller's permissions even though it looks
8951            // to the content provider like the Activity Manager itself is making
8952            // the request.
8953            sCallerIdentity.set(new Identity(
8954                    Binder.getCallingPid(), Binder.getCallingUid()));
8955            try {
8956                pfd = cph.provider.openFile(null, uri, "r", null);
8957            } catch (FileNotFoundException e) {
8958                // do nothing; pfd will be returned null
8959            } finally {
8960                // Ensure that whatever happens, we clean up the identity state
8961                sCallerIdentity.remove();
8962            }
8963
8964            // We've got the fd now, so we're done with the provider.
8965            removeContentProviderExternalUnchecked(name, null, userId);
8966        } else {
8967            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8968        }
8969        return pfd;
8970    }
8971
8972    // Actually is sleeping or shutting down or whatever else in the future
8973    // is an inactive state.
8974    public boolean isSleepingOrShuttingDown() {
8975        return mSleeping || mShuttingDown;
8976    }
8977
8978    public boolean isSleeping() {
8979        return mSleeping;
8980    }
8981
8982    void goingToSleep() {
8983        synchronized(this) {
8984            mWentToSleep = true;
8985            updateEventDispatchingLocked();
8986            goToSleepIfNeededLocked();
8987        }
8988    }
8989
8990    void finishRunningVoiceLocked() {
8991        if (mRunningVoice) {
8992            mRunningVoice = false;
8993            goToSleepIfNeededLocked();
8994        }
8995    }
8996
8997    void goToSleepIfNeededLocked() {
8998        if (mWentToSleep && !mRunningVoice) {
8999            if (!mSleeping) {
9000                mSleeping = true;
9001                mStackSupervisor.goingToSleepLocked();
9002
9003                // Initialize the wake times of all processes.
9004                checkExcessivePowerUsageLocked(false);
9005                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9006                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9007                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9008            }
9009        }
9010    }
9011
9012    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9013        mTaskPersister.notify(task, flush);
9014    }
9015
9016    @Override
9017    public boolean shutdown(int timeout) {
9018        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9019                != PackageManager.PERMISSION_GRANTED) {
9020            throw new SecurityException("Requires permission "
9021                    + android.Manifest.permission.SHUTDOWN);
9022        }
9023
9024        boolean timedout = false;
9025
9026        synchronized(this) {
9027            mShuttingDown = true;
9028            updateEventDispatchingLocked();
9029            timedout = mStackSupervisor.shutdownLocked(timeout);
9030        }
9031
9032        mAppOpsService.shutdown();
9033        mUsageStatsService.shutdown();
9034        mBatteryStatsService.shutdown();
9035        synchronized (this) {
9036            mProcessStats.shutdownLocked();
9037        }
9038        notifyTaskPersisterLocked(null, true);
9039
9040        return timedout;
9041    }
9042
9043    public final void activitySlept(IBinder token) {
9044        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9045
9046        final long origId = Binder.clearCallingIdentity();
9047
9048        synchronized (this) {
9049            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9050            if (r != null) {
9051                mStackSupervisor.activitySleptLocked(r);
9052            }
9053        }
9054
9055        Binder.restoreCallingIdentity(origId);
9056    }
9057
9058    void logLockScreen(String msg) {
9059        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9060                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9061                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
9062                mStackSupervisor.mDismissKeyguardOnNextActivity);
9063    }
9064
9065    private void comeOutOfSleepIfNeededLocked() {
9066        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9067            if (mSleeping) {
9068                mSleeping = false;
9069                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9070            }
9071        }
9072    }
9073
9074    void wakingUp() {
9075        synchronized(this) {
9076            mWentToSleep = false;
9077            updateEventDispatchingLocked();
9078            comeOutOfSleepIfNeededLocked();
9079        }
9080    }
9081
9082    void startRunningVoiceLocked() {
9083        if (!mRunningVoice) {
9084            mRunningVoice = true;
9085            comeOutOfSleepIfNeededLocked();
9086        }
9087    }
9088
9089    private void updateEventDispatchingLocked() {
9090        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9091    }
9092
9093    public void setLockScreenShown(boolean shown) {
9094        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9095                != PackageManager.PERMISSION_GRANTED) {
9096            throw new SecurityException("Requires permission "
9097                    + android.Manifest.permission.DEVICE_POWER);
9098        }
9099
9100        synchronized(this) {
9101            long ident = Binder.clearCallingIdentity();
9102            try {
9103                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9104                mLockScreenShown = shown;
9105                comeOutOfSleepIfNeededLocked();
9106            } finally {
9107                Binder.restoreCallingIdentity(ident);
9108            }
9109        }
9110    }
9111
9112    public void stopAppSwitches() {
9113        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9114                != PackageManager.PERMISSION_GRANTED) {
9115            throw new SecurityException("Requires permission "
9116                    + android.Manifest.permission.STOP_APP_SWITCHES);
9117        }
9118
9119        synchronized(this) {
9120            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9121                    + APP_SWITCH_DELAY_TIME;
9122            mDidAppSwitch = false;
9123            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9124            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9125            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9126        }
9127    }
9128
9129    public void resumeAppSwitches() {
9130        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9131                != PackageManager.PERMISSION_GRANTED) {
9132            throw new SecurityException("Requires permission "
9133                    + android.Manifest.permission.STOP_APP_SWITCHES);
9134        }
9135
9136        synchronized(this) {
9137            // Note that we don't execute any pending app switches... we will
9138            // let those wait until either the timeout, or the next start
9139            // activity request.
9140            mAppSwitchesAllowedTime = 0;
9141        }
9142    }
9143
9144    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9145            String name) {
9146        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9147            return true;
9148        }
9149
9150        final int perm = checkComponentPermission(
9151                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9152                callingUid, -1, true);
9153        if (perm == PackageManager.PERMISSION_GRANTED) {
9154            return true;
9155        }
9156
9157        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9158        return false;
9159    }
9160
9161    public void setDebugApp(String packageName, boolean waitForDebugger,
9162            boolean persistent) {
9163        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9164                "setDebugApp()");
9165
9166        long ident = Binder.clearCallingIdentity();
9167        try {
9168            // Note that this is not really thread safe if there are multiple
9169            // callers into it at the same time, but that's not a situation we
9170            // care about.
9171            if (persistent) {
9172                final ContentResolver resolver = mContext.getContentResolver();
9173                Settings.Global.putString(
9174                    resolver, Settings.Global.DEBUG_APP,
9175                    packageName);
9176                Settings.Global.putInt(
9177                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9178                    waitForDebugger ? 1 : 0);
9179            }
9180
9181            synchronized (this) {
9182                if (!persistent) {
9183                    mOrigDebugApp = mDebugApp;
9184                    mOrigWaitForDebugger = mWaitForDebugger;
9185                }
9186                mDebugApp = packageName;
9187                mWaitForDebugger = waitForDebugger;
9188                mDebugTransient = !persistent;
9189                if (packageName != null) {
9190                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9191                            false, UserHandle.USER_ALL, "set debug app");
9192                }
9193            }
9194        } finally {
9195            Binder.restoreCallingIdentity(ident);
9196        }
9197    }
9198
9199    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9200        synchronized (this) {
9201            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9202            if (!isDebuggable) {
9203                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9204                    throw new SecurityException("Process not debuggable: " + app.packageName);
9205                }
9206            }
9207
9208            mOpenGlTraceApp = processName;
9209        }
9210    }
9211
9212    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9213            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9214        synchronized (this) {
9215            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9216            if (!isDebuggable) {
9217                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9218                    throw new SecurityException("Process not debuggable: " + app.packageName);
9219                }
9220            }
9221            mProfileApp = processName;
9222            mProfileFile = profileFile;
9223            if (mProfileFd != null) {
9224                try {
9225                    mProfileFd.close();
9226                } catch (IOException e) {
9227                }
9228                mProfileFd = null;
9229            }
9230            mProfileFd = profileFd;
9231            mProfileType = 0;
9232            mAutoStopProfiler = autoStopProfiler;
9233        }
9234    }
9235
9236    @Override
9237    public void setAlwaysFinish(boolean enabled) {
9238        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9239                "setAlwaysFinish()");
9240
9241        Settings.Global.putInt(
9242                mContext.getContentResolver(),
9243                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9244
9245        synchronized (this) {
9246            mAlwaysFinishActivities = enabled;
9247        }
9248    }
9249
9250    @Override
9251    public void setActivityController(IActivityController controller) {
9252        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9253                "setActivityController()");
9254        synchronized (this) {
9255            mController = controller;
9256            Watchdog.getInstance().setActivityController(controller);
9257        }
9258    }
9259
9260    @Override
9261    public void setUserIsMonkey(boolean userIsMonkey) {
9262        synchronized (this) {
9263            synchronized (mPidsSelfLocked) {
9264                final int callingPid = Binder.getCallingPid();
9265                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9266                if (precessRecord == null) {
9267                    throw new SecurityException("Unknown process: " + callingPid);
9268                }
9269                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9270                    throw new SecurityException("Only an instrumentation process "
9271                            + "with a UiAutomation can call setUserIsMonkey");
9272                }
9273            }
9274            mUserIsMonkey = userIsMonkey;
9275        }
9276    }
9277
9278    @Override
9279    public boolean isUserAMonkey() {
9280        synchronized (this) {
9281            // If there is a controller also implies the user is a monkey.
9282            return (mUserIsMonkey || mController != null);
9283        }
9284    }
9285
9286    public void requestBugReport() {
9287        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9288        SystemProperties.set("ctl.start", "bugreport");
9289    }
9290
9291    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9292        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9293    }
9294
9295    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9296        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9297            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9298        }
9299        return KEY_DISPATCHING_TIMEOUT;
9300    }
9301
9302    @Override
9303    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9304        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9305                != PackageManager.PERMISSION_GRANTED) {
9306            throw new SecurityException("Requires permission "
9307                    + android.Manifest.permission.FILTER_EVENTS);
9308        }
9309        ProcessRecord proc;
9310        long timeout;
9311        synchronized (this) {
9312            synchronized (mPidsSelfLocked) {
9313                proc = mPidsSelfLocked.get(pid);
9314            }
9315            timeout = getInputDispatchingTimeoutLocked(proc);
9316        }
9317
9318        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9319            return -1;
9320        }
9321
9322        return timeout;
9323    }
9324
9325    /**
9326     * Handle input dispatching timeouts.
9327     * Returns whether input dispatching should be aborted or not.
9328     */
9329    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9330            final ActivityRecord activity, final ActivityRecord parent,
9331            final boolean aboveSystem, String reason) {
9332        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9333                != PackageManager.PERMISSION_GRANTED) {
9334            throw new SecurityException("Requires permission "
9335                    + android.Manifest.permission.FILTER_EVENTS);
9336        }
9337
9338        final String annotation;
9339        if (reason == null) {
9340            annotation = "Input dispatching timed out";
9341        } else {
9342            annotation = "Input dispatching timed out (" + reason + ")";
9343        }
9344
9345        if (proc != null) {
9346            synchronized (this) {
9347                if (proc.debugging) {
9348                    return false;
9349                }
9350
9351                if (mDidDexOpt) {
9352                    // Give more time since we were dexopting.
9353                    mDidDexOpt = false;
9354                    return false;
9355                }
9356
9357                if (proc.instrumentationClass != null) {
9358                    Bundle info = new Bundle();
9359                    info.putString("shortMsg", "keyDispatchingTimedOut");
9360                    info.putString("longMsg", annotation);
9361                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9362                    return true;
9363                }
9364            }
9365            mHandler.post(new Runnable() {
9366                @Override
9367                public void run() {
9368                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9369                }
9370            });
9371        }
9372
9373        return true;
9374    }
9375
9376    public Bundle getAssistContextExtras(int requestType) {
9377        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9378                "getAssistContextExtras()");
9379        PendingAssistExtras pae;
9380        Bundle extras = new Bundle();
9381        synchronized (this) {
9382            ActivityRecord activity = getFocusedStack().mResumedActivity;
9383            if (activity == null) {
9384                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9385                return null;
9386            }
9387            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9388            if (activity.app == null || activity.app.thread == null) {
9389                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9390                return extras;
9391            }
9392            if (activity.app.pid == Binder.getCallingPid()) {
9393                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9394                return extras;
9395            }
9396            pae = new PendingAssistExtras(activity);
9397            try {
9398                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9399                        requestType);
9400                mPendingAssistExtras.add(pae);
9401                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9402            } catch (RemoteException e) {
9403                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9404                return extras;
9405            }
9406        }
9407        synchronized (pae) {
9408            while (!pae.haveResult) {
9409                try {
9410                    pae.wait();
9411                } catch (InterruptedException e) {
9412                }
9413            }
9414            if (pae.result != null) {
9415                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9416            }
9417        }
9418        synchronized (this) {
9419            mPendingAssistExtras.remove(pae);
9420            mHandler.removeCallbacks(pae);
9421        }
9422        return extras;
9423    }
9424
9425    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9426        PendingAssistExtras pae = (PendingAssistExtras)token;
9427        synchronized (pae) {
9428            pae.result = extras;
9429            pae.haveResult = true;
9430            pae.notifyAll();
9431        }
9432    }
9433
9434    public void registerProcessObserver(IProcessObserver observer) {
9435        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9436                "registerProcessObserver()");
9437        synchronized (this) {
9438            mProcessObservers.register(observer);
9439        }
9440    }
9441
9442    @Override
9443    public void unregisterProcessObserver(IProcessObserver observer) {
9444        synchronized (this) {
9445            mProcessObservers.unregister(observer);
9446        }
9447    }
9448
9449    @Override
9450    public boolean convertFromTranslucent(IBinder token) {
9451        final long origId = Binder.clearCallingIdentity();
9452        try {
9453            synchronized (this) {
9454                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9455                if (r == null) {
9456                    return false;
9457                }
9458                if (r.changeWindowTranslucency(true)) {
9459                    mWindowManager.setAppFullscreen(token, true);
9460                    r.task.stack.releaseMediaResources();
9461                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9462                    return true;
9463                }
9464                return false;
9465            }
9466        } finally {
9467            Binder.restoreCallingIdentity(origId);
9468        }
9469    }
9470
9471    @Override
9472    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9473        final long origId = Binder.clearCallingIdentity();
9474        try {
9475            synchronized (this) {
9476                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9477                if (r == null) {
9478                    return false;
9479                }
9480                if (r.changeWindowTranslucency(false)) {
9481                    r.task.stack.convertToTranslucent(r, options);
9482                    mWindowManager.setAppFullscreen(token, false);
9483                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9484                    return true;
9485                } else {
9486                    r.task.stack.mReturningActivityOptions = options;
9487                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9488                    return false;
9489                }
9490            }
9491        } finally {
9492            Binder.restoreCallingIdentity(origId);
9493        }
9494    }
9495
9496    @Override
9497    public boolean setMediaPlaying(IBinder token, boolean playing) {
9498        final long origId = Binder.clearCallingIdentity();
9499        try {
9500            synchronized (this) {
9501                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9502                if (r != null) {
9503                    return mStackSupervisor.setMediaPlayingLocked(r, playing);
9504                }
9505            }
9506            return false;
9507        } finally {
9508            Binder.restoreCallingIdentity(origId);
9509        }
9510    }
9511
9512    @Override
9513    public boolean isBackgroundMediaPlaying(IBinder token) {
9514        final long origId = Binder.clearCallingIdentity();
9515        try {
9516            synchronized (this) {
9517                final ActivityStack stack = ActivityRecord.getStackLocked(token);
9518                final boolean playing = stack == null ? false : stack.isMediaPlaying();
9519                if (ActivityStackSupervisor.DEBUG_MEDIA_VISIBILITY) Slog.d(TAG,
9520                        "isBackgroundMediaPlaying: stack=" + stack + " playing=" + playing);
9521                return playing;
9522            }
9523        } finally {
9524            Binder.restoreCallingIdentity(origId);
9525        }
9526    }
9527
9528    @Override
9529    public ActivityOptions getActivityOptions(IBinder token) {
9530        final long origId = Binder.clearCallingIdentity();
9531        try {
9532            synchronized (this) {
9533                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9534                if (r != null) {
9535                    final ActivityOptions activityOptions = r.pendingOptions;
9536                    r.pendingOptions = null;
9537                    return activityOptions;
9538                }
9539                return null;
9540            }
9541        } finally {
9542            Binder.restoreCallingIdentity(origId);
9543        }
9544    }
9545
9546    @Override
9547    public void setImmersive(IBinder token, boolean immersive) {
9548        synchronized(this) {
9549            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9550            if (r == null) {
9551                throw new IllegalArgumentException();
9552            }
9553            r.immersive = immersive;
9554
9555            // update associated state if we're frontmost
9556            if (r == mFocusedActivity) {
9557                if (DEBUG_IMMERSIVE) {
9558                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9559                }
9560                applyUpdateLockStateLocked(r);
9561            }
9562        }
9563    }
9564
9565    @Override
9566    public boolean isImmersive(IBinder token) {
9567        synchronized (this) {
9568            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9569            if (r == null) {
9570                throw new IllegalArgumentException();
9571            }
9572            return r.immersive;
9573        }
9574    }
9575
9576    public boolean isTopActivityImmersive() {
9577        enforceNotIsolatedCaller("startActivity");
9578        synchronized (this) {
9579            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9580            return (r != null) ? r.immersive : false;
9581        }
9582    }
9583
9584    @Override
9585    public boolean isTopOfTask(IBinder token) {
9586        synchronized (this) {
9587            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9588            if (r == null) {
9589                throw new IllegalArgumentException();
9590            }
9591            return r.task.getTopActivity() == r;
9592        }
9593    }
9594
9595    public final void enterSafeMode() {
9596        synchronized(this) {
9597            // It only makes sense to do this before the system is ready
9598            // and started launching other packages.
9599            if (!mSystemReady) {
9600                try {
9601                    AppGlobals.getPackageManager().enterSafeMode();
9602                } catch (RemoteException e) {
9603                }
9604            }
9605
9606            mSafeMode = true;
9607        }
9608    }
9609
9610    public final void showSafeModeOverlay() {
9611        View v = LayoutInflater.from(mContext).inflate(
9612                com.android.internal.R.layout.safe_mode, null);
9613        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9614        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9615        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9616        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9617        lp.gravity = Gravity.BOTTOM | Gravity.START;
9618        lp.format = v.getBackground().getOpacity();
9619        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9620                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9621        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9622        ((WindowManager)mContext.getSystemService(
9623                Context.WINDOW_SERVICE)).addView(v, lp);
9624    }
9625
9626    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9627        if (!(sender instanceof PendingIntentRecord)) {
9628            return;
9629        }
9630        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9631        synchronized (stats) {
9632            if (mBatteryStatsService.isOnBattery()) {
9633                mBatteryStatsService.enforceCallingPermission();
9634                PendingIntentRecord rec = (PendingIntentRecord)sender;
9635                int MY_UID = Binder.getCallingUid();
9636                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9637                BatteryStatsImpl.Uid.Pkg pkg =
9638                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9639                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9640                pkg.incWakeupsLocked();
9641            }
9642        }
9643    }
9644
9645    public boolean killPids(int[] pids, String pReason, boolean secure) {
9646        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9647            throw new SecurityException("killPids only available to the system");
9648        }
9649        String reason = (pReason == null) ? "Unknown" : pReason;
9650        // XXX Note: don't acquire main activity lock here, because the window
9651        // manager calls in with its locks held.
9652
9653        boolean killed = false;
9654        synchronized (mPidsSelfLocked) {
9655            int[] types = new int[pids.length];
9656            int worstType = 0;
9657            for (int i=0; i<pids.length; i++) {
9658                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9659                if (proc != null) {
9660                    int type = proc.setAdj;
9661                    types[i] = type;
9662                    if (type > worstType) {
9663                        worstType = type;
9664                    }
9665                }
9666            }
9667
9668            // If the worst oom_adj is somewhere in the cached proc LRU range,
9669            // then constrain it so we will kill all cached procs.
9670            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9671                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9672                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9673            }
9674
9675            // If this is not a secure call, don't let it kill processes that
9676            // are important.
9677            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9678                worstType = ProcessList.SERVICE_ADJ;
9679            }
9680
9681            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9682            for (int i=0; i<pids.length; i++) {
9683                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9684                if (proc == null) {
9685                    continue;
9686                }
9687                int adj = proc.setAdj;
9688                if (adj >= worstType && !proc.killedByAm) {
9689                    killUnneededProcessLocked(proc, reason);
9690                    killed = true;
9691                }
9692            }
9693        }
9694        return killed;
9695    }
9696
9697    @Override
9698    public void killUid(int uid, String reason) {
9699        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9700            throw new SecurityException("killUid only available to the system");
9701        }
9702        synchronized (this) {
9703            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9704                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9705                    reason != null ? reason : "kill uid");
9706        }
9707    }
9708
9709    @Override
9710    public boolean killProcessesBelowForeground(String reason) {
9711        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9712            throw new SecurityException("killProcessesBelowForeground() only available to system");
9713        }
9714
9715        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9716    }
9717
9718    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9719        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9720            throw new SecurityException("killProcessesBelowAdj() only available to system");
9721        }
9722
9723        boolean killed = false;
9724        synchronized (mPidsSelfLocked) {
9725            final int size = mPidsSelfLocked.size();
9726            for (int i = 0; i < size; i++) {
9727                final int pid = mPidsSelfLocked.keyAt(i);
9728                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9729                if (proc == null) continue;
9730
9731                final int adj = proc.setAdj;
9732                if (adj > belowAdj && !proc.killedByAm) {
9733                    killUnneededProcessLocked(proc, reason);
9734                    killed = true;
9735                }
9736            }
9737        }
9738        return killed;
9739    }
9740
9741    @Override
9742    public void hang(final IBinder who, boolean allowRestart) {
9743        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9744                != PackageManager.PERMISSION_GRANTED) {
9745            throw new SecurityException("Requires permission "
9746                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9747        }
9748
9749        final IBinder.DeathRecipient death = new DeathRecipient() {
9750            @Override
9751            public void binderDied() {
9752                synchronized (this) {
9753                    notifyAll();
9754                }
9755            }
9756        };
9757
9758        try {
9759            who.linkToDeath(death, 0);
9760        } catch (RemoteException e) {
9761            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9762            return;
9763        }
9764
9765        synchronized (this) {
9766            Watchdog.getInstance().setAllowRestart(allowRestart);
9767            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9768            synchronized (death) {
9769                while (who.isBinderAlive()) {
9770                    try {
9771                        death.wait();
9772                    } catch (InterruptedException e) {
9773                    }
9774                }
9775            }
9776            Watchdog.getInstance().setAllowRestart(true);
9777        }
9778    }
9779
9780    @Override
9781    public void restart() {
9782        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9783                != PackageManager.PERMISSION_GRANTED) {
9784            throw new SecurityException("Requires permission "
9785                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9786        }
9787
9788        Log.i(TAG, "Sending shutdown broadcast...");
9789
9790        BroadcastReceiver br = new BroadcastReceiver() {
9791            @Override public void onReceive(Context context, Intent intent) {
9792                // Now the broadcast is done, finish up the low-level shutdown.
9793                Log.i(TAG, "Shutting down activity manager...");
9794                shutdown(10000);
9795                Log.i(TAG, "Shutdown complete, restarting!");
9796                Process.killProcess(Process.myPid());
9797                System.exit(10);
9798            }
9799        };
9800
9801        // First send the high-level shut down broadcast.
9802        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9803        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9804        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9805        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9806        mContext.sendOrderedBroadcastAsUser(intent,
9807                UserHandle.ALL, null, br, mHandler, 0, null, null);
9808        */
9809        br.onReceive(mContext, intent);
9810    }
9811
9812    private long getLowRamTimeSinceIdle(long now) {
9813        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9814    }
9815
9816    @Override
9817    public void performIdleMaintenance() {
9818        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9819                != PackageManager.PERMISSION_GRANTED) {
9820            throw new SecurityException("Requires permission "
9821                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9822        }
9823
9824        synchronized (this) {
9825            final long now = SystemClock.uptimeMillis();
9826            final long timeSinceLastIdle = now - mLastIdleTime;
9827            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9828            mLastIdleTime = now;
9829            mLowRamTimeSinceLastIdle = 0;
9830            if (mLowRamStartTime != 0) {
9831                mLowRamStartTime = now;
9832            }
9833
9834            StringBuilder sb = new StringBuilder(128);
9835            sb.append("Idle maintenance over ");
9836            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9837            sb.append(" low RAM for ");
9838            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9839            Slog.i(TAG, sb.toString());
9840
9841            // If at least 1/3 of our time since the last idle period has been spent
9842            // with RAM low, then we want to kill processes.
9843            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9844
9845            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9846                ProcessRecord proc = mLruProcesses.get(i);
9847                if (proc.notCachedSinceIdle) {
9848                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9849                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9850                        if (doKilling && proc.initialIdlePss != 0
9851                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9852                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9853                                    + " from " + proc.initialIdlePss + ")");
9854                        }
9855                    }
9856                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9857                    proc.notCachedSinceIdle = true;
9858                    proc.initialIdlePss = 0;
9859                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9860                            isSleeping(), now);
9861                }
9862            }
9863
9864            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9865            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9866        }
9867    }
9868
9869    private void retrieveSettings() {
9870        final ContentResolver resolver = mContext.getContentResolver();
9871        String debugApp = Settings.Global.getString(
9872            resolver, Settings.Global.DEBUG_APP);
9873        boolean waitForDebugger = Settings.Global.getInt(
9874            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9875        boolean alwaysFinishActivities = Settings.Global.getInt(
9876            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9877        boolean forceRtl = Settings.Global.getInt(
9878                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9879        // Transfer any global setting for forcing RTL layout, into a System Property
9880        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9881
9882        Configuration configuration = new Configuration();
9883        Settings.System.getConfiguration(resolver, configuration);
9884        if (forceRtl) {
9885            // This will take care of setting the correct layout direction flags
9886            configuration.setLayoutDirection(configuration.locale);
9887        }
9888
9889        synchronized (this) {
9890            mDebugApp = mOrigDebugApp = debugApp;
9891            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9892            mAlwaysFinishActivities = alwaysFinishActivities;
9893            // This happens before any activities are started, so we can
9894            // change mConfiguration in-place.
9895            updateConfigurationLocked(configuration, null, false, true);
9896            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9897        }
9898    }
9899
9900    public boolean testIsSystemReady() {
9901        // no need to synchronize(this) just to read & return the value
9902        return mSystemReady;
9903    }
9904
9905    private static File getCalledPreBootReceiversFile() {
9906        File dataDir = Environment.getDataDirectory();
9907        File systemDir = new File(dataDir, "system");
9908        File fname = new File(systemDir, "called_pre_boots.dat");
9909        return fname;
9910    }
9911
9912    static final int LAST_DONE_VERSION = 10000;
9913
9914    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9915        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9916        File file = getCalledPreBootReceiversFile();
9917        FileInputStream fis = null;
9918        try {
9919            fis = new FileInputStream(file);
9920            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9921            int fvers = dis.readInt();
9922            if (fvers == LAST_DONE_VERSION) {
9923                String vers = dis.readUTF();
9924                String codename = dis.readUTF();
9925                String build = dis.readUTF();
9926                if (android.os.Build.VERSION.RELEASE.equals(vers)
9927                        && android.os.Build.VERSION.CODENAME.equals(codename)
9928                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9929                    int num = dis.readInt();
9930                    while (num > 0) {
9931                        num--;
9932                        String pkg = dis.readUTF();
9933                        String cls = dis.readUTF();
9934                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9935                    }
9936                }
9937            }
9938        } catch (FileNotFoundException e) {
9939        } catch (IOException e) {
9940            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9941        } finally {
9942            if (fis != null) {
9943                try {
9944                    fis.close();
9945                } catch (IOException e) {
9946                }
9947            }
9948        }
9949        return lastDoneReceivers;
9950    }
9951
9952    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9953        File file = getCalledPreBootReceiversFile();
9954        FileOutputStream fos = null;
9955        DataOutputStream dos = null;
9956        try {
9957            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9958            fos = new FileOutputStream(file);
9959            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9960            dos.writeInt(LAST_DONE_VERSION);
9961            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9962            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9963            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9964            dos.writeInt(list.size());
9965            for (int i=0; i<list.size(); i++) {
9966                dos.writeUTF(list.get(i).getPackageName());
9967                dos.writeUTF(list.get(i).getClassName());
9968            }
9969        } catch (IOException e) {
9970            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9971            file.delete();
9972        } finally {
9973            FileUtils.sync(fos);
9974            if (dos != null) {
9975                try {
9976                    dos.close();
9977                } catch (IOException e) {
9978                    // TODO Auto-generated catch block
9979                    e.printStackTrace();
9980                }
9981            }
9982        }
9983    }
9984
9985    public void systemReady(final Runnable goingCallback) {
9986        synchronized(this) {
9987            if (mSystemReady) {
9988                if (goingCallback != null) goingCallback.run();
9989                return;
9990            }
9991
9992            // Make sure we have the current profile info, since it is needed for
9993            // security checks.
9994            updateCurrentProfileIdsLocked();
9995
9996            if (mRecentTasks == null) {
9997                mRecentTasks = mTaskPersister.restoreTasksLocked();
9998                if (!mRecentTasks.isEmpty()) {
9999                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10000                }
10001                mTaskPersister.startPersisting();
10002            }
10003
10004            // Check to see if there are any update receivers to run.
10005            if (!mDidUpdate) {
10006                if (mWaitingUpdate) {
10007                    return;
10008                }
10009                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10010                List<ResolveInfo> ris = null;
10011                try {
10012                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
10013                            intent, null, 0, 0);
10014                } catch (RemoteException e) {
10015                }
10016                if (ris != null) {
10017                    for (int i=ris.size()-1; i>=0; i--) {
10018                        if ((ris.get(i).activityInfo.applicationInfo.flags
10019                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
10020                            ris.remove(i);
10021                        }
10022                    }
10023                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10024
10025                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10026
10027                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10028                    for (int i=0; i<ris.size(); i++) {
10029                        ActivityInfo ai = ris.get(i).activityInfo;
10030                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
10031                        if (lastDoneReceivers.contains(comp)) {
10032                            // We already did the pre boot receiver for this app with the current
10033                            // platform version, so don't do it again...
10034                            ris.remove(i);
10035                            i--;
10036                            // ...however, do keep it as one that has been done, so we don't
10037                            // forget about it when rewriting the file of last done receivers.
10038                            doneReceivers.add(comp);
10039                        }
10040                    }
10041
10042                    final int[] users = getUsersLocked();
10043                    for (int i=0; i<ris.size(); i++) {
10044                        ActivityInfo ai = ris.get(i).activityInfo;
10045                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
10046                        doneReceivers.add(comp);
10047                        intent.setComponent(comp);
10048                        for (int j=0; j<users.length; j++) {
10049                            IIntentReceiver finisher = null;
10050                            if (i == ris.size()-1 && j == users.length-1) {
10051                                finisher = new IIntentReceiver.Stub() {
10052                                    public void performReceive(Intent intent, int resultCode,
10053                                            String data, Bundle extras, boolean ordered,
10054                                            boolean sticky, int sendingUser) {
10055                                        // The raw IIntentReceiver interface is called
10056                                        // with the AM lock held, so redispatch to
10057                                        // execute our code without the lock.
10058                                        mHandler.post(new Runnable() {
10059                                            public void run() {
10060                                                synchronized (ActivityManagerService.this) {
10061                                                    mDidUpdate = true;
10062                                                }
10063                                                writeLastDonePreBootReceivers(doneReceivers);
10064                                                showBootMessage(mContext.getText(
10065                                                        R.string.android_upgrading_complete),
10066                                                        false);
10067                                                systemReady(goingCallback);
10068                                            }
10069                                        });
10070                                    }
10071                                };
10072                            }
10073                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
10074                                    + " for user " + users[j]);
10075                            broadcastIntentLocked(null, null, intent, null, finisher,
10076                                    0, null, null, null, AppOpsManager.OP_NONE,
10077                                    true, false, MY_PID, Process.SYSTEM_UID,
10078                                    users[j]);
10079                            if (finisher != null) {
10080                                mWaitingUpdate = true;
10081                            }
10082                        }
10083                    }
10084                }
10085                if (mWaitingUpdate) {
10086                    return;
10087                }
10088                mDidUpdate = true;
10089            }
10090
10091            mAppOpsService.systemReady();
10092            mUsageStatsService.systemReady();
10093            mSystemReady = true;
10094        }
10095
10096        ArrayList<ProcessRecord> procsToKill = null;
10097        synchronized(mPidsSelfLocked) {
10098            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10099                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10100                if (!isAllowedWhileBooting(proc.info)){
10101                    if (procsToKill == null) {
10102                        procsToKill = new ArrayList<ProcessRecord>();
10103                    }
10104                    procsToKill.add(proc);
10105                }
10106            }
10107        }
10108
10109        synchronized(this) {
10110            if (procsToKill != null) {
10111                for (int i=procsToKill.size()-1; i>=0; i--) {
10112                    ProcessRecord proc = procsToKill.get(i);
10113                    Slog.i(TAG, "Removing system update proc: " + proc);
10114                    removeProcessLocked(proc, true, false, "system update done");
10115                }
10116            }
10117
10118            // Now that we have cleaned up any update processes, we
10119            // are ready to start launching real processes and know that
10120            // we won't trample on them any more.
10121            mProcessesReady = true;
10122        }
10123
10124        Slog.i(TAG, "System now ready");
10125        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10126            SystemClock.uptimeMillis());
10127
10128        synchronized(this) {
10129            // Make sure we have no pre-ready processes sitting around.
10130
10131            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10132                ResolveInfo ri = mContext.getPackageManager()
10133                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10134                                STOCK_PM_FLAGS);
10135                CharSequence errorMsg = null;
10136                if (ri != null) {
10137                    ActivityInfo ai = ri.activityInfo;
10138                    ApplicationInfo app = ai.applicationInfo;
10139                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10140                        mTopAction = Intent.ACTION_FACTORY_TEST;
10141                        mTopData = null;
10142                        mTopComponent = new ComponentName(app.packageName,
10143                                ai.name);
10144                    } else {
10145                        errorMsg = mContext.getResources().getText(
10146                                com.android.internal.R.string.factorytest_not_system);
10147                    }
10148                } else {
10149                    errorMsg = mContext.getResources().getText(
10150                            com.android.internal.R.string.factorytest_no_action);
10151                }
10152                if (errorMsg != null) {
10153                    mTopAction = null;
10154                    mTopData = null;
10155                    mTopComponent = null;
10156                    Message msg = Message.obtain();
10157                    msg.what = SHOW_FACTORY_ERROR_MSG;
10158                    msg.getData().putCharSequence("msg", errorMsg);
10159                    mHandler.sendMessage(msg);
10160                }
10161            }
10162        }
10163
10164        retrieveSettings();
10165
10166        synchronized (this) {
10167            readGrantedUriPermissionsLocked();
10168        }
10169
10170        if (goingCallback != null) goingCallback.run();
10171
10172        mSystemServiceManager.startUser(mCurrentUserId);
10173
10174        synchronized (this) {
10175            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10176                try {
10177                    List apps = AppGlobals.getPackageManager().
10178                        getPersistentApplications(STOCK_PM_FLAGS);
10179                    if (apps != null) {
10180                        int N = apps.size();
10181                        int i;
10182                        for (i=0; i<N; i++) {
10183                            ApplicationInfo info
10184                                = (ApplicationInfo)apps.get(i);
10185                            if (info != null &&
10186                                    !info.packageName.equals("android")) {
10187                                addAppLocked(info, false, null /* ABI override */);
10188                            }
10189                        }
10190                    }
10191                } catch (RemoteException ex) {
10192                    // pm is in same process, this will never happen.
10193                }
10194            }
10195
10196            // Start up initial activity.
10197            mBooting = true;
10198
10199            try {
10200                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10201                    Message msg = Message.obtain();
10202                    msg.what = SHOW_UID_ERROR_MSG;
10203                    mHandler.sendMessage(msg);
10204                }
10205            } catch (RemoteException e) {
10206            }
10207
10208            long ident = Binder.clearCallingIdentity();
10209            try {
10210                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10211                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10212                        | Intent.FLAG_RECEIVER_FOREGROUND);
10213                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10214                broadcastIntentLocked(null, null, intent,
10215                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10216                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10217                intent = new Intent(Intent.ACTION_USER_STARTING);
10218                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10219                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10220                broadcastIntentLocked(null, null, intent,
10221                        null, new IIntentReceiver.Stub() {
10222                            @Override
10223                            public void performReceive(Intent intent, int resultCode, String data,
10224                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10225                                    throws RemoteException {
10226                            }
10227                        }, 0, null, null,
10228                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10229                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10230            } catch (Throwable t) {
10231                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10232            } finally {
10233                Binder.restoreCallingIdentity(ident);
10234            }
10235            mStackSupervisor.resumeTopActivitiesLocked();
10236            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10237        }
10238    }
10239
10240    private boolean makeAppCrashingLocked(ProcessRecord app,
10241            String shortMsg, String longMsg, String stackTrace) {
10242        app.crashing = true;
10243        app.crashingReport = generateProcessError(app,
10244                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10245        startAppProblemLocked(app);
10246        app.stopFreezingAllLocked();
10247        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10248    }
10249
10250    private void makeAppNotRespondingLocked(ProcessRecord app,
10251            String activity, String shortMsg, String longMsg) {
10252        app.notResponding = true;
10253        app.notRespondingReport = generateProcessError(app,
10254                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10255                activity, shortMsg, longMsg, null);
10256        startAppProblemLocked(app);
10257        app.stopFreezingAllLocked();
10258    }
10259
10260    /**
10261     * Generate a process error record, suitable for attachment to a ProcessRecord.
10262     *
10263     * @param app The ProcessRecord in which the error occurred.
10264     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10265     *                      ActivityManager.AppErrorStateInfo
10266     * @param activity The activity associated with the crash, if known.
10267     * @param shortMsg Short message describing the crash.
10268     * @param longMsg Long message describing the crash.
10269     * @param stackTrace Full crash stack trace, may be null.
10270     *
10271     * @return Returns a fully-formed AppErrorStateInfo record.
10272     */
10273    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10274            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10275        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10276
10277        report.condition = condition;
10278        report.processName = app.processName;
10279        report.pid = app.pid;
10280        report.uid = app.info.uid;
10281        report.tag = activity;
10282        report.shortMsg = shortMsg;
10283        report.longMsg = longMsg;
10284        report.stackTrace = stackTrace;
10285
10286        return report;
10287    }
10288
10289    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10290        synchronized (this) {
10291            app.crashing = false;
10292            app.crashingReport = null;
10293            app.notResponding = false;
10294            app.notRespondingReport = null;
10295            if (app.anrDialog == fromDialog) {
10296                app.anrDialog = null;
10297            }
10298            if (app.waitDialog == fromDialog) {
10299                app.waitDialog = null;
10300            }
10301            if (app.pid > 0 && app.pid != MY_PID) {
10302                handleAppCrashLocked(app, null, null, null);
10303                killUnneededProcessLocked(app, "user request after error");
10304            }
10305        }
10306    }
10307
10308    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10309            String stackTrace) {
10310        long now = SystemClock.uptimeMillis();
10311
10312        Long crashTime;
10313        if (!app.isolated) {
10314            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10315        } else {
10316            crashTime = null;
10317        }
10318        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10319            // This process loses!
10320            Slog.w(TAG, "Process " + app.info.processName
10321                    + " has crashed too many times: killing!");
10322            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10323                    app.userId, app.info.processName, app.uid);
10324            mStackSupervisor.handleAppCrashLocked(app);
10325            if (!app.persistent) {
10326                // We don't want to start this process again until the user
10327                // explicitly does so...  but for persistent process, we really
10328                // need to keep it running.  If a persistent process is actually
10329                // repeatedly crashing, then badness for everyone.
10330                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10331                        app.info.processName);
10332                if (!app.isolated) {
10333                    // XXX We don't have a way to mark isolated processes
10334                    // as bad, since they don't have a peristent identity.
10335                    mBadProcesses.put(app.info.processName, app.uid,
10336                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10337                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10338                }
10339                app.bad = true;
10340                app.removed = true;
10341                // Don't let services in this process be restarted and potentially
10342                // annoy the user repeatedly.  Unless it is persistent, since those
10343                // processes run critical code.
10344                removeProcessLocked(app, false, false, "crash");
10345                mStackSupervisor.resumeTopActivitiesLocked();
10346                return false;
10347            }
10348            mStackSupervisor.resumeTopActivitiesLocked();
10349        } else {
10350            mStackSupervisor.finishTopRunningActivityLocked(app);
10351        }
10352
10353        // Bump up the crash count of any services currently running in the proc.
10354        for (int i=app.services.size()-1; i>=0; i--) {
10355            // Any services running in the application need to be placed
10356            // back in the pending list.
10357            ServiceRecord sr = app.services.valueAt(i);
10358            sr.crashCount++;
10359        }
10360
10361        // If the crashing process is what we consider to be the "home process" and it has been
10362        // replaced by a third-party app, clear the package preferred activities from packages
10363        // with a home activity running in the process to prevent a repeatedly crashing app
10364        // from blocking the user to manually clear the list.
10365        final ArrayList<ActivityRecord> activities = app.activities;
10366        if (app == mHomeProcess && activities.size() > 0
10367                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10368            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10369                final ActivityRecord r = activities.get(activityNdx);
10370                if (r.isHomeActivity()) {
10371                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10372                    try {
10373                        ActivityThread.getPackageManager()
10374                                .clearPackagePreferredActivities(r.packageName);
10375                    } catch (RemoteException c) {
10376                        // pm is in same process, this will never happen.
10377                    }
10378                }
10379            }
10380        }
10381
10382        if (!app.isolated) {
10383            // XXX Can't keep track of crash times for isolated processes,
10384            // because they don't have a perisistent identity.
10385            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10386        }
10387
10388        return true;
10389    }
10390
10391    void startAppProblemLocked(ProcessRecord app) {
10392        if (app.userId == mCurrentUserId) {
10393            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10394                    mContext, app.info.packageName, app.info.flags);
10395        } else {
10396            // If this app is not running under the current user, then we
10397            // can't give it a report button because that would require
10398            // launching the report UI under a different user.
10399            app.errorReportReceiver = null;
10400        }
10401        skipCurrentReceiverLocked(app);
10402    }
10403
10404    void skipCurrentReceiverLocked(ProcessRecord app) {
10405        for (BroadcastQueue queue : mBroadcastQueues) {
10406            queue.skipCurrentReceiverLocked(app);
10407        }
10408    }
10409
10410    /**
10411     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10412     * The application process will exit immediately after this call returns.
10413     * @param app object of the crashing app, null for the system server
10414     * @param crashInfo describing the exception
10415     */
10416    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10417        ProcessRecord r = findAppProcess(app, "Crash");
10418        final String processName = app == null ? "system_server"
10419                : (r == null ? "unknown" : r.processName);
10420
10421        handleApplicationCrashInner("crash", r, processName, crashInfo);
10422    }
10423
10424    /* Native crash reporting uses this inner version because it needs to be somewhat
10425     * decoupled from the AM-managed cleanup lifecycle
10426     */
10427    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10428            ApplicationErrorReport.CrashInfo crashInfo) {
10429        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10430                UserHandle.getUserId(Binder.getCallingUid()), processName,
10431                r == null ? -1 : r.info.flags,
10432                crashInfo.exceptionClassName,
10433                crashInfo.exceptionMessage,
10434                crashInfo.throwFileName,
10435                crashInfo.throwLineNumber);
10436
10437        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10438
10439        crashApplication(r, crashInfo);
10440    }
10441
10442    public void handleApplicationStrictModeViolation(
10443            IBinder app,
10444            int violationMask,
10445            StrictMode.ViolationInfo info) {
10446        ProcessRecord r = findAppProcess(app, "StrictMode");
10447        if (r == null) {
10448            return;
10449        }
10450
10451        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10452            Integer stackFingerprint = info.hashCode();
10453            boolean logIt = true;
10454            synchronized (mAlreadyLoggedViolatedStacks) {
10455                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10456                    logIt = false;
10457                    // TODO: sub-sample into EventLog for these, with
10458                    // the info.durationMillis?  Then we'd get
10459                    // the relative pain numbers, without logging all
10460                    // the stack traces repeatedly.  We'd want to do
10461                    // likewise in the client code, which also does
10462                    // dup suppression, before the Binder call.
10463                } else {
10464                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10465                        mAlreadyLoggedViolatedStacks.clear();
10466                    }
10467                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10468                }
10469            }
10470            if (logIt) {
10471                logStrictModeViolationToDropBox(r, info);
10472            }
10473        }
10474
10475        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10476            AppErrorResult result = new AppErrorResult();
10477            synchronized (this) {
10478                final long origId = Binder.clearCallingIdentity();
10479
10480                Message msg = Message.obtain();
10481                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10482                HashMap<String, Object> data = new HashMap<String, Object>();
10483                data.put("result", result);
10484                data.put("app", r);
10485                data.put("violationMask", violationMask);
10486                data.put("info", info);
10487                msg.obj = data;
10488                mHandler.sendMessage(msg);
10489
10490                Binder.restoreCallingIdentity(origId);
10491            }
10492            int res = result.get();
10493            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10494        }
10495    }
10496
10497    // Depending on the policy in effect, there could be a bunch of
10498    // these in quick succession so we try to batch these together to
10499    // minimize disk writes, number of dropbox entries, and maximize
10500    // compression, by having more fewer, larger records.
10501    private void logStrictModeViolationToDropBox(
10502            ProcessRecord process,
10503            StrictMode.ViolationInfo info) {
10504        if (info == null) {
10505            return;
10506        }
10507        final boolean isSystemApp = process == null ||
10508                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10509                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10510        final String processName = process == null ? "unknown" : process.processName;
10511        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10512        final DropBoxManager dbox = (DropBoxManager)
10513                mContext.getSystemService(Context.DROPBOX_SERVICE);
10514
10515        // Exit early if the dropbox isn't configured to accept this report type.
10516        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10517
10518        boolean bufferWasEmpty;
10519        boolean needsFlush;
10520        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10521        synchronized (sb) {
10522            bufferWasEmpty = sb.length() == 0;
10523            appendDropBoxProcessHeaders(process, processName, sb);
10524            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10525            sb.append("System-App: ").append(isSystemApp).append("\n");
10526            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10527            if (info.violationNumThisLoop != 0) {
10528                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10529            }
10530            if (info.numAnimationsRunning != 0) {
10531                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10532            }
10533            if (info.broadcastIntentAction != null) {
10534                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10535            }
10536            if (info.durationMillis != -1) {
10537                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10538            }
10539            if (info.numInstances != -1) {
10540                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10541            }
10542            if (info.tags != null) {
10543                for (String tag : info.tags) {
10544                    sb.append("Span-Tag: ").append(tag).append("\n");
10545                }
10546            }
10547            sb.append("\n");
10548            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10549                sb.append(info.crashInfo.stackTrace);
10550            }
10551            sb.append("\n");
10552
10553            // Only buffer up to ~64k.  Various logging bits truncate
10554            // things at 128k.
10555            needsFlush = (sb.length() > 64 * 1024);
10556        }
10557
10558        // Flush immediately if the buffer's grown too large, or this
10559        // is a non-system app.  Non-system apps are isolated with a
10560        // different tag & policy and not batched.
10561        //
10562        // Batching is useful during internal testing with
10563        // StrictMode settings turned up high.  Without batching,
10564        // thousands of separate files could be created on boot.
10565        if (!isSystemApp || needsFlush) {
10566            new Thread("Error dump: " + dropboxTag) {
10567                @Override
10568                public void run() {
10569                    String report;
10570                    synchronized (sb) {
10571                        report = sb.toString();
10572                        sb.delete(0, sb.length());
10573                        sb.trimToSize();
10574                    }
10575                    if (report.length() != 0) {
10576                        dbox.addText(dropboxTag, report);
10577                    }
10578                }
10579            }.start();
10580            return;
10581        }
10582
10583        // System app batching:
10584        if (!bufferWasEmpty) {
10585            // An existing dropbox-writing thread is outstanding, so
10586            // we don't need to start it up.  The existing thread will
10587            // catch the buffer appends we just did.
10588            return;
10589        }
10590
10591        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10592        // (After this point, we shouldn't access AMS internal data structures.)
10593        new Thread("Error dump: " + dropboxTag) {
10594            @Override
10595            public void run() {
10596                // 5 second sleep to let stacks arrive and be batched together
10597                try {
10598                    Thread.sleep(5000);  // 5 seconds
10599                } catch (InterruptedException e) {}
10600
10601                String errorReport;
10602                synchronized (mStrictModeBuffer) {
10603                    errorReport = mStrictModeBuffer.toString();
10604                    if (errorReport.length() == 0) {
10605                        return;
10606                    }
10607                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10608                    mStrictModeBuffer.trimToSize();
10609                }
10610                dbox.addText(dropboxTag, errorReport);
10611            }
10612        }.start();
10613    }
10614
10615    /**
10616     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10617     * @param app object of the crashing app, null for the system server
10618     * @param tag reported by the caller
10619     * @param crashInfo describing the context of the error
10620     * @return true if the process should exit immediately (WTF is fatal)
10621     */
10622    public boolean handleApplicationWtf(IBinder app, String tag,
10623            ApplicationErrorReport.CrashInfo crashInfo) {
10624        ProcessRecord r = findAppProcess(app, "WTF");
10625        final String processName = app == null ? "system_server"
10626                : (r == null ? "unknown" : r.processName);
10627
10628        EventLog.writeEvent(EventLogTags.AM_WTF,
10629                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10630                processName,
10631                r == null ? -1 : r.info.flags,
10632                tag, crashInfo.exceptionMessage);
10633
10634        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10635
10636        if (r != null && r.pid != Process.myPid() &&
10637                Settings.Global.getInt(mContext.getContentResolver(),
10638                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10639            crashApplication(r, crashInfo);
10640            return true;
10641        } else {
10642            return false;
10643        }
10644    }
10645
10646    /**
10647     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10648     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10649     */
10650    private ProcessRecord findAppProcess(IBinder app, String reason) {
10651        if (app == null) {
10652            return null;
10653        }
10654
10655        synchronized (this) {
10656            final int NP = mProcessNames.getMap().size();
10657            for (int ip=0; ip<NP; ip++) {
10658                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10659                final int NA = apps.size();
10660                for (int ia=0; ia<NA; ia++) {
10661                    ProcessRecord p = apps.valueAt(ia);
10662                    if (p.thread != null && p.thread.asBinder() == app) {
10663                        return p;
10664                    }
10665                }
10666            }
10667
10668            Slog.w(TAG, "Can't find mystery application for " + reason
10669                    + " from pid=" + Binder.getCallingPid()
10670                    + " uid=" + Binder.getCallingUid() + ": " + app);
10671            return null;
10672        }
10673    }
10674
10675    /**
10676     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10677     * to append various headers to the dropbox log text.
10678     */
10679    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10680            StringBuilder sb) {
10681        // Watchdog thread ends up invoking this function (with
10682        // a null ProcessRecord) to add the stack file to dropbox.
10683        // Do not acquire a lock on this (am) in such cases, as it
10684        // could cause a potential deadlock, if and when watchdog
10685        // is invoked due to unavailability of lock on am and it
10686        // would prevent watchdog from killing system_server.
10687        if (process == null) {
10688            sb.append("Process: ").append(processName).append("\n");
10689            return;
10690        }
10691        // Note: ProcessRecord 'process' is guarded by the service
10692        // instance.  (notably process.pkgList, which could otherwise change
10693        // concurrently during execution of this method)
10694        synchronized (this) {
10695            sb.append("Process: ").append(processName).append("\n");
10696            int flags = process.info.flags;
10697            IPackageManager pm = AppGlobals.getPackageManager();
10698            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10699            for (int ip=0; ip<process.pkgList.size(); ip++) {
10700                String pkg = process.pkgList.keyAt(ip);
10701                sb.append("Package: ").append(pkg);
10702                try {
10703                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10704                    if (pi != null) {
10705                        sb.append(" v").append(pi.versionCode);
10706                        if (pi.versionName != null) {
10707                            sb.append(" (").append(pi.versionName).append(")");
10708                        }
10709                    }
10710                } catch (RemoteException e) {
10711                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10712                }
10713                sb.append("\n");
10714            }
10715        }
10716    }
10717
10718    private static String processClass(ProcessRecord process) {
10719        if (process == null || process.pid == MY_PID) {
10720            return "system_server";
10721        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10722            return "system_app";
10723        } else {
10724            return "data_app";
10725        }
10726    }
10727
10728    /**
10729     * Write a description of an error (crash, WTF, ANR) to the drop box.
10730     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10731     * @param process which caused the error, null means the system server
10732     * @param activity which triggered the error, null if unknown
10733     * @param parent activity related to the error, null if unknown
10734     * @param subject line related to the error, null if absent
10735     * @param report in long form describing the error, null if absent
10736     * @param logFile to include in the report, null if none
10737     * @param crashInfo giving an application stack trace, null if absent
10738     */
10739    public void addErrorToDropBox(String eventType,
10740            ProcessRecord process, String processName, ActivityRecord activity,
10741            ActivityRecord parent, String subject,
10742            final String report, final File logFile,
10743            final ApplicationErrorReport.CrashInfo crashInfo) {
10744        // NOTE -- this must never acquire the ActivityManagerService lock,
10745        // otherwise the watchdog may be prevented from resetting the system.
10746
10747        final String dropboxTag = processClass(process) + "_" + eventType;
10748        final DropBoxManager dbox = (DropBoxManager)
10749                mContext.getSystemService(Context.DROPBOX_SERVICE);
10750
10751        // Exit early if the dropbox isn't configured to accept this report type.
10752        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10753
10754        final StringBuilder sb = new StringBuilder(1024);
10755        appendDropBoxProcessHeaders(process, processName, sb);
10756        if (activity != null) {
10757            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10758        }
10759        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10760            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10761        }
10762        if (parent != null && parent != activity) {
10763            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10764        }
10765        if (subject != null) {
10766            sb.append("Subject: ").append(subject).append("\n");
10767        }
10768        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10769        if (Debug.isDebuggerConnected()) {
10770            sb.append("Debugger: Connected\n");
10771        }
10772        sb.append("\n");
10773
10774        // Do the rest in a worker thread to avoid blocking the caller on I/O
10775        // (After this point, we shouldn't access AMS internal data structures.)
10776        Thread worker = new Thread("Error dump: " + dropboxTag) {
10777            @Override
10778            public void run() {
10779                if (report != null) {
10780                    sb.append(report);
10781                }
10782                if (logFile != null) {
10783                    try {
10784                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10785                                    "\n\n[[TRUNCATED]]"));
10786                    } catch (IOException e) {
10787                        Slog.e(TAG, "Error reading " + logFile, e);
10788                    }
10789                }
10790                if (crashInfo != null && crashInfo.stackTrace != null) {
10791                    sb.append(crashInfo.stackTrace);
10792                }
10793
10794                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10795                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10796                if (lines > 0) {
10797                    sb.append("\n");
10798
10799                    // Merge several logcat streams, and take the last N lines
10800                    InputStreamReader input = null;
10801                    try {
10802                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10803                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10804                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10805
10806                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10807                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10808                        input = new InputStreamReader(logcat.getInputStream());
10809
10810                        int num;
10811                        char[] buf = new char[8192];
10812                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10813                    } catch (IOException e) {
10814                        Slog.e(TAG, "Error running logcat", e);
10815                    } finally {
10816                        if (input != null) try { input.close(); } catch (IOException e) {}
10817                    }
10818                }
10819
10820                dbox.addText(dropboxTag, sb.toString());
10821            }
10822        };
10823
10824        if (process == null) {
10825            // If process is null, we are being called from some internal code
10826            // and may be about to die -- run this synchronously.
10827            worker.run();
10828        } else {
10829            worker.start();
10830        }
10831    }
10832
10833    /**
10834     * Bring up the "unexpected error" dialog box for a crashing app.
10835     * Deal with edge cases (intercepts from instrumented applications,
10836     * ActivityController, error intent receivers, that sort of thing).
10837     * @param r the application crashing
10838     * @param crashInfo describing the failure
10839     */
10840    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10841        long timeMillis = System.currentTimeMillis();
10842        String shortMsg = crashInfo.exceptionClassName;
10843        String longMsg = crashInfo.exceptionMessage;
10844        String stackTrace = crashInfo.stackTrace;
10845        if (shortMsg != null && longMsg != null) {
10846            longMsg = shortMsg + ": " + longMsg;
10847        } else if (shortMsg != null) {
10848            longMsg = shortMsg;
10849        }
10850
10851        AppErrorResult result = new AppErrorResult();
10852        synchronized (this) {
10853            if (mController != null) {
10854                try {
10855                    String name = r != null ? r.processName : null;
10856                    int pid = r != null ? r.pid : Binder.getCallingPid();
10857                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
10858                    if (!mController.appCrashed(name, pid,
10859                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10860                        Slog.w(TAG, "Force-killing crashed app " + name
10861                                + " at watcher's request");
10862                        Process.killProcess(pid);
10863                        if (r != null) {
10864                            Process.killProcessGroup(uid, pid);
10865                        }
10866                        return;
10867                    }
10868                } catch (RemoteException e) {
10869                    mController = null;
10870                    Watchdog.getInstance().setActivityController(null);
10871                }
10872            }
10873
10874            final long origId = Binder.clearCallingIdentity();
10875
10876            // If this process is running instrumentation, finish it.
10877            if (r != null && r.instrumentationClass != null) {
10878                Slog.w(TAG, "Error in app " + r.processName
10879                      + " running instrumentation " + r.instrumentationClass + ":");
10880                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10881                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10882                Bundle info = new Bundle();
10883                info.putString("shortMsg", shortMsg);
10884                info.putString("longMsg", longMsg);
10885                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10886                Binder.restoreCallingIdentity(origId);
10887                return;
10888            }
10889
10890            // If we can't identify the process or it's already exceeded its crash quota,
10891            // quit right away without showing a crash dialog.
10892            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10893                Binder.restoreCallingIdentity(origId);
10894                return;
10895            }
10896
10897            Message msg = Message.obtain();
10898            msg.what = SHOW_ERROR_MSG;
10899            HashMap data = new HashMap();
10900            data.put("result", result);
10901            data.put("app", r);
10902            msg.obj = data;
10903            mHandler.sendMessage(msg);
10904
10905            Binder.restoreCallingIdentity(origId);
10906        }
10907
10908        int res = result.get();
10909
10910        Intent appErrorIntent = null;
10911        synchronized (this) {
10912            if (r != null && !r.isolated) {
10913                // XXX Can't keep track of crash time for isolated processes,
10914                // since they don't have a persistent identity.
10915                mProcessCrashTimes.put(r.info.processName, r.uid,
10916                        SystemClock.uptimeMillis());
10917            }
10918            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10919                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10920            }
10921        }
10922
10923        if (appErrorIntent != null) {
10924            try {
10925                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10926            } catch (ActivityNotFoundException e) {
10927                Slog.w(TAG, "bug report receiver dissappeared", e);
10928            }
10929        }
10930    }
10931
10932    Intent createAppErrorIntentLocked(ProcessRecord r,
10933            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10934        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10935        if (report == null) {
10936            return null;
10937        }
10938        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10939        result.setComponent(r.errorReportReceiver);
10940        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10941        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10942        return result;
10943    }
10944
10945    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10946            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10947        if (r.errorReportReceiver == null) {
10948            return null;
10949        }
10950
10951        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10952            return null;
10953        }
10954
10955        ApplicationErrorReport report = new ApplicationErrorReport();
10956        report.packageName = r.info.packageName;
10957        report.installerPackageName = r.errorReportReceiver.getPackageName();
10958        report.processName = r.processName;
10959        report.time = timeMillis;
10960        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10961
10962        if (r.crashing || r.forceCrashReport) {
10963            report.type = ApplicationErrorReport.TYPE_CRASH;
10964            report.crashInfo = crashInfo;
10965        } else if (r.notResponding) {
10966            report.type = ApplicationErrorReport.TYPE_ANR;
10967            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10968
10969            report.anrInfo.activity = r.notRespondingReport.tag;
10970            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10971            report.anrInfo.info = r.notRespondingReport.longMsg;
10972        }
10973
10974        return report;
10975    }
10976
10977    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10978        enforceNotIsolatedCaller("getProcessesInErrorState");
10979        // assume our apps are happy - lazy create the list
10980        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10981
10982        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10983                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10984        int userId = UserHandle.getUserId(Binder.getCallingUid());
10985
10986        synchronized (this) {
10987
10988            // iterate across all processes
10989            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10990                ProcessRecord app = mLruProcesses.get(i);
10991                if (!allUsers && app.userId != userId) {
10992                    continue;
10993                }
10994                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10995                    // This one's in trouble, so we'll generate a report for it
10996                    // crashes are higher priority (in case there's a crash *and* an anr)
10997                    ActivityManager.ProcessErrorStateInfo report = null;
10998                    if (app.crashing) {
10999                        report = app.crashingReport;
11000                    } else if (app.notResponding) {
11001                        report = app.notRespondingReport;
11002                    }
11003
11004                    if (report != null) {
11005                        if (errList == null) {
11006                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11007                        }
11008                        errList.add(report);
11009                    } else {
11010                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11011                                " crashing = " + app.crashing +
11012                                " notResponding = " + app.notResponding);
11013                    }
11014                }
11015            }
11016        }
11017
11018        return errList;
11019    }
11020
11021    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
11022        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
11023            if (currApp != null) {
11024                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
11025            }
11026            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
11027        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
11028            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
11029        } else if (adj >= ProcessList.HOME_APP_ADJ) {
11030            if (currApp != null) {
11031                currApp.lru = 0;
11032            }
11033            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
11034        } else if (adj >= ProcessList.SERVICE_ADJ) {
11035            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
11036        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
11037            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
11038        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
11039            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
11040        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
11041            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
11042        } else {
11043            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
11044        }
11045    }
11046
11047    private void fillInProcMemInfo(ProcessRecord app,
11048            ActivityManager.RunningAppProcessInfo outInfo) {
11049        outInfo.pid = app.pid;
11050        outInfo.uid = app.info.uid;
11051        if (mHeavyWeightProcess == app) {
11052            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11053        }
11054        if (app.persistent) {
11055            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11056        }
11057        if (app.activities.size() > 0) {
11058            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11059        }
11060        outInfo.lastTrimLevel = app.trimMemoryLevel;
11061        int adj = app.curAdj;
11062        outInfo.importance = oomAdjToImportance(adj, outInfo);
11063        outInfo.importanceReasonCode = app.adjTypeCode;
11064        outInfo.processState = app.curProcState;
11065    }
11066
11067    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11068        enforceNotIsolatedCaller("getRunningAppProcesses");
11069        // Lazy instantiation of list
11070        List<ActivityManager.RunningAppProcessInfo> runList = null;
11071        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11072                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11073        int userId = UserHandle.getUserId(Binder.getCallingUid());
11074        synchronized (this) {
11075            // Iterate across all processes
11076            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11077                ProcessRecord app = mLruProcesses.get(i);
11078                if (!allUsers && app.userId != userId) {
11079                    continue;
11080                }
11081                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11082                    // Generate process state info for running application
11083                    ActivityManager.RunningAppProcessInfo currApp =
11084                        new ActivityManager.RunningAppProcessInfo(app.processName,
11085                                app.pid, app.getPackageList());
11086                    fillInProcMemInfo(app, currApp);
11087                    if (app.adjSource instanceof ProcessRecord) {
11088                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11089                        currApp.importanceReasonImportance = oomAdjToImportance(
11090                                app.adjSourceOom, null);
11091                    } else if (app.adjSource instanceof ActivityRecord) {
11092                        ActivityRecord r = (ActivityRecord)app.adjSource;
11093                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11094                    }
11095                    if (app.adjTarget instanceof ComponentName) {
11096                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11097                    }
11098                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11099                    //        + " lru=" + currApp.lru);
11100                    if (runList == null) {
11101                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11102                    }
11103                    runList.add(currApp);
11104                }
11105            }
11106        }
11107        return runList;
11108    }
11109
11110    public List<ApplicationInfo> getRunningExternalApplications() {
11111        enforceNotIsolatedCaller("getRunningExternalApplications");
11112        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11113        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11114        if (runningApps != null && runningApps.size() > 0) {
11115            Set<String> extList = new HashSet<String>();
11116            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11117                if (app.pkgList != null) {
11118                    for (String pkg : app.pkgList) {
11119                        extList.add(pkg);
11120                    }
11121                }
11122            }
11123            IPackageManager pm = AppGlobals.getPackageManager();
11124            for (String pkg : extList) {
11125                try {
11126                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11127                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11128                        retList.add(info);
11129                    }
11130                } catch (RemoteException e) {
11131                }
11132            }
11133        }
11134        return retList;
11135    }
11136
11137    @Override
11138    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11139        enforceNotIsolatedCaller("getMyMemoryState");
11140        synchronized (this) {
11141            ProcessRecord proc;
11142            synchronized (mPidsSelfLocked) {
11143                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11144            }
11145            fillInProcMemInfo(proc, outInfo);
11146        }
11147    }
11148
11149    @Override
11150    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11151        if (checkCallingPermission(android.Manifest.permission.DUMP)
11152                != PackageManager.PERMISSION_GRANTED) {
11153            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11154                    + Binder.getCallingPid()
11155                    + ", uid=" + Binder.getCallingUid()
11156                    + " without permission "
11157                    + android.Manifest.permission.DUMP);
11158            return;
11159        }
11160
11161        boolean dumpAll = false;
11162        boolean dumpClient = false;
11163        String dumpPackage = null;
11164
11165        int opti = 0;
11166        while (opti < args.length) {
11167            String opt = args[opti];
11168            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11169                break;
11170            }
11171            opti++;
11172            if ("-a".equals(opt)) {
11173                dumpAll = true;
11174            } else if ("-c".equals(opt)) {
11175                dumpClient = true;
11176            } else if ("-h".equals(opt)) {
11177                pw.println("Activity manager dump options:");
11178                pw.println("  [-a] [-c] [-h] [cmd] ...");
11179                pw.println("  cmd may be one of:");
11180                pw.println("    a[ctivities]: activity stack state");
11181                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11182                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11183                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11184                pw.println("    o[om]: out of memory management");
11185                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11186                pw.println("    provider [COMP_SPEC]: provider client-side state");
11187                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11188                pw.println("    service [COMP_SPEC]: service client-side state");
11189                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11190                pw.println("    all: dump all activities");
11191                pw.println("    top: dump the top activity");
11192                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11193                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11194                pw.println("    a partial substring in a component name, a");
11195                pw.println("    hex object identifier.");
11196                pw.println("  -a: include all available server state.");
11197                pw.println("  -c: include client state.");
11198                return;
11199            } else {
11200                pw.println("Unknown argument: " + opt + "; use -h for help");
11201            }
11202        }
11203
11204        long origId = Binder.clearCallingIdentity();
11205        boolean more = false;
11206        // Is the caller requesting to dump a particular piece of data?
11207        if (opti < args.length) {
11208            String cmd = args[opti];
11209            opti++;
11210            if ("activities".equals(cmd) || "a".equals(cmd)) {
11211                synchronized (this) {
11212                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11213                }
11214            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11215                String[] newArgs;
11216                String name;
11217                if (opti >= args.length) {
11218                    name = null;
11219                    newArgs = EMPTY_STRING_ARRAY;
11220                } else {
11221                    name = args[opti];
11222                    opti++;
11223                    newArgs = new String[args.length - opti];
11224                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11225                            args.length - opti);
11226                }
11227                synchronized (this) {
11228                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11229                }
11230            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11231                String[] newArgs;
11232                String name;
11233                if (opti >= args.length) {
11234                    name = null;
11235                    newArgs = EMPTY_STRING_ARRAY;
11236                } else {
11237                    name = args[opti];
11238                    opti++;
11239                    newArgs = new String[args.length - opti];
11240                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11241                            args.length - opti);
11242                }
11243                synchronized (this) {
11244                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11245                }
11246            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11247                String[] newArgs;
11248                String name;
11249                if (opti >= args.length) {
11250                    name = null;
11251                    newArgs = EMPTY_STRING_ARRAY;
11252                } else {
11253                    name = args[opti];
11254                    opti++;
11255                    newArgs = new String[args.length - opti];
11256                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11257                            args.length - opti);
11258                }
11259                synchronized (this) {
11260                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11261                }
11262            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11263                synchronized (this) {
11264                    dumpOomLocked(fd, pw, args, opti, true);
11265                }
11266            } else if ("provider".equals(cmd)) {
11267                String[] newArgs;
11268                String name;
11269                if (opti >= args.length) {
11270                    name = null;
11271                    newArgs = EMPTY_STRING_ARRAY;
11272                } else {
11273                    name = args[opti];
11274                    opti++;
11275                    newArgs = new String[args.length - opti];
11276                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11277                }
11278                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11279                    pw.println("No providers match: " + name);
11280                    pw.println("Use -h for help.");
11281                }
11282            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11283                synchronized (this) {
11284                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11285                }
11286            } else if ("service".equals(cmd)) {
11287                String[] newArgs;
11288                String name;
11289                if (opti >= args.length) {
11290                    name = null;
11291                    newArgs = EMPTY_STRING_ARRAY;
11292                } else {
11293                    name = args[opti];
11294                    opti++;
11295                    newArgs = new String[args.length - opti];
11296                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11297                            args.length - opti);
11298                }
11299                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11300                    pw.println("No services match: " + name);
11301                    pw.println("Use -h for help.");
11302                }
11303            } else if ("package".equals(cmd)) {
11304                String[] newArgs;
11305                if (opti >= args.length) {
11306                    pw.println("package: no package name specified");
11307                    pw.println("Use -h for help.");
11308                } else {
11309                    dumpPackage = args[opti];
11310                    opti++;
11311                    newArgs = new String[args.length - opti];
11312                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11313                            args.length - opti);
11314                    args = newArgs;
11315                    opti = 0;
11316                    more = true;
11317                }
11318            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11319                synchronized (this) {
11320                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11321                }
11322            } else {
11323                // Dumping a single activity?
11324                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11325                    pw.println("Bad activity command, or no activities match: " + cmd);
11326                    pw.println("Use -h for help.");
11327                }
11328            }
11329            if (!more) {
11330                Binder.restoreCallingIdentity(origId);
11331                return;
11332            }
11333        }
11334
11335        // No piece of data specified, dump everything.
11336        synchronized (this) {
11337            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11338            pw.println();
11339            if (dumpAll) {
11340                pw.println("-------------------------------------------------------------------------------");
11341            }
11342            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11343            pw.println();
11344            if (dumpAll) {
11345                pw.println("-------------------------------------------------------------------------------");
11346            }
11347            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11348            pw.println();
11349            if (dumpAll) {
11350                pw.println("-------------------------------------------------------------------------------");
11351            }
11352            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11353            pw.println();
11354            if (dumpAll) {
11355                pw.println("-------------------------------------------------------------------------------");
11356            }
11357            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11358            pw.println();
11359            if (dumpAll) {
11360                pw.println("-------------------------------------------------------------------------------");
11361            }
11362            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11363        }
11364        Binder.restoreCallingIdentity(origId);
11365    }
11366
11367    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11368            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11369        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11370
11371        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11372                dumpPackage);
11373        boolean needSep = printedAnything;
11374
11375        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11376                dumpPackage, needSep, "  mFocusedActivity: ");
11377        if (printed) {
11378            printedAnything = true;
11379            needSep = false;
11380        }
11381
11382        if (dumpPackage == null) {
11383            if (needSep) {
11384                pw.println();
11385            }
11386            needSep = true;
11387            printedAnything = true;
11388            mStackSupervisor.dump(pw, "  ");
11389        }
11390
11391        if (mRecentTasks.size() > 0) {
11392            boolean printedHeader = false;
11393
11394            final int N = mRecentTasks.size();
11395            for (int i=0; i<N; i++) {
11396                TaskRecord tr = mRecentTasks.get(i);
11397                if (dumpPackage != null) {
11398                    if (tr.realActivity == null ||
11399                            !dumpPackage.equals(tr.realActivity)) {
11400                        continue;
11401                    }
11402                }
11403                if (!printedHeader) {
11404                    if (needSep) {
11405                        pw.println();
11406                    }
11407                    pw.println("  Recent tasks:");
11408                    printedHeader = true;
11409                    printedAnything = true;
11410                }
11411                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11412                        pw.println(tr);
11413                if (dumpAll) {
11414                    mRecentTasks.get(i).dump(pw, "    ");
11415                }
11416            }
11417        }
11418
11419        if (!printedAnything) {
11420            pw.println("  (nothing)");
11421        }
11422    }
11423
11424    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11425            int opti, boolean dumpAll, String dumpPackage) {
11426        boolean needSep = false;
11427        boolean printedAnything = false;
11428        int numPers = 0;
11429
11430        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11431
11432        if (dumpAll) {
11433            final int NP = mProcessNames.getMap().size();
11434            for (int ip=0; ip<NP; ip++) {
11435                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11436                final int NA = procs.size();
11437                for (int ia=0; ia<NA; ia++) {
11438                    ProcessRecord r = procs.valueAt(ia);
11439                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11440                        continue;
11441                    }
11442                    if (!needSep) {
11443                        pw.println("  All known processes:");
11444                        needSep = true;
11445                        printedAnything = true;
11446                    }
11447                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11448                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11449                        pw.print(" "); pw.println(r);
11450                    r.dump(pw, "    ");
11451                    if (r.persistent) {
11452                        numPers++;
11453                    }
11454                }
11455            }
11456        }
11457
11458        if (mIsolatedProcesses.size() > 0) {
11459            boolean printed = false;
11460            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11461                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11462                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11463                    continue;
11464                }
11465                if (!printed) {
11466                    if (needSep) {
11467                        pw.println();
11468                    }
11469                    pw.println("  Isolated process list (sorted by uid):");
11470                    printedAnything = true;
11471                    printed = true;
11472                    needSep = true;
11473                }
11474                pw.println(String.format("%sIsolated #%2d: %s",
11475                        "    ", i, r.toString()));
11476            }
11477        }
11478
11479        if (mLruProcesses.size() > 0) {
11480            if (needSep) {
11481                pw.println();
11482            }
11483            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11484                    pw.print(" total, non-act at ");
11485                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11486                    pw.print(", non-svc at ");
11487                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11488                    pw.println("):");
11489            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11490            needSep = true;
11491            printedAnything = true;
11492        }
11493
11494        if (dumpAll || dumpPackage != null) {
11495            synchronized (mPidsSelfLocked) {
11496                boolean printed = false;
11497                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11498                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11499                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11500                        continue;
11501                    }
11502                    if (!printed) {
11503                        if (needSep) pw.println();
11504                        needSep = true;
11505                        pw.println("  PID mappings:");
11506                        printed = true;
11507                        printedAnything = true;
11508                    }
11509                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11510                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11511                }
11512            }
11513        }
11514
11515        if (mForegroundProcesses.size() > 0) {
11516            synchronized (mPidsSelfLocked) {
11517                boolean printed = false;
11518                for (int i=0; i<mForegroundProcesses.size(); i++) {
11519                    ProcessRecord r = mPidsSelfLocked.get(
11520                            mForegroundProcesses.valueAt(i).pid);
11521                    if (dumpPackage != null && (r == null
11522                            || !r.pkgList.containsKey(dumpPackage))) {
11523                        continue;
11524                    }
11525                    if (!printed) {
11526                        if (needSep) pw.println();
11527                        needSep = true;
11528                        pw.println("  Foreground Processes:");
11529                        printed = true;
11530                        printedAnything = true;
11531                    }
11532                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11533                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11534                }
11535            }
11536        }
11537
11538        if (mPersistentStartingProcesses.size() > 0) {
11539            if (needSep) pw.println();
11540            needSep = true;
11541            printedAnything = true;
11542            pw.println("  Persisent processes that are starting:");
11543            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11544                    "Starting Norm", "Restarting PERS", dumpPackage);
11545        }
11546
11547        if (mRemovedProcesses.size() > 0) {
11548            if (needSep) pw.println();
11549            needSep = true;
11550            printedAnything = true;
11551            pw.println("  Processes that are being removed:");
11552            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11553                    "Removed Norm", "Removed PERS", dumpPackage);
11554        }
11555
11556        if (mProcessesOnHold.size() > 0) {
11557            if (needSep) pw.println();
11558            needSep = true;
11559            printedAnything = true;
11560            pw.println("  Processes that are on old until the system is ready:");
11561            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11562                    "OnHold Norm", "OnHold PERS", dumpPackage);
11563        }
11564
11565        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11566
11567        if (mProcessCrashTimes.getMap().size() > 0) {
11568            boolean printed = false;
11569            long now = SystemClock.uptimeMillis();
11570            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11571            final int NP = pmap.size();
11572            for (int ip=0; ip<NP; ip++) {
11573                String pname = pmap.keyAt(ip);
11574                SparseArray<Long> uids = pmap.valueAt(ip);
11575                final int N = uids.size();
11576                for (int i=0; i<N; i++) {
11577                    int puid = uids.keyAt(i);
11578                    ProcessRecord r = mProcessNames.get(pname, puid);
11579                    if (dumpPackage != null && (r == null
11580                            || !r.pkgList.containsKey(dumpPackage))) {
11581                        continue;
11582                    }
11583                    if (!printed) {
11584                        if (needSep) pw.println();
11585                        needSep = true;
11586                        pw.println("  Time since processes crashed:");
11587                        printed = true;
11588                        printedAnything = true;
11589                    }
11590                    pw.print("    Process "); pw.print(pname);
11591                            pw.print(" uid "); pw.print(puid);
11592                            pw.print(": last crashed ");
11593                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11594                            pw.println(" ago");
11595                }
11596            }
11597        }
11598
11599        if (mBadProcesses.getMap().size() > 0) {
11600            boolean printed = false;
11601            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11602            final int NP = pmap.size();
11603            for (int ip=0; ip<NP; ip++) {
11604                String pname = pmap.keyAt(ip);
11605                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11606                final int N = uids.size();
11607                for (int i=0; i<N; i++) {
11608                    int puid = uids.keyAt(i);
11609                    ProcessRecord r = mProcessNames.get(pname, puid);
11610                    if (dumpPackage != null && (r == null
11611                            || !r.pkgList.containsKey(dumpPackage))) {
11612                        continue;
11613                    }
11614                    if (!printed) {
11615                        if (needSep) pw.println();
11616                        needSep = true;
11617                        pw.println("  Bad processes:");
11618                        printedAnything = true;
11619                    }
11620                    BadProcessInfo info = uids.valueAt(i);
11621                    pw.print("    Bad process "); pw.print(pname);
11622                            pw.print(" uid "); pw.print(puid);
11623                            pw.print(": crashed at time "); pw.println(info.time);
11624                    if (info.shortMsg != null) {
11625                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11626                    }
11627                    if (info.longMsg != null) {
11628                        pw.print("      Long msg: "); pw.println(info.longMsg);
11629                    }
11630                    if (info.stack != null) {
11631                        pw.println("      Stack:");
11632                        int lastPos = 0;
11633                        for (int pos=0; pos<info.stack.length(); pos++) {
11634                            if (info.stack.charAt(pos) == '\n') {
11635                                pw.print("        ");
11636                                pw.write(info.stack, lastPos, pos-lastPos);
11637                                pw.println();
11638                                lastPos = pos+1;
11639                            }
11640                        }
11641                        if (lastPos < info.stack.length()) {
11642                            pw.print("        ");
11643                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11644                            pw.println();
11645                        }
11646                    }
11647                }
11648            }
11649        }
11650
11651        if (dumpPackage == null) {
11652            pw.println();
11653            needSep = false;
11654            pw.println("  mStartedUsers:");
11655            for (int i=0; i<mStartedUsers.size(); i++) {
11656                UserStartedState uss = mStartedUsers.valueAt(i);
11657                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11658                        pw.print(": "); uss.dump("", pw);
11659            }
11660            pw.print("  mStartedUserArray: [");
11661            for (int i=0; i<mStartedUserArray.length; i++) {
11662                if (i > 0) pw.print(", ");
11663                pw.print(mStartedUserArray[i]);
11664            }
11665            pw.println("]");
11666            pw.print("  mUserLru: [");
11667            for (int i=0; i<mUserLru.size(); i++) {
11668                if (i > 0) pw.print(", ");
11669                pw.print(mUserLru.get(i));
11670            }
11671            pw.println("]");
11672            if (dumpAll) {
11673                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11674            }
11675            synchronized (mUserProfileGroupIdsSelfLocked) {
11676                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
11677                    pw.println("  mUserProfileGroupIds:");
11678                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
11679                        pw.print("    User #");
11680                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
11681                        pw.print(" -> profile #");
11682                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
11683                    }
11684                }
11685            }
11686        }
11687        if (mHomeProcess != null && (dumpPackage == null
11688                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11689            if (needSep) {
11690                pw.println();
11691                needSep = false;
11692            }
11693            pw.println("  mHomeProcess: " + mHomeProcess);
11694        }
11695        if (mPreviousProcess != null && (dumpPackage == null
11696                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11697            if (needSep) {
11698                pw.println();
11699                needSep = false;
11700            }
11701            pw.println("  mPreviousProcess: " + mPreviousProcess);
11702        }
11703        if (dumpAll) {
11704            StringBuilder sb = new StringBuilder(128);
11705            sb.append("  mPreviousProcessVisibleTime: ");
11706            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11707            pw.println(sb);
11708        }
11709        if (mHeavyWeightProcess != null && (dumpPackage == null
11710                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11711            if (needSep) {
11712                pw.println();
11713                needSep = false;
11714            }
11715            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11716        }
11717        if (dumpPackage == null) {
11718            pw.println("  mConfiguration: " + mConfiguration);
11719        }
11720        if (dumpAll) {
11721            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11722            if (mCompatModePackages.getPackages().size() > 0) {
11723                boolean printed = false;
11724                for (Map.Entry<String, Integer> entry
11725                        : mCompatModePackages.getPackages().entrySet()) {
11726                    String pkg = entry.getKey();
11727                    int mode = entry.getValue();
11728                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11729                        continue;
11730                    }
11731                    if (!printed) {
11732                        pw.println("  mScreenCompatPackages:");
11733                        printed = true;
11734                    }
11735                    pw.print("    "); pw.print(pkg); pw.print(": ");
11736                            pw.print(mode); pw.println();
11737                }
11738            }
11739        }
11740        if (dumpPackage == null) {
11741            if (mSleeping || mWentToSleep || mLockScreenShown) {
11742                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11743                        + " mLockScreenShown " + mLockScreenShown);
11744            }
11745            if (mShuttingDown || mRunningVoice) {
11746                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11747            }
11748        }
11749        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11750                || mOrigWaitForDebugger) {
11751            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11752                    || dumpPackage.equals(mOrigDebugApp)) {
11753                if (needSep) {
11754                    pw.println();
11755                    needSep = false;
11756                }
11757                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11758                        + " mDebugTransient=" + mDebugTransient
11759                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11760            }
11761        }
11762        if (mOpenGlTraceApp != null) {
11763            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11764                if (needSep) {
11765                    pw.println();
11766                    needSep = false;
11767                }
11768                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11769            }
11770        }
11771        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11772                || mProfileFd != null) {
11773            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11774                if (needSep) {
11775                    pw.println();
11776                    needSep = false;
11777                }
11778                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11779                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11780                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11781                        + mAutoStopProfiler);
11782            }
11783        }
11784        if (dumpPackage == null) {
11785            if (mAlwaysFinishActivities || mController != null) {
11786                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11787                        + " mController=" + mController);
11788            }
11789            if (dumpAll) {
11790                pw.println("  Total persistent processes: " + numPers);
11791                pw.println("  mProcessesReady=" + mProcessesReady
11792                        + " mSystemReady=" + mSystemReady);
11793                pw.println("  mBooting=" + mBooting
11794                        + " mBooted=" + mBooted
11795                        + " mFactoryTest=" + mFactoryTest);
11796                pw.print("  mLastPowerCheckRealtime=");
11797                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11798                        pw.println("");
11799                pw.print("  mLastPowerCheckUptime=");
11800                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11801                        pw.println("");
11802                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11803                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11804                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11805                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11806                        + " (" + mLruProcesses.size() + " total)"
11807                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11808                        + " mNumServiceProcs=" + mNumServiceProcs
11809                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11810                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11811                        + " mLastMemoryLevel" + mLastMemoryLevel
11812                        + " mLastNumProcesses" + mLastNumProcesses);
11813                long now = SystemClock.uptimeMillis();
11814                pw.print("  mLastIdleTime=");
11815                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11816                        pw.print(" mLowRamSinceLastIdle=");
11817                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11818                        pw.println();
11819            }
11820        }
11821
11822        if (!printedAnything) {
11823            pw.println("  (nothing)");
11824        }
11825    }
11826
11827    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11828            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11829        if (mProcessesToGc.size() > 0) {
11830            boolean printed = false;
11831            long now = SystemClock.uptimeMillis();
11832            for (int i=0; i<mProcessesToGc.size(); i++) {
11833                ProcessRecord proc = mProcessesToGc.get(i);
11834                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11835                    continue;
11836                }
11837                if (!printed) {
11838                    if (needSep) pw.println();
11839                    needSep = true;
11840                    pw.println("  Processes that are waiting to GC:");
11841                    printed = true;
11842                }
11843                pw.print("    Process "); pw.println(proc);
11844                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11845                        pw.print(", last gced=");
11846                        pw.print(now-proc.lastRequestedGc);
11847                        pw.print(" ms ago, last lowMem=");
11848                        pw.print(now-proc.lastLowMemory);
11849                        pw.println(" ms ago");
11850
11851            }
11852        }
11853        return needSep;
11854    }
11855
11856    void printOomLevel(PrintWriter pw, String name, int adj) {
11857        pw.print("    ");
11858        if (adj >= 0) {
11859            pw.print(' ');
11860            if (adj < 10) pw.print(' ');
11861        } else {
11862            if (adj > -10) pw.print(' ');
11863        }
11864        pw.print(adj);
11865        pw.print(": ");
11866        pw.print(name);
11867        pw.print(" (");
11868        pw.print(mProcessList.getMemLevel(adj)/1024);
11869        pw.println(" kB)");
11870    }
11871
11872    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11873            int opti, boolean dumpAll) {
11874        boolean needSep = false;
11875
11876        if (mLruProcesses.size() > 0) {
11877            if (needSep) pw.println();
11878            needSep = true;
11879            pw.println("  OOM levels:");
11880            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11881            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11882            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11883            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11884            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11885            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11886            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11887            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11888            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11889            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11890            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11891            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11892            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11893
11894            if (needSep) pw.println();
11895            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11896                    pw.print(" total, non-act at ");
11897                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11898                    pw.print(", non-svc at ");
11899                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11900                    pw.println("):");
11901            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11902            needSep = true;
11903        }
11904
11905        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11906
11907        pw.println();
11908        pw.println("  mHomeProcess: " + mHomeProcess);
11909        pw.println("  mPreviousProcess: " + mPreviousProcess);
11910        if (mHeavyWeightProcess != null) {
11911            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11912        }
11913
11914        return true;
11915    }
11916
11917    /**
11918     * There are three ways to call this:
11919     *  - no provider specified: dump all the providers
11920     *  - a flattened component name that matched an existing provider was specified as the
11921     *    first arg: dump that one provider
11922     *  - the first arg isn't the flattened component name of an existing provider:
11923     *    dump all providers whose component contains the first arg as a substring
11924     */
11925    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11926            int opti, boolean dumpAll) {
11927        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11928    }
11929
11930    static class ItemMatcher {
11931        ArrayList<ComponentName> components;
11932        ArrayList<String> strings;
11933        ArrayList<Integer> objects;
11934        boolean all;
11935
11936        ItemMatcher() {
11937            all = true;
11938        }
11939
11940        void build(String name) {
11941            ComponentName componentName = ComponentName.unflattenFromString(name);
11942            if (componentName != null) {
11943                if (components == null) {
11944                    components = new ArrayList<ComponentName>();
11945                }
11946                components.add(componentName);
11947                all = false;
11948            } else {
11949                int objectId = 0;
11950                // Not a '/' separated full component name; maybe an object ID?
11951                try {
11952                    objectId = Integer.parseInt(name, 16);
11953                    if (objects == null) {
11954                        objects = new ArrayList<Integer>();
11955                    }
11956                    objects.add(objectId);
11957                    all = false;
11958                } catch (RuntimeException e) {
11959                    // Not an integer; just do string match.
11960                    if (strings == null) {
11961                        strings = new ArrayList<String>();
11962                    }
11963                    strings.add(name);
11964                    all = false;
11965                }
11966            }
11967        }
11968
11969        int build(String[] args, int opti) {
11970            for (; opti<args.length; opti++) {
11971                String name = args[opti];
11972                if ("--".equals(name)) {
11973                    return opti+1;
11974                }
11975                build(name);
11976            }
11977            return opti;
11978        }
11979
11980        boolean match(Object object, ComponentName comp) {
11981            if (all) {
11982                return true;
11983            }
11984            if (components != null) {
11985                for (int i=0; i<components.size(); i++) {
11986                    if (components.get(i).equals(comp)) {
11987                        return true;
11988                    }
11989                }
11990            }
11991            if (objects != null) {
11992                for (int i=0; i<objects.size(); i++) {
11993                    if (System.identityHashCode(object) == objects.get(i)) {
11994                        return true;
11995                    }
11996                }
11997            }
11998            if (strings != null) {
11999                String flat = comp.flattenToString();
12000                for (int i=0; i<strings.size(); i++) {
12001                    if (flat.contains(strings.get(i))) {
12002                        return true;
12003                    }
12004                }
12005            }
12006            return false;
12007        }
12008    }
12009
12010    /**
12011     * There are three things that cmd can be:
12012     *  - a flattened component name that matches an existing activity
12013     *  - the cmd arg isn't the flattened component name of an existing activity:
12014     *    dump all activity whose component contains the cmd as a substring
12015     *  - A hex number of the ActivityRecord object instance.
12016     */
12017    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12018            int opti, boolean dumpAll) {
12019        ArrayList<ActivityRecord> activities;
12020
12021        synchronized (this) {
12022            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12023        }
12024
12025        if (activities.size() <= 0) {
12026            return false;
12027        }
12028
12029        String[] newArgs = new String[args.length - opti];
12030        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12031
12032        TaskRecord lastTask = null;
12033        boolean needSep = false;
12034        for (int i=activities.size()-1; i>=0; i--) {
12035            ActivityRecord r = activities.get(i);
12036            if (needSep) {
12037                pw.println();
12038            }
12039            needSep = true;
12040            synchronized (this) {
12041                if (lastTask != r.task) {
12042                    lastTask = r.task;
12043                    pw.print("TASK "); pw.print(lastTask.affinity);
12044                            pw.print(" id="); pw.println(lastTask.taskId);
12045                    if (dumpAll) {
12046                        lastTask.dump(pw, "  ");
12047                    }
12048                }
12049            }
12050            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12051        }
12052        return true;
12053    }
12054
12055    /**
12056     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12057     * there is a thread associated with the activity.
12058     */
12059    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12060            final ActivityRecord r, String[] args, boolean dumpAll) {
12061        String innerPrefix = prefix + "  ";
12062        synchronized (this) {
12063            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12064                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12065                    pw.print(" pid=");
12066                    if (r.app != null) pw.println(r.app.pid);
12067                    else pw.println("(not running)");
12068            if (dumpAll) {
12069                r.dump(pw, innerPrefix);
12070            }
12071        }
12072        if (r.app != null && r.app.thread != null) {
12073            // flush anything that is already in the PrintWriter since the thread is going
12074            // to write to the file descriptor directly
12075            pw.flush();
12076            try {
12077                TransferPipe tp = new TransferPipe();
12078                try {
12079                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12080                            r.appToken, innerPrefix, args);
12081                    tp.go(fd);
12082                } finally {
12083                    tp.kill();
12084                }
12085            } catch (IOException e) {
12086                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12087            } catch (RemoteException e) {
12088                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12089            }
12090        }
12091    }
12092
12093    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12094            int opti, boolean dumpAll, String dumpPackage) {
12095        boolean needSep = false;
12096        boolean onlyHistory = false;
12097        boolean printedAnything = false;
12098
12099        if ("history".equals(dumpPackage)) {
12100            if (opti < args.length && "-s".equals(args[opti])) {
12101                dumpAll = false;
12102            }
12103            onlyHistory = true;
12104            dumpPackage = null;
12105        }
12106
12107        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12108        if (!onlyHistory && dumpAll) {
12109            if (mRegisteredReceivers.size() > 0) {
12110                boolean printed = false;
12111                Iterator it = mRegisteredReceivers.values().iterator();
12112                while (it.hasNext()) {
12113                    ReceiverList r = (ReceiverList)it.next();
12114                    if (dumpPackage != null && (r.app == null ||
12115                            !dumpPackage.equals(r.app.info.packageName))) {
12116                        continue;
12117                    }
12118                    if (!printed) {
12119                        pw.println("  Registered Receivers:");
12120                        needSep = true;
12121                        printed = true;
12122                        printedAnything = true;
12123                    }
12124                    pw.print("  * "); pw.println(r);
12125                    r.dump(pw, "    ");
12126                }
12127            }
12128
12129            if (mReceiverResolver.dump(pw, needSep ?
12130                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12131                    "    ", dumpPackage, false)) {
12132                needSep = true;
12133                printedAnything = true;
12134            }
12135        }
12136
12137        for (BroadcastQueue q : mBroadcastQueues) {
12138            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12139            printedAnything |= needSep;
12140        }
12141
12142        needSep = true;
12143
12144        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12145            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12146                if (needSep) {
12147                    pw.println();
12148                }
12149                needSep = true;
12150                printedAnything = true;
12151                pw.print("  Sticky broadcasts for user ");
12152                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12153                StringBuilder sb = new StringBuilder(128);
12154                for (Map.Entry<String, ArrayList<Intent>> ent
12155                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12156                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12157                    if (dumpAll) {
12158                        pw.println(":");
12159                        ArrayList<Intent> intents = ent.getValue();
12160                        final int N = intents.size();
12161                        for (int i=0; i<N; i++) {
12162                            sb.setLength(0);
12163                            sb.append("    Intent: ");
12164                            intents.get(i).toShortString(sb, false, true, false, false);
12165                            pw.println(sb.toString());
12166                            Bundle bundle = intents.get(i).getExtras();
12167                            if (bundle != null) {
12168                                pw.print("      ");
12169                                pw.println(bundle.toString());
12170                            }
12171                        }
12172                    } else {
12173                        pw.println("");
12174                    }
12175                }
12176            }
12177        }
12178
12179        if (!onlyHistory && dumpAll) {
12180            pw.println();
12181            for (BroadcastQueue queue : mBroadcastQueues) {
12182                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12183                        + queue.mBroadcastsScheduled);
12184            }
12185            pw.println("  mHandler:");
12186            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12187            needSep = true;
12188            printedAnything = true;
12189        }
12190
12191        if (!printedAnything) {
12192            pw.println("  (nothing)");
12193        }
12194    }
12195
12196    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12197            int opti, boolean dumpAll, String dumpPackage) {
12198        boolean needSep;
12199        boolean printedAnything = false;
12200
12201        ItemMatcher matcher = new ItemMatcher();
12202        matcher.build(args, opti);
12203
12204        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12205
12206        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12207        printedAnything |= needSep;
12208
12209        if (mLaunchingProviders.size() > 0) {
12210            boolean printed = false;
12211            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12212                ContentProviderRecord r = mLaunchingProviders.get(i);
12213                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12214                    continue;
12215                }
12216                if (!printed) {
12217                    if (needSep) pw.println();
12218                    needSep = true;
12219                    pw.println("  Launching content providers:");
12220                    printed = true;
12221                    printedAnything = true;
12222                }
12223                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12224                        pw.println(r);
12225            }
12226        }
12227
12228        if (mGrantedUriPermissions.size() > 0) {
12229            boolean printed = false;
12230            int dumpUid = -2;
12231            if (dumpPackage != null) {
12232                try {
12233                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12234                } catch (NameNotFoundException e) {
12235                    dumpUid = -1;
12236                }
12237            }
12238            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12239                int uid = mGrantedUriPermissions.keyAt(i);
12240                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12241                    continue;
12242                }
12243                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12244                if (!printed) {
12245                    if (needSep) pw.println();
12246                    needSep = true;
12247                    pw.println("  Granted Uri Permissions:");
12248                    printed = true;
12249                    printedAnything = true;
12250                }
12251                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12252                for (UriPermission perm : perms.values()) {
12253                    pw.print("    "); pw.println(perm);
12254                    if (dumpAll) {
12255                        perm.dump(pw, "      ");
12256                    }
12257                }
12258            }
12259        }
12260
12261        if (!printedAnything) {
12262            pw.println("  (nothing)");
12263        }
12264    }
12265
12266    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12267            int opti, boolean dumpAll, String dumpPackage) {
12268        boolean printed = false;
12269
12270        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12271
12272        if (mIntentSenderRecords.size() > 0) {
12273            Iterator<WeakReference<PendingIntentRecord>> it
12274                    = mIntentSenderRecords.values().iterator();
12275            while (it.hasNext()) {
12276                WeakReference<PendingIntentRecord> ref = it.next();
12277                PendingIntentRecord rec = ref != null ? ref.get(): null;
12278                if (dumpPackage != null && (rec == null
12279                        || !dumpPackage.equals(rec.key.packageName))) {
12280                    continue;
12281                }
12282                printed = true;
12283                if (rec != null) {
12284                    pw.print("  * "); pw.println(rec);
12285                    if (dumpAll) {
12286                        rec.dump(pw, "    ");
12287                    }
12288                } else {
12289                    pw.print("  * "); pw.println(ref);
12290                }
12291            }
12292        }
12293
12294        if (!printed) {
12295            pw.println("  (nothing)");
12296        }
12297    }
12298
12299    private static final int dumpProcessList(PrintWriter pw,
12300            ActivityManagerService service, List list,
12301            String prefix, String normalLabel, String persistentLabel,
12302            String dumpPackage) {
12303        int numPers = 0;
12304        final int N = list.size()-1;
12305        for (int i=N; i>=0; i--) {
12306            ProcessRecord r = (ProcessRecord)list.get(i);
12307            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12308                continue;
12309            }
12310            pw.println(String.format("%s%s #%2d: %s",
12311                    prefix, (r.persistent ? persistentLabel : normalLabel),
12312                    i, r.toString()));
12313            if (r.persistent) {
12314                numPers++;
12315            }
12316        }
12317        return numPers;
12318    }
12319
12320    private static final boolean dumpProcessOomList(PrintWriter pw,
12321            ActivityManagerService service, List<ProcessRecord> origList,
12322            String prefix, String normalLabel, String persistentLabel,
12323            boolean inclDetails, String dumpPackage) {
12324
12325        ArrayList<Pair<ProcessRecord, Integer>> list
12326                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12327        for (int i=0; i<origList.size(); i++) {
12328            ProcessRecord r = origList.get(i);
12329            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12330                continue;
12331            }
12332            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12333        }
12334
12335        if (list.size() <= 0) {
12336            return false;
12337        }
12338
12339        Comparator<Pair<ProcessRecord, Integer>> comparator
12340                = new Comparator<Pair<ProcessRecord, Integer>>() {
12341            @Override
12342            public int compare(Pair<ProcessRecord, Integer> object1,
12343                    Pair<ProcessRecord, Integer> object2) {
12344                if (object1.first.setAdj != object2.first.setAdj) {
12345                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12346                }
12347                if (object1.second.intValue() != object2.second.intValue()) {
12348                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12349                }
12350                return 0;
12351            }
12352        };
12353
12354        Collections.sort(list, comparator);
12355
12356        final long curRealtime = SystemClock.elapsedRealtime();
12357        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12358        final long curUptime = SystemClock.uptimeMillis();
12359        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12360
12361        for (int i=list.size()-1; i>=0; i--) {
12362            ProcessRecord r = list.get(i).first;
12363            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12364            char schedGroup;
12365            switch (r.setSchedGroup) {
12366                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12367                    schedGroup = 'B';
12368                    break;
12369                case Process.THREAD_GROUP_DEFAULT:
12370                    schedGroup = 'F';
12371                    break;
12372                default:
12373                    schedGroup = '?';
12374                    break;
12375            }
12376            char foreground;
12377            if (r.foregroundActivities) {
12378                foreground = 'A';
12379            } else if (r.foregroundServices) {
12380                foreground = 'S';
12381            } else {
12382                foreground = ' ';
12383            }
12384            String procState = ProcessList.makeProcStateString(r.curProcState);
12385            pw.print(prefix);
12386            pw.print(r.persistent ? persistentLabel : normalLabel);
12387            pw.print(" #");
12388            int num = (origList.size()-1)-list.get(i).second;
12389            if (num < 10) pw.print(' ');
12390            pw.print(num);
12391            pw.print(": ");
12392            pw.print(oomAdj);
12393            pw.print(' ');
12394            pw.print(schedGroup);
12395            pw.print('/');
12396            pw.print(foreground);
12397            pw.print('/');
12398            pw.print(procState);
12399            pw.print(" trm:");
12400            if (r.trimMemoryLevel < 10) pw.print(' ');
12401            pw.print(r.trimMemoryLevel);
12402            pw.print(' ');
12403            pw.print(r.toShortString());
12404            pw.print(" (");
12405            pw.print(r.adjType);
12406            pw.println(')');
12407            if (r.adjSource != null || r.adjTarget != null) {
12408                pw.print(prefix);
12409                pw.print("    ");
12410                if (r.adjTarget instanceof ComponentName) {
12411                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12412                } else if (r.adjTarget != null) {
12413                    pw.print(r.adjTarget.toString());
12414                } else {
12415                    pw.print("{null}");
12416                }
12417                pw.print("<=");
12418                if (r.adjSource instanceof ProcessRecord) {
12419                    pw.print("Proc{");
12420                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12421                    pw.println("}");
12422                } else if (r.adjSource != null) {
12423                    pw.println(r.adjSource.toString());
12424                } else {
12425                    pw.println("{null}");
12426                }
12427            }
12428            if (inclDetails) {
12429                pw.print(prefix);
12430                pw.print("    ");
12431                pw.print("oom: max="); pw.print(r.maxAdj);
12432                pw.print(" curRaw="); pw.print(r.curRawAdj);
12433                pw.print(" setRaw="); pw.print(r.setRawAdj);
12434                pw.print(" cur="); pw.print(r.curAdj);
12435                pw.print(" set="); pw.println(r.setAdj);
12436                pw.print(prefix);
12437                pw.print("    ");
12438                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12439                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12440                pw.print(" lastPss="); pw.print(r.lastPss);
12441                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12442                pw.print(prefix);
12443                pw.print("    ");
12444                pw.print("keeping="); pw.print(r.keeping);
12445                pw.print(" cached="); pw.print(r.cached);
12446                pw.print(" empty="); pw.print(r.empty);
12447                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12448
12449                if (!r.keeping) {
12450                    if (r.lastWakeTime != 0) {
12451                        long wtime;
12452                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12453                        synchronized (stats) {
12454                            wtime = stats.getProcessWakeTime(r.info.uid,
12455                                    r.pid, curRealtime);
12456                        }
12457                        long timeUsed = wtime - r.lastWakeTime;
12458                        pw.print(prefix);
12459                        pw.print("    ");
12460                        pw.print("keep awake over ");
12461                        TimeUtils.formatDuration(realtimeSince, pw);
12462                        pw.print(" used ");
12463                        TimeUtils.formatDuration(timeUsed, pw);
12464                        pw.print(" (");
12465                        pw.print((timeUsed*100)/realtimeSince);
12466                        pw.println("%)");
12467                    }
12468                    if (r.lastCpuTime != 0) {
12469                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12470                        pw.print(prefix);
12471                        pw.print("    ");
12472                        pw.print("run cpu over ");
12473                        TimeUtils.formatDuration(uptimeSince, pw);
12474                        pw.print(" used ");
12475                        TimeUtils.formatDuration(timeUsed, pw);
12476                        pw.print(" (");
12477                        pw.print((timeUsed*100)/uptimeSince);
12478                        pw.println("%)");
12479                    }
12480                }
12481            }
12482        }
12483        return true;
12484    }
12485
12486    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12487        ArrayList<ProcessRecord> procs;
12488        synchronized (this) {
12489            if (args != null && args.length > start
12490                    && args[start].charAt(0) != '-') {
12491                procs = new ArrayList<ProcessRecord>();
12492                int pid = -1;
12493                try {
12494                    pid = Integer.parseInt(args[start]);
12495                } catch (NumberFormatException e) {
12496                }
12497                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12498                    ProcessRecord proc = mLruProcesses.get(i);
12499                    if (proc.pid == pid) {
12500                        procs.add(proc);
12501                    } else if (proc.processName.equals(args[start])) {
12502                        procs.add(proc);
12503                    }
12504                }
12505                if (procs.size() <= 0) {
12506                    return null;
12507                }
12508            } else {
12509                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12510            }
12511        }
12512        return procs;
12513    }
12514
12515    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12516            PrintWriter pw, String[] args) {
12517        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12518        if (procs == null) {
12519            pw.println("No process found for: " + args[0]);
12520            return;
12521        }
12522
12523        long uptime = SystemClock.uptimeMillis();
12524        long realtime = SystemClock.elapsedRealtime();
12525        pw.println("Applications Graphics Acceleration Info:");
12526        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12527
12528        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12529            ProcessRecord r = procs.get(i);
12530            if (r.thread != null) {
12531                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12532                pw.flush();
12533                try {
12534                    TransferPipe tp = new TransferPipe();
12535                    try {
12536                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12537                        tp.go(fd);
12538                    } finally {
12539                        tp.kill();
12540                    }
12541                } catch (IOException e) {
12542                    pw.println("Failure while dumping the app: " + r);
12543                    pw.flush();
12544                } catch (RemoteException e) {
12545                    pw.println("Got a RemoteException while dumping the app " + r);
12546                    pw.flush();
12547                }
12548            }
12549        }
12550    }
12551
12552    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12553        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12554        if (procs == null) {
12555            pw.println("No process found for: " + args[0]);
12556            return;
12557        }
12558
12559        pw.println("Applications Database Info:");
12560
12561        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12562            ProcessRecord r = procs.get(i);
12563            if (r.thread != null) {
12564                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12565                pw.flush();
12566                try {
12567                    TransferPipe tp = new TransferPipe();
12568                    try {
12569                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12570                        tp.go(fd);
12571                    } finally {
12572                        tp.kill();
12573                    }
12574                } catch (IOException e) {
12575                    pw.println("Failure while dumping the app: " + r);
12576                    pw.flush();
12577                } catch (RemoteException e) {
12578                    pw.println("Got a RemoteException while dumping the app " + r);
12579                    pw.flush();
12580                }
12581            }
12582        }
12583    }
12584
12585    final static class MemItem {
12586        final boolean isProc;
12587        final String label;
12588        final String shortLabel;
12589        final long pss;
12590        final int id;
12591        final boolean hasActivities;
12592        ArrayList<MemItem> subitems;
12593
12594        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12595                boolean _hasActivities) {
12596            isProc = true;
12597            label = _label;
12598            shortLabel = _shortLabel;
12599            pss = _pss;
12600            id = _id;
12601            hasActivities = _hasActivities;
12602        }
12603
12604        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12605            isProc = false;
12606            label = _label;
12607            shortLabel = _shortLabel;
12608            pss = _pss;
12609            id = _id;
12610            hasActivities = false;
12611        }
12612    }
12613
12614    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12615            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12616        if (sort && !isCompact) {
12617            Collections.sort(items, new Comparator<MemItem>() {
12618                @Override
12619                public int compare(MemItem lhs, MemItem rhs) {
12620                    if (lhs.pss < rhs.pss) {
12621                        return 1;
12622                    } else if (lhs.pss > rhs.pss) {
12623                        return -1;
12624                    }
12625                    return 0;
12626                }
12627            });
12628        }
12629
12630        for (int i=0; i<items.size(); i++) {
12631            MemItem mi = items.get(i);
12632            if (!isCompact) {
12633                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12634            } else if (mi.isProc) {
12635                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12636                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12637                pw.println(mi.hasActivities ? ",a" : ",e");
12638            } else {
12639                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12640                pw.println(mi.pss);
12641            }
12642            if (mi.subitems != null) {
12643                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12644                        true, isCompact);
12645            }
12646        }
12647    }
12648
12649    // These are in KB.
12650    static final long[] DUMP_MEM_BUCKETS = new long[] {
12651        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12652        120*1024, 160*1024, 200*1024,
12653        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12654        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12655    };
12656
12657    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12658            boolean stackLike) {
12659        int start = label.lastIndexOf('.');
12660        if (start >= 0) start++;
12661        else start = 0;
12662        int end = label.length();
12663        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12664            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12665                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12666                out.append(bucket);
12667                out.append(stackLike ? "MB." : "MB ");
12668                out.append(label, start, end);
12669                return;
12670            }
12671        }
12672        out.append(memKB/1024);
12673        out.append(stackLike ? "MB." : "MB ");
12674        out.append(label, start, end);
12675    }
12676
12677    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12678            ProcessList.NATIVE_ADJ,
12679            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12680            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12681            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12682            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12683            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12684    };
12685    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12686            "Native",
12687            "System", "Persistent", "Foreground",
12688            "Visible", "Perceptible",
12689            "Heavy Weight", "Backup",
12690            "A Services", "Home",
12691            "Previous", "B Services", "Cached"
12692    };
12693    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12694            "native",
12695            "sys", "pers", "fore",
12696            "vis", "percept",
12697            "heavy", "backup",
12698            "servicea", "home",
12699            "prev", "serviceb", "cached"
12700    };
12701
12702    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12703            long realtime, boolean isCheckinRequest, boolean isCompact) {
12704        if (isCheckinRequest || isCompact) {
12705            // short checkin version
12706            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12707        } else {
12708            pw.println("Applications Memory Usage (kB):");
12709            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12710        }
12711    }
12712
12713    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12714            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12715        boolean dumpDetails = false;
12716        boolean dumpFullDetails = false;
12717        boolean dumpDalvik = false;
12718        boolean oomOnly = false;
12719        boolean isCompact = false;
12720        boolean localOnly = false;
12721
12722        int opti = 0;
12723        while (opti < args.length) {
12724            String opt = args[opti];
12725            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12726                break;
12727            }
12728            opti++;
12729            if ("-a".equals(opt)) {
12730                dumpDetails = true;
12731                dumpFullDetails = true;
12732                dumpDalvik = true;
12733            } else if ("-d".equals(opt)) {
12734                dumpDalvik = true;
12735            } else if ("-c".equals(opt)) {
12736                isCompact = true;
12737            } else if ("--oom".equals(opt)) {
12738                oomOnly = true;
12739            } else if ("--local".equals(opt)) {
12740                localOnly = true;
12741            } else if ("-h".equals(opt)) {
12742                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12743                pw.println("  -a: include all available information for each process.");
12744                pw.println("  -d: include dalvik details when dumping process details.");
12745                pw.println("  -c: dump in a compact machine-parseable representation.");
12746                pw.println("  --oom: only show processes organized by oom adj.");
12747                pw.println("  --local: only collect details locally, don't call process.");
12748                pw.println("If [process] is specified it can be the name or ");
12749                pw.println("pid of a specific process to dump.");
12750                return;
12751            } else {
12752                pw.println("Unknown argument: " + opt + "; use -h for help");
12753            }
12754        }
12755
12756        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12757        long uptime = SystemClock.uptimeMillis();
12758        long realtime = SystemClock.elapsedRealtime();
12759        final long[] tmpLong = new long[1];
12760
12761        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12762        if (procs == null) {
12763            // No Java processes.  Maybe they want to print a native process.
12764            if (args != null && args.length > opti
12765                    && args[opti].charAt(0) != '-') {
12766                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12767                        = new ArrayList<ProcessCpuTracker.Stats>();
12768                updateCpuStatsNow();
12769                int findPid = -1;
12770                try {
12771                    findPid = Integer.parseInt(args[opti]);
12772                } catch (NumberFormatException e) {
12773                }
12774                synchronized (mProcessCpuThread) {
12775                    final int N = mProcessCpuTracker.countStats();
12776                    for (int i=0; i<N; i++) {
12777                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12778                        if (st.pid == findPid || (st.baseName != null
12779                                && st.baseName.equals(args[opti]))) {
12780                            nativeProcs.add(st);
12781                        }
12782                    }
12783                }
12784                if (nativeProcs.size() > 0) {
12785                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12786                            isCompact);
12787                    Debug.MemoryInfo mi = null;
12788                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12789                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12790                        final int pid = r.pid;
12791                        if (!isCheckinRequest && dumpDetails) {
12792                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12793                        }
12794                        if (mi == null) {
12795                            mi = new Debug.MemoryInfo();
12796                        }
12797                        if (dumpDetails || (!brief && !oomOnly)) {
12798                            Debug.getMemoryInfo(pid, mi);
12799                        } else {
12800                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12801                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12802                        }
12803                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12804                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12805                        if (isCheckinRequest) {
12806                            pw.println();
12807                        }
12808                    }
12809                    return;
12810                }
12811            }
12812            pw.println("No process found for: " + args[opti]);
12813            return;
12814        }
12815
12816        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12817            dumpDetails = true;
12818        }
12819
12820        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12821
12822        String[] innerArgs = new String[args.length-opti];
12823        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12824
12825        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12826        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12827        long nativePss=0, dalvikPss=0, otherPss=0;
12828        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12829
12830        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12831        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12832                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12833
12834        long totalPss = 0;
12835        long cachedPss = 0;
12836
12837        Debug.MemoryInfo mi = null;
12838        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12839            final ProcessRecord r = procs.get(i);
12840            final IApplicationThread thread;
12841            final int pid;
12842            final int oomAdj;
12843            final boolean hasActivities;
12844            synchronized (this) {
12845                thread = r.thread;
12846                pid = r.pid;
12847                oomAdj = r.getSetAdjWithServices();
12848                hasActivities = r.activities.size() > 0;
12849            }
12850            if (thread != null) {
12851                if (!isCheckinRequest && dumpDetails) {
12852                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12853                }
12854                if (mi == null) {
12855                    mi = new Debug.MemoryInfo();
12856                }
12857                if (dumpDetails || (!brief && !oomOnly)) {
12858                    Debug.getMemoryInfo(pid, mi);
12859                } else {
12860                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12861                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12862                }
12863                if (dumpDetails) {
12864                    if (localOnly) {
12865                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12866                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12867                        if (isCheckinRequest) {
12868                            pw.println();
12869                        }
12870                    } else {
12871                        try {
12872                            pw.flush();
12873                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12874                                    dumpDalvik, innerArgs);
12875                        } catch (RemoteException e) {
12876                            if (!isCheckinRequest) {
12877                                pw.println("Got RemoteException!");
12878                                pw.flush();
12879                            }
12880                        }
12881                    }
12882                }
12883
12884                final long myTotalPss = mi.getTotalPss();
12885                final long myTotalUss = mi.getTotalUss();
12886
12887                synchronized (this) {
12888                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12889                        // Record this for posterity if the process has been stable.
12890                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12891                    }
12892                }
12893
12894                if (!isCheckinRequest && mi != null) {
12895                    totalPss += myTotalPss;
12896                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12897                            (hasActivities ? " / activities)" : ")"),
12898                            r.processName, myTotalPss, pid, hasActivities);
12899                    procMems.add(pssItem);
12900                    procMemsMap.put(pid, pssItem);
12901
12902                    nativePss += mi.nativePss;
12903                    dalvikPss += mi.dalvikPss;
12904                    otherPss += mi.otherPss;
12905                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12906                        long mem = mi.getOtherPss(j);
12907                        miscPss[j] += mem;
12908                        otherPss -= mem;
12909                    }
12910
12911                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12912                        cachedPss += myTotalPss;
12913                    }
12914
12915                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12916                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12917                                || oomIndex == (oomPss.length-1)) {
12918                            oomPss[oomIndex] += myTotalPss;
12919                            if (oomProcs[oomIndex] == null) {
12920                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12921                            }
12922                            oomProcs[oomIndex].add(pssItem);
12923                            break;
12924                        }
12925                    }
12926                }
12927            }
12928        }
12929
12930        long nativeProcTotalPss = 0;
12931
12932        if (!isCheckinRequest && procs.size() > 1) {
12933            // If we are showing aggregations, also look for native processes to
12934            // include so that our aggregations are more accurate.
12935            updateCpuStatsNow();
12936            synchronized (mProcessCpuThread) {
12937                final int N = mProcessCpuTracker.countStats();
12938                for (int i=0; i<N; i++) {
12939                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12940                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12941                        if (mi == null) {
12942                            mi = new Debug.MemoryInfo();
12943                        }
12944                        if (!brief && !oomOnly) {
12945                            Debug.getMemoryInfo(st.pid, mi);
12946                        } else {
12947                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12948                            mi.nativePrivateDirty = (int)tmpLong[0];
12949                        }
12950
12951                        final long myTotalPss = mi.getTotalPss();
12952                        totalPss += myTotalPss;
12953                        nativeProcTotalPss += myTotalPss;
12954
12955                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12956                                st.name, myTotalPss, st.pid, false);
12957                        procMems.add(pssItem);
12958
12959                        nativePss += mi.nativePss;
12960                        dalvikPss += mi.dalvikPss;
12961                        otherPss += mi.otherPss;
12962                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12963                            long mem = mi.getOtherPss(j);
12964                            miscPss[j] += mem;
12965                            otherPss -= mem;
12966                        }
12967                        oomPss[0] += myTotalPss;
12968                        if (oomProcs[0] == null) {
12969                            oomProcs[0] = new ArrayList<MemItem>();
12970                        }
12971                        oomProcs[0].add(pssItem);
12972                    }
12973                }
12974            }
12975
12976            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12977
12978            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12979            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12980            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12981            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12982                String label = Debug.MemoryInfo.getOtherLabel(j);
12983                catMems.add(new MemItem(label, label, miscPss[j], j));
12984            }
12985
12986            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12987            for (int j=0; j<oomPss.length; j++) {
12988                if (oomPss[j] != 0) {
12989                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12990                            : DUMP_MEM_OOM_LABEL[j];
12991                    MemItem item = new MemItem(label, label, oomPss[j],
12992                            DUMP_MEM_OOM_ADJ[j]);
12993                    item.subitems = oomProcs[j];
12994                    oomMems.add(item);
12995                }
12996            }
12997
12998            if (!brief && !oomOnly && !isCompact) {
12999                pw.println();
13000                pw.println("Total PSS by process:");
13001                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13002                pw.println();
13003            }
13004            if (!isCompact) {
13005                pw.println("Total PSS by OOM adjustment:");
13006            }
13007            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13008            if (!brief && !oomOnly) {
13009                PrintWriter out = categoryPw != null ? categoryPw : pw;
13010                if (!isCompact) {
13011                    out.println();
13012                    out.println("Total PSS by category:");
13013                }
13014                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13015            }
13016            if (!isCompact) {
13017                pw.println();
13018            }
13019            MemInfoReader memInfo = new MemInfoReader();
13020            memInfo.readMemInfo();
13021            if (nativeProcTotalPss > 0) {
13022                synchronized (this) {
13023                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13024                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13025                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13026                            nativeProcTotalPss);
13027                }
13028            }
13029            if (!brief) {
13030                if (!isCompact) {
13031                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13032                    pw.print(" kB (status ");
13033                    switch (mLastMemoryLevel) {
13034                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13035                            pw.println("normal)");
13036                            break;
13037                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13038                            pw.println("moderate)");
13039                            break;
13040                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13041                            pw.println("low)");
13042                            break;
13043                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13044                            pw.println("critical)");
13045                            break;
13046                        default:
13047                            pw.print(mLastMemoryLevel);
13048                            pw.println(")");
13049                            break;
13050                    }
13051                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13052                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13053                            pw.print(cachedPss); pw.print(" cached pss + ");
13054                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13055                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13056                } else {
13057                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13058                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13059                            + memInfo.getFreeSizeKb()); pw.print(",");
13060                    pw.println(totalPss - cachedPss);
13061                }
13062            }
13063            if (!isCompact) {
13064                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13065                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13066                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13067                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13068                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13069                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13070                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13071                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13072                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13073                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13074                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13075            }
13076            if (!brief) {
13077                if (memInfo.getZramTotalSizeKb() != 0) {
13078                    if (!isCompact) {
13079                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13080                                pw.print(" kB physical used for ");
13081                                pw.print(memInfo.getSwapTotalSizeKb()
13082                                        - memInfo.getSwapFreeSizeKb());
13083                                pw.print(" kB in swap (");
13084                                pw.print(memInfo.getSwapTotalSizeKb());
13085                                pw.println(" kB total swap)");
13086                    } else {
13087                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13088                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13089                                pw.println(memInfo.getSwapFreeSizeKb());
13090                    }
13091                }
13092                final int[] SINGLE_LONG_FORMAT = new int[] {
13093                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13094                };
13095                long[] longOut = new long[1];
13096                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13097                        SINGLE_LONG_FORMAT, null, longOut, null);
13098                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13099                longOut[0] = 0;
13100                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13101                        SINGLE_LONG_FORMAT, null, longOut, null);
13102                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13103                longOut[0] = 0;
13104                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13105                        SINGLE_LONG_FORMAT, null, longOut, null);
13106                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13107                longOut[0] = 0;
13108                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13109                        SINGLE_LONG_FORMAT, null, longOut, null);
13110                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13111                if (!isCompact) {
13112                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13113                        pw.print("      KSM: "); pw.print(sharing);
13114                                pw.print(" kB saved from shared ");
13115                                pw.print(shared); pw.println(" kB");
13116                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13117                                pw.print(voltile); pw.println(" kB volatile");
13118                    }
13119                    pw.print("   Tuning: ");
13120                    pw.print(ActivityManager.staticGetMemoryClass());
13121                    pw.print(" (large ");
13122                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13123                    pw.print("), oom ");
13124                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13125                    pw.print(" kB");
13126                    pw.print(", restore limit ");
13127                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13128                    pw.print(" kB");
13129                    if (ActivityManager.isLowRamDeviceStatic()) {
13130                        pw.print(" (low-ram)");
13131                    }
13132                    if (ActivityManager.isHighEndGfx()) {
13133                        pw.print(" (high-end-gfx)");
13134                    }
13135                    pw.println();
13136                } else {
13137                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13138                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13139                    pw.println(voltile);
13140                    pw.print("tuning,");
13141                    pw.print(ActivityManager.staticGetMemoryClass());
13142                    pw.print(',');
13143                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13144                    pw.print(',');
13145                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13146                    if (ActivityManager.isLowRamDeviceStatic()) {
13147                        pw.print(",low-ram");
13148                    }
13149                    if (ActivityManager.isHighEndGfx()) {
13150                        pw.print(",high-end-gfx");
13151                    }
13152                    pw.println();
13153                }
13154            }
13155        }
13156    }
13157
13158    /**
13159     * Searches array of arguments for the specified string
13160     * @param args array of argument strings
13161     * @param value value to search for
13162     * @return true if the value is contained in the array
13163     */
13164    private static boolean scanArgs(String[] args, String value) {
13165        if (args != null) {
13166            for (String arg : args) {
13167                if (value.equals(arg)) {
13168                    return true;
13169                }
13170            }
13171        }
13172        return false;
13173    }
13174
13175    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13176            ContentProviderRecord cpr, boolean always) {
13177        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13178
13179        if (!inLaunching || always) {
13180            synchronized (cpr) {
13181                cpr.launchingApp = null;
13182                cpr.notifyAll();
13183            }
13184            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13185            String names[] = cpr.info.authority.split(";");
13186            for (int j = 0; j < names.length; j++) {
13187                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13188            }
13189        }
13190
13191        for (int i=0; i<cpr.connections.size(); i++) {
13192            ContentProviderConnection conn = cpr.connections.get(i);
13193            if (conn.waiting) {
13194                // If this connection is waiting for the provider, then we don't
13195                // need to mess with its process unless we are always removing
13196                // or for some reason the provider is not currently launching.
13197                if (inLaunching && !always) {
13198                    continue;
13199                }
13200            }
13201            ProcessRecord capp = conn.client;
13202            conn.dead = true;
13203            if (conn.stableCount > 0) {
13204                if (!capp.persistent && capp.thread != null
13205                        && capp.pid != 0
13206                        && capp.pid != MY_PID) {
13207                    killUnneededProcessLocked(capp, "depends on provider "
13208                            + cpr.name.flattenToShortString()
13209                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13210                }
13211            } else if (capp.thread != null && conn.provider.provider != null) {
13212                try {
13213                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13214                } catch (RemoteException e) {
13215                }
13216                // In the protocol here, we don't expect the client to correctly
13217                // clean up this connection, we'll just remove it.
13218                cpr.connections.remove(i);
13219                conn.client.conProviders.remove(conn);
13220            }
13221        }
13222
13223        if (inLaunching && always) {
13224            mLaunchingProviders.remove(cpr);
13225        }
13226        return inLaunching;
13227    }
13228
13229    /**
13230     * Main code for cleaning up a process when it has gone away.  This is
13231     * called both as a result of the process dying, or directly when stopping
13232     * a process when running in single process mode.
13233     */
13234    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13235            boolean restarting, boolean allowRestart, int index) {
13236        if (index >= 0) {
13237            removeLruProcessLocked(app);
13238            ProcessList.remove(app.pid);
13239        }
13240
13241        mProcessesToGc.remove(app);
13242        mPendingPssProcesses.remove(app);
13243
13244        // Dismiss any open dialogs.
13245        if (app.crashDialog != null && !app.forceCrashReport) {
13246            app.crashDialog.dismiss();
13247            app.crashDialog = null;
13248        }
13249        if (app.anrDialog != null) {
13250            app.anrDialog.dismiss();
13251            app.anrDialog = null;
13252        }
13253        if (app.waitDialog != null) {
13254            app.waitDialog.dismiss();
13255            app.waitDialog = null;
13256        }
13257
13258        app.crashing = false;
13259        app.notResponding = false;
13260
13261        app.resetPackageList(mProcessStats);
13262        app.unlinkDeathRecipient();
13263        app.makeInactive(mProcessStats);
13264        app.waitingToKill = null;
13265        app.forcingToForeground = null;
13266        updateProcessForegroundLocked(app, false, false);
13267        app.foregroundActivities = false;
13268        app.hasShownUi = false;
13269        app.treatLikeActivity = false;
13270        app.hasAboveClient = false;
13271        app.hasClientActivities = false;
13272
13273        mServices.killServicesLocked(app, allowRestart);
13274
13275        boolean restart = false;
13276
13277        // Remove published content providers.
13278        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13279            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13280            final boolean always = app.bad || !allowRestart;
13281            if (removeDyingProviderLocked(app, cpr, always) || always) {
13282                // We left the provider in the launching list, need to
13283                // restart it.
13284                restart = true;
13285            }
13286
13287            cpr.provider = null;
13288            cpr.proc = null;
13289        }
13290        app.pubProviders.clear();
13291
13292        // Take care of any launching providers waiting for this process.
13293        if (checkAppInLaunchingProvidersLocked(app, false)) {
13294            restart = true;
13295        }
13296
13297        // Unregister from connected content providers.
13298        if (!app.conProviders.isEmpty()) {
13299            for (int i=0; i<app.conProviders.size(); i++) {
13300                ContentProviderConnection conn = app.conProviders.get(i);
13301                conn.provider.connections.remove(conn);
13302            }
13303            app.conProviders.clear();
13304        }
13305
13306        // At this point there may be remaining entries in mLaunchingProviders
13307        // where we were the only one waiting, so they are no longer of use.
13308        // Look for these and clean up if found.
13309        // XXX Commented out for now.  Trying to figure out a way to reproduce
13310        // the actual situation to identify what is actually going on.
13311        if (false) {
13312            for (int i=0; i<mLaunchingProviders.size(); i++) {
13313                ContentProviderRecord cpr = (ContentProviderRecord)
13314                        mLaunchingProviders.get(i);
13315                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13316                    synchronized (cpr) {
13317                        cpr.launchingApp = null;
13318                        cpr.notifyAll();
13319                    }
13320                }
13321            }
13322        }
13323
13324        skipCurrentReceiverLocked(app);
13325
13326        // Unregister any receivers.
13327        for (int i=app.receivers.size()-1; i>=0; i--) {
13328            removeReceiverLocked(app.receivers.valueAt(i));
13329        }
13330        app.receivers.clear();
13331
13332        // If the app is undergoing backup, tell the backup manager about it
13333        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13334            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13335                    + mBackupTarget.appInfo + " died during backup");
13336            try {
13337                IBackupManager bm = IBackupManager.Stub.asInterface(
13338                        ServiceManager.getService(Context.BACKUP_SERVICE));
13339                bm.agentDisconnected(app.info.packageName);
13340            } catch (RemoteException e) {
13341                // can't happen; backup manager is local
13342            }
13343        }
13344
13345        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13346            ProcessChangeItem item = mPendingProcessChanges.get(i);
13347            if (item.pid == app.pid) {
13348                mPendingProcessChanges.remove(i);
13349                mAvailProcessChanges.add(item);
13350            }
13351        }
13352        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13353
13354        // If the caller is restarting this app, then leave it in its
13355        // current lists and let the caller take care of it.
13356        if (restarting) {
13357            return;
13358        }
13359
13360        if (!app.persistent || app.isolated) {
13361            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13362                    "Removing non-persistent process during cleanup: " + app);
13363            mProcessNames.remove(app.processName, app.uid);
13364            mIsolatedProcesses.remove(app.uid);
13365            if (mHeavyWeightProcess == app) {
13366                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13367                        mHeavyWeightProcess.userId, 0));
13368                mHeavyWeightProcess = null;
13369            }
13370        } else if (!app.removed) {
13371            // This app is persistent, so we need to keep its record around.
13372            // If it is not already on the pending app list, add it there
13373            // and start a new process for it.
13374            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13375                mPersistentStartingProcesses.add(app);
13376                restart = true;
13377            }
13378        }
13379        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13380                "Clean-up removing on hold: " + app);
13381        mProcessesOnHold.remove(app);
13382
13383        if (app == mHomeProcess) {
13384            mHomeProcess = null;
13385        }
13386        if (app == mPreviousProcess) {
13387            mPreviousProcess = null;
13388        }
13389
13390        if (restart && !app.isolated) {
13391            // We have components that still need to be running in the
13392            // process, so re-launch it.
13393            mProcessNames.put(app.processName, app.uid, app);
13394            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13395        } else if (app.pid > 0 && app.pid != MY_PID) {
13396            // Goodbye!
13397            boolean removed;
13398            synchronized (mPidsSelfLocked) {
13399                mPidsSelfLocked.remove(app.pid);
13400                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13401            }
13402            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
13403            if (app.isolated) {
13404                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13405            }
13406            app.setPid(0);
13407        }
13408    }
13409
13410    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13411        // Look through the content providers we are waiting to have launched,
13412        // and if any run in this process then either schedule a restart of
13413        // the process or kill the client waiting for it if this process has
13414        // gone bad.
13415        int NL = mLaunchingProviders.size();
13416        boolean restart = false;
13417        for (int i=0; i<NL; i++) {
13418            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13419            if (cpr.launchingApp == app) {
13420                if (!alwaysBad && !app.bad) {
13421                    restart = true;
13422                } else {
13423                    removeDyingProviderLocked(app, cpr, true);
13424                    // cpr should have been removed from mLaunchingProviders
13425                    NL = mLaunchingProviders.size();
13426                    i--;
13427                }
13428            }
13429        }
13430        return restart;
13431    }
13432
13433    // =========================================================
13434    // SERVICES
13435    // =========================================================
13436
13437    @Override
13438    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13439            int flags) {
13440        enforceNotIsolatedCaller("getServices");
13441        synchronized (this) {
13442            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13443        }
13444    }
13445
13446    @Override
13447    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13448        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13449        synchronized (this) {
13450            return mServices.getRunningServiceControlPanelLocked(name);
13451        }
13452    }
13453
13454    @Override
13455    public ComponentName startService(IApplicationThread caller, Intent service,
13456            String resolvedType, int userId) {
13457        enforceNotIsolatedCaller("startService");
13458        // Refuse possible leaked file descriptors
13459        if (service != null && service.hasFileDescriptors() == true) {
13460            throw new IllegalArgumentException("File descriptors passed in Intent");
13461        }
13462
13463        if (DEBUG_SERVICE)
13464            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13465        synchronized(this) {
13466            final int callingPid = Binder.getCallingPid();
13467            final int callingUid = Binder.getCallingUid();
13468            final long origId = Binder.clearCallingIdentity();
13469            ComponentName res = mServices.startServiceLocked(caller, service,
13470                    resolvedType, callingPid, callingUid, userId);
13471            Binder.restoreCallingIdentity(origId);
13472            return res;
13473        }
13474    }
13475
13476    ComponentName startServiceInPackage(int uid,
13477            Intent service, String resolvedType, int userId) {
13478        synchronized(this) {
13479            if (DEBUG_SERVICE)
13480                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13481            final long origId = Binder.clearCallingIdentity();
13482            ComponentName res = mServices.startServiceLocked(null, service,
13483                    resolvedType, -1, uid, userId);
13484            Binder.restoreCallingIdentity(origId);
13485            return res;
13486        }
13487    }
13488
13489    @Override
13490    public int stopService(IApplicationThread caller, Intent service,
13491            String resolvedType, int userId) {
13492        enforceNotIsolatedCaller("stopService");
13493        // Refuse possible leaked file descriptors
13494        if (service != null && service.hasFileDescriptors() == true) {
13495            throw new IllegalArgumentException("File descriptors passed in Intent");
13496        }
13497
13498        synchronized(this) {
13499            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13500        }
13501    }
13502
13503    @Override
13504    public IBinder peekService(Intent service, String resolvedType) {
13505        enforceNotIsolatedCaller("peekService");
13506        // Refuse possible leaked file descriptors
13507        if (service != null && service.hasFileDescriptors() == true) {
13508            throw new IllegalArgumentException("File descriptors passed in Intent");
13509        }
13510        synchronized(this) {
13511            return mServices.peekServiceLocked(service, resolvedType);
13512        }
13513    }
13514
13515    @Override
13516    public boolean stopServiceToken(ComponentName className, IBinder token,
13517            int startId) {
13518        synchronized(this) {
13519            return mServices.stopServiceTokenLocked(className, token, startId);
13520        }
13521    }
13522
13523    @Override
13524    public void setServiceForeground(ComponentName className, IBinder token,
13525            int id, Notification notification, boolean removeNotification) {
13526        synchronized(this) {
13527            mServices.setServiceForegroundLocked(className, token, id, notification,
13528                    removeNotification);
13529        }
13530    }
13531
13532    @Override
13533    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13534            boolean requireFull, String name, String callerPackage) {
13535        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
13536                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
13537    }
13538
13539    int unsafeConvertIncomingUser(int userId) {
13540        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
13541                ? mCurrentUserId : userId;
13542    }
13543
13544    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13545            int allowMode, String name, String callerPackage) {
13546        final int callingUserId = UserHandle.getUserId(callingUid);
13547        if (callingUserId == userId) {
13548            return userId;
13549        }
13550
13551        // Note that we may be accessing mCurrentUserId outside of a lock...
13552        // shouldn't be a big deal, if this is being called outside
13553        // of a locked context there is intrinsically a race with
13554        // the value the caller will receive and someone else changing it.
13555        // We assume that USER_CURRENT_OR_SELF will use the current user; later
13556        // we will switch to the calling user if access to the current user fails.
13557        int targetUserId = unsafeConvertIncomingUser(userId);
13558
13559        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13560            final boolean allow;
13561            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
13562                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
13563                // If the caller has this permission, they always pass go.  And collect $200.
13564                allow = true;
13565            } else if (allowMode == ALLOW_FULL_ONLY) {
13566                // We require full access, sucks to be you.
13567                allow = false;
13568            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
13569                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
13570                // If the caller does not have either permission, they are always doomed.
13571                allow = false;
13572            } else if (allowMode == ALLOW_NON_FULL) {
13573                // We are blanket allowing non-full access, you lucky caller!
13574                allow = true;
13575            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
13576                // We may or may not allow this depending on whether the two users are
13577                // in the same profile.
13578                synchronized (mUserProfileGroupIdsSelfLocked) {
13579                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
13580                            UserInfo.NO_PROFILE_GROUP_ID);
13581                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
13582                            UserInfo.NO_PROFILE_GROUP_ID);
13583                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
13584                            && callingProfile == targetProfile;
13585                }
13586            } else {
13587                throw new IllegalArgumentException("Unknown mode: " + allowMode);
13588            }
13589            if (!allow) {
13590                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13591                    // In this case, they would like to just execute as their
13592                    // owner user instead of failing.
13593                    targetUserId = callingUserId;
13594                } else {
13595                    StringBuilder builder = new StringBuilder(128);
13596                    builder.append("Permission Denial: ");
13597                    builder.append(name);
13598                    if (callerPackage != null) {
13599                        builder.append(" from ");
13600                        builder.append(callerPackage);
13601                    }
13602                    builder.append(" asks to run as user ");
13603                    builder.append(userId);
13604                    builder.append(" but is calling from user ");
13605                    builder.append(UserHandle.getUserId(callingUid));
13606                    builder.append("; this requires ");
13607                    builder.append(INTERACT_ACROSS_USERS_FULL);
13608                    if (allowMode != ALLOW_FULL_ONLY) {
13609                        builder.append(" or ");
13610                        builder.append(INTERACT_ACROSS_USERS);
13611                    }
13612                    String msg = builder.toString();
13613                    Slog.w(TAG, msg);
13614                    throw new SecurityException(msg);
13615                }
13616            }
13617        }
13618        if (!allowAll && targetUserId < 0) {
13619            throw new IllegalArgumentException(
13620                    "Call does not support special user #" + targetUserId);
13621        }
13622        return targetUserId;
13623    }
13624
13625    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13626            String className, int flags) {
13627        boolean result = false;
13628        // For apps that don't have pre-defined UIDs, check for permission
13629        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13630            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13631                if (ActivityManager.checkUidPermission(
13632                        INTERACT_ACROSS_USERS,
13633                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13634                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13635                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13636                            + " requests FLAG_SINGLE_USER, but app does not hold "
13637                            + INTERACT_ACROSS_USERS;
13638                    Slog.w(TAG, msg);
13639                    throw new SecurityException(msg);
13640                }
13641                // Permission passed
13642                result = true;
13643            }
13644        } else if ("system".equals(componentProcessName)) {
13645            result = true;
13646        } else {
13647            // App with pre-defined UID, check if it's a persistent app
13648            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13649        }
13650        if (DEBUG_MU) {
13651            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13652                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13653        }
13654        return result;
13655    }
13656
13657    /**
13658     * Checks to see if the caller is in the same app as the singleton
13659     * component, or the component is in a special app. It allows special apps
13660     * to export singleton components but prevents exporting singleton
13661     * components for regular apps.
13662     */
13663    boolean isValidSingletonCall(int callingUid, int componentUid) {
13664        int componentAppId = UserHandle.getAppId(componentUid);
13665        return UserHandle.isSameApp(callingUid, componentUid)
13666                || componentAppId == Process.SYSTEM_UID
13667                || componentAppId == Process.PHONE_UID
13668                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13669                        == PackageManager.PERMISSION_GRANTED;
13670    }
13671
13672    public int bindService(IApplicationThread caller, IBinder token,
13673            Intent service, String resolvedType,
13674            IServiceConnection connection, int flags, int userId) {
13675        enforceNotIsolatedCaller("bindService");
13676        // Refuse possible leaked file descriptors
13677        if (service != null && service.hasFileDescriptors() == true) {
13678            throw new IllegalArgumentException("File descriptors passed in Intent");
13679        }
13680
13681        synchronized(this) {
13682            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13683                    connection, flags, userId);
13684        }
13685    }
13686
13687    public boolean unbindService(IServiceConnection connection) {
13688        synchronized (this) {
13689            return mServices.unbindServiceLocked(connection);
13690        }
13691    }
13692
13693    public void publishService(IBinder token, Intent intent, IBinder service) {
13694        // Refuse possible leaked file descriptors
13695        if (intent != null && intent.hasFileDescriptors() == true) {
13696            throw new IllegalArgumentException("File descriptors passed in Intent");
13697        }
13698
13699        synchronized(this) {
13700            if (!(token instanceof ServiceRecord)) {
13701                throw new IllegalArgumentException("Invalid service token");
13702            }
13703            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13704        }
13705    }
13706
13707    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13708        // Refuse possible leaked file descriptors
13709        if (intent != null && intent.hasFileDescriptors() == true) {
13710            throw new IllegalArgumentException("File descriptors passed in Intent");
13711        }
13712
13713        synchronized(this) {
13714            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13715        }
13716    }
13717
13718    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13719        synchronized(this) {
13720            if (!(token instanceof ServiceRecord)) {
13721                throw new IllegalArgumentException("Invalid service token");
13722            }
13723            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13724        }
13725    }
13726
13727    // =========================================================
13728    // BACKUP AND RESTORE
13729    // =========================================================
13730
13731    // Cause the target app to be launched if necessary and its backup agent
13732    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13733    // activity manager to announce its creation.
13734    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13735        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13736        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
13737
13738        synchronized(this) {
13739            // !!! TODO: currently no check here that we're already bound
13740            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13741            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13742            synchronized (stats) {
13743                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13744            }
13745
13746            // Backup agent is now in use, its package can't be stopped.
13747            try {
13748                AppGlobals.getPackageManager().setPackageStoppedState(
13749                        app.packageName, false, UserHandle.getUserId(app.uid));
13750            } catch (RemoteException e) {
13751            } catch (IllegalArgumentException e) {
13752                Slog.w(TAG, "Failed trying to unstop package "
13753                        + app.packageName + ": " + e);
13754            }
13755
13756            BackupRecord r = new BackupRecord(ss, app, backupMode);
13757            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13758                    ? new ComponentName(app.packageName, app.backupAgentName)
13759                    : new ComponentName("android", "FullBackupAgent");
13760            // startProcessLocked() returns existing proc's record if it's already running
13761            ProcessRecord proc = startProcessLocked(app.processName, app,
13762                    false, 0, "backup", hostingName, false, false, false);
13763            if (proc == null) {
13764                Slog.e(TAG, "Unable to start backup agent process " + r);
13765                return false;
13766            }
13767
13768            r.app = proc;
13769            mBackupTarget = r;
13770            mBackupAppName = app.packageName;
13771
13772            // Try not to kill the process during backup
13773            updateOomAdjLocked(proc);
13774
13775            // If the process is already attached, schedule the creation of the backup agent now.
13776            // If it is not yet live, this will be done when it attaches to the framework.
13777            if (proc.thread != null) {
13778                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13779                try {
13780                    proc.thread.scheduleCreateBackupAgent(app,
13781                            compatibilityInfoForPackageLocked(app), backupMode);
13782                } catch (RemoteException e) {
13783                    // Will time out on the backup manager side
13784                }
13785            } else {
13786                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13787            }
13788            // Invariants: at this point, the target app process exists and the application
13789            // is either already running or in the process of coming up.  mBackupTarget and
13790            // mBackupAppName describe the app, so that when it binds back to the AM we
13791            // know that it's scheduled for a backup-agent operation.
13792        }
13793
13794        return true;
13795    }
13796
13797    @Override
13798    public void clearPendingBackup() {
13799        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13800        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13801
13802        synchronized (this) {
13803            mBackupTarget = null;
13804            mBackupAppName = null;
13805        }
13806    }
13807
13808    // A backup agent has just come up
13809    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13810        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13811                + " = " + agent);
13812
13813        synchronized(this) {
13814            if (!agentPackageName.equals(mBackupAppName)) {
13815                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13816                return;
13817            }
13818        }
13819
13820        long oldIdent = Binder.clearCallingIdentity();
13821        try {
13822            IBackupManager bm = IBackupManager.Stub.asInterface(
13823                    ServiceManager.getService(Context.BACKUP_SERVICE));
13824            bm.agentConnected(agentPackageName, agent);
13825        } catch (RemoteException e) {
13826            // can't happen; the backup manager service is local
13827        } catch (Exception e) {
13828            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13829            e.printStackTrace();
13830        } finally {
13831            Binder.restoreCallingIdentity(oldIdent);
13832        }
13833    }
13834
13835    // done with this agent
13836    public void unbindBackupAgent(ApplicationInfo appInfo) {
13837        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13838        if (appInfo == null) {
13839            Slog.w(TAG, "unbind backup agent for null app");
13840            return;
13841        }
13842
13843        synchronized(this) {
13844            try {
13845                if (mBackupAppName == null) {
13846                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13847                    return;
13848                }
13849
13850                if (!mBackupAppName.equals(appInfo.packageName)) {
13851                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13852                    return;
13853                }
13854
13855                // Not backing this app up any more; reset its OOM adjustment
13856                final ProcessRecord proc = mBackupTarget.app;
13857                updateOomAdjLocked(proc);
13858
13859                // If the app crashed during backup, 'thread' will be null here
13860                if (proc.thread != null) {
13861                    try {
13862                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13863                                compatibilityInfoForPackageLocked(appInfo));
13864                    } catch (Exception e) {
13865                        Slog.e(TAG, "Exception when unbinding backup agent:");
13866                        e.printStackTrace();
13867                    }
13868                }
13869            } finally {
13870                mBackupTarget = null;
13871                mBackupAppName = null;
13872            }
13873        }
13874    }
13875    // =========================================================
13876    // BROADCASTS
13877    // =========================================================
13878
13879    private final List getStickiesLocked(String action, IntentFilter filter,
13880            List cur, int userId) {
13881        final ContentResolver resolver = mContext.getContentResolver();
13882        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13883        if (stickies == null) {
13884            return cur;
13885        }
13886        final ArrayList<Intent> list = stickies.get(action);
13887        if (list == null) {
13888            return cur;
13889        }
13890        int N = list.size();
13891        for (int i=0; i<N; i++) {
13892            Intent intent = list.get(i);
13893            if (filter.match(resolver, intent, true, TAG) >= 0) {
13894                if (cur == null) {
13895                    cur = new ArrayList<Intent>();
13896                }
13897                cur.add(intent);
13898            }
13899        }
13900        return cur;
13901    }
13902
13903    boolean isPendingBroadcastProcessLocked(int pid) {
13904        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13905                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13906    }
13907
13908    void skipPendingBroadcastLocked(int pid) {
13909            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13910            for (BroadcastQueue queue : mBroadcastQueues) {
13911                queue.skipPendingBroadcastLocked(pid);
13912            }
13913    }
13914
13915    // The app just attached; send any pending broadcasts that it should receive
13916    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13917        boolean didSomething = false;
13918        for (BroadcastQueue queue : mBroadcastQueues) {
13919            didSomething |= queue.sendPendingBroadcastsLocked(app);
13920        }
13921        return didSomething;
13922    }
13923
13924    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13925            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13926        enforceNotIsolatedCaller("registerReceiver");
13927        int callingUid;
13928        int callingPid;
13929        synchronized(this) {
13930            ProcessRecord callerApp = null;
13931            if (caller != null) {
13932                callerApp = getRecordForAppLocked(caller);
13933                if (callerApp == null) {
13934                    throw new SecurityException(
13935                            "Unable to find app for caller " + caller
13936                            + " (pid=" + Binder.getCallingPid()
13937                            + ") when registering receiver " + receiver);
13938                }
13939                if (callerApp.info.uid != Process.SYSTEM_UID &&
13940                        !callerApp.pkgList.containsKey(callerPackage) &&
13941                        !"android".equals(callerPackage)) {
13942                    throw new SecurityException("Given caller package " + callerPackage
13943                            + " is not running in process " + callerApp);
13944                }
13945                callingUid = callerApp.info.uid;
13946                callingPid = callerApp.pid;
13947            } else {
13948                callerPackage = null;
13949                callingUid = Binder.getCallingUid();
13950                callingPid = Binder.getCallingPid();
13951            }
13952
13953            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13954                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
13955
13956            List allSticky = null;
13957
13958            // Look for any matching sticky broadcasts...
13959            Iterator actions = filter.actionsIterator();
13960            if (actions != null) {
13961                while (actions.hasNext()) {
13962                    String action = (String)actions.next();
13963                    allSticky = getStickiesLocked(action, filter, allSticky,
13964                            UserHandle.USER_ALL);
13965                    allSticky = getStickiesLocked(action, filter, allSticky,
13966                            UserHandle.getUserId(callingUid));
13967                }
13968            } else {
13969                allSticky = getStickiesLocked(null, filter, allSticky,
13970                        UserHandle.USER_ALL);
13971                allSticky = getStickiesLocked(null, filter, allSticky,
13972                        UserHandle.getUserId(callingUid));
13973            }
13974
13975            // The first sticky in the list is returned directly back to
13976            // the client.
13977            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13978
13979            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13980                    + ": " + sticky);
13981
13982            if (receiver == null) {
13983                return sticky;
13984            }
13985
13986            ReceiverList rl
13987                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13988            if (rl == null) {
13989                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13990                        userId, receiver);
13991                if (rl.app != null) {
13992                    rl.app.receivers.add(rl);
13993                } else {
13994                    try {
13995                        receiver.asBinder().linkToDeath(rl, 0);
13996                    } catch (RemoteException e) {
13997                        return sticky;
13998                    }
13999                    rl.linkedToDeath = true;
14000                }
14001                mRegisteredReceivers.put(receiver.asBinder(), rl);
14002            } else if (rl.uid != callingUid) {
14003                throw new IllegalArgumentException(
14004                        "Receiver requested to register for uid " + callingUid
14005                        + " was previously registered for uid " + rl.uid);
14006            } else if (rl.pid != callingPid) {
14007                throw new IllegalArgumentException(
14008                        "Receiver requested to register for pid " + callingPid
14009                        + " was previously registered for pid " + rl.pid);
14010            } else if (rl.userId != userId) {
14011                throw new IllegalArgumentException(
14012                        "Receiver requested to register for user " + userId
14013                        + " was previously registered for user " + rl.userId);
14014            }
14015            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14016                    permission, callingUid, userId);
14017            rl.add(bf);
14018            if (!bf.debugCheck()) {
14019                Slog.w(TAG, "==> For Dynamic broadast");
14020            }
14021            mReceiverResolver.addFilter(bf);
14022
14023            // Enqueue broadcasts for all existing stickies that match
14024            // this filter.
14025            if (allSticky != null) {
14026                ArrayList receivers = new ArrayList();
14027                receivers.add(bf);
14028
14029                int N = allSticky.size();
14030                for (int i=0; i<N; i++) {
14031                    Intent intent = (Intent)allSticky.get(i);
14032                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14033                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14034                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14035                            null, null, false, true, true, -1);
14036                    queue.enqueueParallelBroadcastLocked(r);
14037                    queue.scheduleBroadcastsLocked();
14038                }
14039            }
14040
14041            return sticky;
14042        }
14043    }
14044
14045    public void unregisterReceiver(IIntentReceiver receiver) {
14046        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14047
14048        final long origId = Binder.clearCallingIdentity();
14049        try {
14050            boolean doTrim = false;
14051
14052            synchronized(this) {
14053                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14054                if (rl != null) {
14055                    if (rl.curBroadcast != null) {
14056                        BroadcastRecord r = rl.curBroadcast;
14057                        final boolean doNext = finishReceiverLocked(
14058                                receiver.asBinder(), r.resultCode, r.resultData,
14059                                r.resultExtras, r.resultAbort);
14060                        if (doNext) {
14061                            doTrim = true;
14062                            r.queue.processNextBroadcast(false);
14063                        }
14064                    }
14065
14066                    if (rl.app != null) {
14067                        rl.app.receivers.remove(rl);
14068                    }
14069                    removeReceiverLocked(rl);
14070                    if (rl.linkedToDeath) {
14071                        rl.linkedToDeath = false;
14072                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14073                    }
14074                }
14075            }
14076
14077            // If we actually concluded any broadcasts, we might now be able
14078            // to trim the recipients' apps from our working set
14079            if (doTrim) {
14080                trimApplications();
14081                return;
14082            }
14083
14084        } finally {
14085            Binder.restoreCallingIdentity(origId);
14086        }
14087    }
14088
14089    void removeReceiverLocked(ReceiverList rl) {
14090        mRegisteredReceivers.remove(rl.receiver.asBinder());
14091        int N = rl.size();
14092        for (int i=0; i<N; i++) {
14093            mReceiverResolver.removeFilter(rl.get(i));
14094        }
14095    }
14096
14097    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14098        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14099            ProcessRecord r = mLruProcesses.get(i);
14100            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14101                try {
14102                    r.thread.dispatchPackageBroadcast(cmd, packages);
14103                } catch (RemoteException ex) {
14104                }
14105            }
14106        }
14107    }
14108
14109    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14110            int[] users) {
14111        List<ResolveInfo> receivers = null;
14112        try {
14113            HashSet<ComponentName> singleUserReceivers = null;
14114            boolean scannedFirstReceivers = false;
14115            for (int user : users) {
14116                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14117                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14118                if (user != 0 && newReceivers != null) {
14119                    // If this is not the primary user, we need to check for
14120                    // any receivers that should be filtered out.
14121                    for (int i=0; i<newReceivers.size(); i++) {
14122                        ResolveInfo ri = newReceivers.get(i);
14123                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14124                            newReceivers.remove(i);
14125                            i--;
14126                        }
14127                    }
14128                }
14129                if (newReceivers != null && newReceivers.size() == 0) {
14130                    newReceivers = null;
14131                }
14132                if (receivers == null) {
14133                    receivers = newReceivers;
14134                } else if (newReceivers != null) {
14135                    // We need to concatenate the additional receivers
14136                    // found with what we have do far.  This would be easy,
14137                    // but we also need to de-dup any receivers that are
14138                    // singleUser.
14139                    if (!scannedFirstReceivers) {
14140                        // Collect any single user receivers we had already retrieved.
14141                        scannedFirstReceivers = true;
14142                        for (int i=0; i<receivers.size(); i++) {
14143                            ResolveInfo ri = receivers.get(i);
14144                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14145                                ComponentName cn = new ComponentName(
14146                                        ri.activityInfo.packageName, ri.activityInfo.name);
14147                                if (singleUserReceivers == null) {
14148                                    singleUserReceivers = new HashSet<ComponentName>();
14149                                }
14150                                singleUserReceivers.add(cn);
14151                            }
14152                        }
14153                    }
14154                    // Add the new results to the existing results, tracking
14155                    // and de-dupping single user receivers.
14156                    for (int i=0; i<newReceivers.size(); i++) {
14157                        ResolveInfo ri = newReceivers.get(i);
14158                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14159                            ComponentName cn = new ComponentName(
14160                                    ri.activityInfo.packageName, ri.activityInfo.name);
14161                            if (singleUserReceivers == null) {
14162                                singleUserReceivers = new HashSet<ComponentName>();
14163                            }
14164                            if (!singleUserReceivers.contains(cn)) {
14165                                singleUserReceivers.add(cn);
14166                                receivers.add(ri);
14167                            }
14168                        } else {
14169                            receivers.add(ri);
14170                        }
14171                    }
14172                }
14173            }
14174        } catch (RemoteException ex) {
14175            // pm is in same process, this will never happen.
14176        }
14177        return receivers;
14178    }
14179
14180    private final int broadcastIntentLocked(ProcessRecord callerApp,
14181            String callerPackage, Intent intent, String resolvedType,
14182            IIntentReceiver resultTo, int resultCode, String resultData,
14183            Bundle map, String requiredPermission, int appOp,
14184            boolean ordered, boolean sticky, int callingPid, int callingUid,
14185            int userId) {
14186        intent = new Intent(intent);
14187
14188        // By default broadcasts do not go to stopped apps.
14189        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
14190
14191        if (DEBUG_BROADCAST_LIGHT) Slog.v(
14192            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
14193            + " ordered=" + ordered + " userid=" + userId);
14194        if ((resultTo != null) && !ordered) {
14195            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
14196        }
14197
14198        userId = handleIncomingUser(callingPid, callingUid, userId,
14199                true, ALLOW_NON_FULL, "broadcast", callerPackage);
14200
14201        // Make sure that the user who is receiving this broadcast is started.
14202        // If not, we will just skip it.
14203
14204
14205        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
14206            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14207                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14208                Slog.w(TAG, "Skipping broadcast of " + intent
14209                        + ": user " + userId + " is stopped");
14210                return ActivityManager.BROADCAST_SUCCESS;
14211            }
14212        }
14213
14214        /*
14215         * Prevent non-system code (defined here to be non-persistent
14216         * processes) from sending protected broadcasts.
14217         */
14218        int callingAppId = UserHandle.getAppId(callingUid);
14219        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14220            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14221            || callingAppId == Process.NFC_UID || callingUid == 0) {
14222            // Always okay.
14223        } else if (callerApp == null || !callerApp.persistent) {
14224            try {
14225                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14226                        intent.getAction())) {
14227                    String msg = "Permission Denial: not allowed to send broadcast "
14228                            + intent.getAction() + " from pid="
14229                            + callingPid + ", uid=" + callingUid;
14230                    Slog.w(TAG, msg);
14231                    throw new SecurityException(msg);
14232                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14233                    // Special case for compatibility: we don't want apps to send this,
14234                    // but historically it has not been protected and apps may be using it
14235                    // to poke their own app widget.  So, instead of making it protected,
14236                    // just limit it to the caller.
14237                    if (callerApp == null) {
14238                        String msg = "Permission Denial: not allowed to send broadcast "
14239                                + intent.getAction() + " from unknown caller.";
14240                        Slog.w(TAG, msg);
14241                        throw new SecurityException(msg);
14242                    } else if (intent.getComponent() != null) {
14243                        // They are good enough to send to an explicit component...  verify
14244                        // it is being sent to the calling app.
14245                        if (!intent.getComponent().getPackageName().equals(
14246                                callerApp.info.packageName)) {
14247                            String msg = "Permission Denial: not allowed to send broadcast "
14248                                    + intent.getAction() + " to "
14249                                    + intent.getComponent().getPackageName() + " from "
14250                                    + callerApp.info.packageName;
14251                            Slog.w(TAG, msg);
14252                            throw new SecurityException(msg);
14253                        }
14254                    } else {
14255                        // Limit broadcast to their own package.
14256                        intent.setPackage(callerApp.info.packageName);
14257                    }
14258                }
14259            } catch (RemoteException e) {
14260                Slog.w(TAG, "Remote exception", e);
14261                return ActivityManager.BROADCAST_SUCCESS;
14262            }
14263        }
14264
14265        // Handle special intents: if this broadcast is from the package
14266        // manager about a package being removed, we need to remove all of
14267        // its activities from the history stack.
14268        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14269                intent.getAction());
14270        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14271                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14272                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14273                || uidRemoved) {
14274            if (checkComponentPermission(
14275                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14276                    callingPid, callingUid, -1, true)
14277                    == PackageManager.PERMISSION_GRANTED) {
14278                if (uidRemoved) {
14279                    final Bundle intentExtras = intent.getExtras();
14280                    final int uid = intentExtras != null
14281                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14282                    if (uid >= 0) {
14283                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14284                        synchronized (bs) {
14285                            bs.removeUidStatsLocked(uid);
14286                        }
14287                        mAppOpsService.uidRemoved(uid);
14288                    }
14289                } else {
14290                    // If resources are unavailable just force stop all
14291                    // those packages and flush the attribute cache as well.
14292                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14293                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14294                        if (list != null && (list.length > 0)) {
14295                            for (String pkg : list) {
14296                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14297                                        "storage unmount");
14298                            }
14299                            sendPackageBroadcastLocked(
14300                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14301                        }
14302                    } else {
14303                        Uri data = intent.getData();
14304                        String ssp;
14305                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14306                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14307                                    intent.getAction());
14308                            boolean fullUninstall = removed &&
14309                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14310                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14311                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14312                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14313                                        false, fullUninstall, userId,
14314                                        removed ? "pkg removed" : "pkg changed");
14315                            }
14316                            if (removed) {
14317                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14318                                        new String[] {ssp}, userId);
14319                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14320                                    mAppOpsService.packageRemoved(
14321                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14322
14323                                    // Remove all permissions granted from/to this package
14324                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14325                                }
14326                            }
14327                        }
14328                    }
14329                }
14330            } else {
14331                String msg = "Permission Denial: " + intent.getAction()
14332                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14333                        + ", uid=" + callingUid + ")"
14334                        + " requires "
14335                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14336                Slog.w(TAG, msg);
14337                throw new SecurityException(msg);
14338            }
14339
14340        // Special case for adding a package: by default turn on compatibility
14341        // mode.
14342        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14343            Uri data = intent.getData();
14344            String ssp;
14345            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14346                mCompatModePackages.handlePackageAddedLocked(ssp,
14347                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14348            }
14349        }
14350
14351        /*
14352         * If this is the time zone changed action, queue up a message that will reset the timezone
14353         * of all currently running processes. This message will get queued up before the broadcast
14354         * happens.
14355         */
14356        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14357            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14358        }
14359
14360        /*
14361         * If the user set the time, let all running processes know.
14362         */
14363        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14364            final int is24Hour = intent.getBooleanExtra(
14365                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14366            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14367        }
14368
14369        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14370            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14371        }
14372
14373        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14374            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14375            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14376        }
14377
14378        // Add to the sticky list if requested.
14379        if (sticky) {
14380            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14381                    callingPid, callingUid)
14382                    != PackageManager.PERMISSION_GRANTED) {
14383                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14384                        + callingPid + ", uid=" + callingUid
14385                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14386                Slog.w(TAG, msg);
14387                throw new SecurityException(msg);
14388            }
14389            if (requiredPermission != null) {
14390                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14391                        + " and enforce permission " + requiredPermission);
14392                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14393            }
14394            if (intent.getComponent() != null) {
14395                throw new SecurityException(
14396                        "Sticky broadcasts can't target a specific component");
14397            }
14398            // We use userId directly here, since the "all" target is maintained
14399            // as a separate set of sticky broadcasts.
14400            if (userId != UserHandle.USER_ALL) {
14401                // But first, if this is not a broadcast to all users, then
14402                // make sure it doesn't conflict with an existing broadcast to
14403                // all users.
14404                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14405                        UserHandle.USER_ALL);
14406                if (stickies != null) {
14407                    ArrayList<Intent> list = stickies.get(intent.getAction());
14408                    if (list != null) {
14409                        int N = list.size();
14410                        int i;
14411                        for (i=0; i<N; i++) {
14412                            if (intent.filterEquals(list.get(i))) {
14413                                throw new IllegalArgumentException(
14414                                        "Sticky broadcast " + intent + " for user "
14415                                        + userId + " conflicts with existing global broadcast");
14416                            }
14417                        }
14418                    }
14419                }
14420            }
14421            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14422            if (stickies == null) {
14423                stickies = new ArrayMap<String, ArrayList<Intent>>();
14424                mStickyBroadcasts.put(userId, stickies);
14425            }
14426            ArrayList<Intent> list = stickies.get(intent.getAction());
14427            if (list == null) {
14428                list = new ArrayList<Intent>();
14429                stickies.put(intent.getAction(), list);
14430            }
14431            int N = list.size();
14432            int i;
14433            for (i=0; i<N; i++) {
14434                if (intent.filterEquals(list.get(i))) {
14435                    // This sticky already exists, replace it.
14436                    list.set(i, new Intent(intent));
14437                    break;
14438                }
14439            }
14440            if (i >= N) {
14441                list.add(new Intent(intent));
14442            }
14443        }
14444
14445        int[] users;
14446        if (userId == UserHandle.USER_ALL) {
14447            // Caller wants broadcast to go to all started users.
14448            users = mStartedUserArray;
14449        } else {
14450            // Caller wants broadcast to go to one specific user.
14451            users = new int[] {userId};
14452        }
14453
14454        // Figure out who all will receive this broadcast.
14455        List receivers = null;
14456        List<BroadcastFilter> registeredReceivers = null;
14457        // Need to resolve the intent to interested receivers...
14458        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14459                 == 0) {
14460            receivers = collectReceiverComponents(intent, resolvedType, users);
14461        }
14462        if (intent.getComponent() == null) {
14463            registeredReceivers = mReceiverResolver.queryIntent(intent,
14464                    resolvedType, false, userId);
14465        }
14466
14467        final boolean replacePending =
14468                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14469
14470        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14471                + " replacePending=" + replacePending);
14472
14473        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14474        if (!ordered && NR > 0) {
14475            // If we are not serializing this broadcast, then send the
14476            // registered receivers separately so they don't wait for the
14477            // components to be launched.
14478            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14479            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14480                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14481                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14482                    ordered, sticky, false, userId);
14483            if (DEBUG_BROADCAST) Slog.v(
14484                    TAG, "Enqueueing parallel broadcast " + r);
14485            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14486            if (!replaced) {
14487                queue.enqueueParallelBroadcastLocked(r);
14488                queue.scheduleBroadcastsLocked();
14489            }
14490            registeredReceivers = null;
14491            NR = 0;
14492        }
14493
14494        // Merge into one list.
14495        int ir = 0;
14496        if (receivers != null) {
14497            // A special case for PACKAGE_ADDED: do not allow the package
14498            // being added to see this broadcast.  This prevents them from
14499            // using this as a back door to get run as soon as they are
14500            // installed.  Maybe in the future we want to have a special install
14501            // broadcast or such for apps, but we'd like to deliberately make
14502            // this decision.
14503            String skipPackages[] = null;
14504            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14505                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14506                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14507                Uri data = intent.getData();
14508                if (data != null) {
14509                    String pkgName = data.getSchemeSpecificPart();
14510                    if (pkgName != null) {
14511                        skipPackages = new String[] { pkgName };
14512                    }
14513                }
14514            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14515                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14516            }
14517            if (skipPackages != null && (skipPackages.length > 0)) {
14518                for (String skipPackage : skipPackages) {
14519                    if (skipPackage != null) {
14520                        int NT = receivers.size();
14521                        for (int it=0; it<NT; it++) {
14522                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14523                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14524                                receivers.remove(it);
14525                                it--;
14526                                NT--;
14527                            }
14528                        }
14529                    }
14530                }
14531            }
14532
14533            int NT = receivers != null ? receivers.size() : 0;
14534            int it = 0;
14535            ResolveInfo curt = null;
14536            BroadcastFilter curr = null;
14537            while (it < NT && ir < NR) {
14538                if (curt == null) {
14539                    curt = (ResolveInfo)receivers.get(it);
14540                }
14541                if (curr == null) {
14542                    curr = registeredReceivers.get(ir);
14543                }
14544                if (curr.getPriority() >= curt.priority) {
14545                    // Insert this broadcast record into the final list.
14546                    receivers.add(it, curr);
14547                    ir++;
14548                    curr = null;
14549                    it++;
14550                    NT++;
14551                } else {
14552                    // Skip to the next ResolveInfo in the final list.
14553                    it++;
14554                    curt = null;
14555                }
14556            }
14557        }
14558        while (ir < NR) {
14559            if (receivers == null) {
14560                receivers = new ArrayList();
14561            }
14562            receivers.add(registeredReceivers.get(ir));
14563            ir++;
14564        }
14565
14566        if ((receivers != null && receivers.size() > 0)
14567                || resultTo != null) {
14568            BroadcastQueue queue = broadcastQueueForIntent(intent);
14569            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14570                    callerPackage, callingPid, callingUid, resolvedType,
14571                    requiredPermission, appOp, receivers, resultTo, resultCode,
14572                    resultData, map, ordered, sticky, false, userId);
14573            if (DEBUG_BROADCAST) Slog.v(
14574                    TAG, "Enqueueing ordered broadcast " + r
14575                    + ": prev had " + queue.mOrderedBroadcasts.size());
14576            if (DEBUG_BROADCAST) {
14577                int seq = r.intent.getIntExtra("seq", -1);
14578                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14579            }
14580            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14581            if (!replaced) {
14582                queue.enqueueOrderedBroadcastLocked(r);
14583                queue.scheduleBroadcastsLocked();
14584            }
14585        }
14586
14587        return ActivityManager.BROADCAST_SUCCESS;
14588    }
14589
14590    final Intent verifyBroadcastLocked(Intent intent) {
14591        // Refuse possible leaked file descriptors
14592        if (intent != null && intent.hasFileDescriptors() == true) {
14593            throw new IllegalArgumentException("File descriptors passed in Intent");
14594        }
14595
14596        int flags = intent.getFlags();
14597
14598        if (!mProcessesReady) {
14599            // if the caller really truly claims to know what they're doing, go
14600            // ahead and allow the broadcast without launching any receivers
14601            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14602                intent = new Intent(intent);
14603                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14604            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14605                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14606                        + " before boot completion");
14607                throw new IllegalStateException("Cannot broadcast before boot completed");
14608            }
14609        }
14610
14611        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14612            throw new IllegalArgumentException(
14613                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14614        }
14615
14616        return intent;
14617    }
14618
14619    public final int broadcastIntent(IApplicationThread caller,
14620            Intent intent, String resolvedType, IIntentReceiver resultTo,
14621            int resultCode, String resultData, Bundle map,
14622            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14623        enforceNotIsolatedCaller("broadcastIntent");
14624        synchronized(this) {
14625            intent = verifyBroadcastLocked(intent);
14626
14627            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14628            final int callingPid = Binder.getCallingPid();
14629            final int callingUid = Binder.getCallingUid();
14630            final long origId = Binder.clearCallingIdentity();
14631            int res = broadcastIntentLocked(callerApp,
14632                    callerApp != null ? callerApp.info.packageName : null,
14633                    intent, resolvedType, resultTo,
14634                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14635                    callingPid, callingUid, userId);
14636            Binder.restoreCallingIdentity(origId);
14637            return res;
14638        }
14639    }
14640
14641    int broadcastIntentInPackage(String packageName, int uid,
14642            Intent intent, String resolvedType, IIntentReceiver resultTo,
14643            int resultCode, String resultData, Bundle map,
14644            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14645        synchronized(this) {
14646            intent = verifyBroadcastLocked(intent);
14647
14648            final long origId = Binder.clearCallingIdentity();
14649            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14650                    resultTo, resultCode, resultData, map, requiredPermission,
14651                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14652            Binder.restoreCallingIdentity(origId);
14653            return res;
14654        }
14655    }
14656
14657    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14658        // Refuse possible leaked file descriptors
14659        if (intent != null && intent.hasFileDescriptors() == true) {
14660            throw new IllegalArgumentException("File descriptors passed in Intent");
14661        }
14662
14663        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14664                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
14665
14666        synchronized(this) {
14667            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14668                    != PackageManager.PERMISSION_GRANTED) {
14669                String msg = "Permission Denial: unbroadcastIntent() from pid="
14670                        + Binder.getCallingPid()
14671                        + ", uid=" + Binder.getCallingUid()
14672                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14673                Slog.w(TAG, msg);
14674                throw new SecurityException(msg);
14675            }
14676            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14677            if (stickies != null) {
14678                ArrayList<Intent> list = stickies.get(intent.getAction());
14679                if (list != null) {
14680                    int N = list.size();
14681                    int i;
14682                    for (i=0; i<N; i++) {
14683                        if (intent.filterEquals(list.get(i))) {
14684                            list.remove(i);
14685                            break;
14686                        }
14687                    }
14688                    if (list.size() <= 0) {
14689                        stickies.remove(intent.getAction());
14690                    }
14691                }
14692                if (stickies.size() <= 0) {
14693                    mStickyBroadcasts.remove(userId);
14694                }
14695            }
14696        }
14697    }
14698
14699    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14700            String resultData, Bundle resultExtras, boolean resultAbort) {
14701        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14702        if (r == null) {
14703            Slog.w(TAG, "finishReceiver called but not found on queue");
14704            return false;
14705        }
14706
14707        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14708    }
14709
14710    void backgroundServicesFinishedLocked(int userId) {
14711        for (BroadcastQueue queue : mBroadcastQueues) {
14712            queue.backgroundServicesFinishedLocked(userId);
14713        }
14714    }
14715
14716    public void finishReceiver(IBinder who, int resultCode, String resultData,
14717            Bundle resultExtras, boolean resultAbort) {
14718        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14719
14720        // Refuse possible leaked file descriptors
14721        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14722            throw new IllegalArgumentException("File descriptors passed in Bundle");
14723        }
14724
14725        final long origId = Binder.clearCallingIdentity();
14726        try {
14727            boolean doNext = false;
14728            BroadcastRecord r;
14729
14730            synchronized(this) {
14731                r = broadcastRecordForReceiverLocked(who);
14732                if (r != null) {
14733                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14734                        resultData, resultExtras, resultAbort, true);
14735                }
14736            }
14737
14738            if (doNext) {
14739                r.queue.processNextBroadcast(false);
14740            }
14741            trimApplications();
14742        } finally {
14743            Binder.restoreCallingIdentity(origId);
14744        }
14745    }
14746
14747    // =========================================================
14748    // INSTRUMENTATION
14749    // =========================================================
14750
14751    public boolean startInstrumentation(ComponentName className,
14752            String profileFile, int flags, Bundle arguments,
14753            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14754            int userId, String abiOverride) {
14755        enforceNotIsolatedCaller("startInstrumentation");
14756        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14757                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
14758        // Refuse possible leaked file descriptors
14759        if (arguments != null && arguments.hasFileDescriptors()) {
14760            throw new IllegalArgumentException("File descriptors passed in Bundle");
14761        }
14762
14763        synchronized(this) {
14764            InstrumentationInfo ii = null;
14765            ApplicationInfo ai = null;
14766            try {
14767                ii = mContext.getPackageManager().getInstrumentationInfo(
14768                    className, STOCK_PM_FLAGS);
14769                ai = AppGlobals.getPackageManager().getApplicationInfo(
14770                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14771            } catch (PackageManager.NameNotFoundException e) {
14772            } catch (RemoteException e) {
14773            }
14774            if (ii == null) {
14775                reportStartInstrumentationFailure(watcher, className,
14776                        "Unable to find instrumentation info for: " + className);
14777                return false;
14778            }
14779            if (ai == null) {
14780                reportStartInstrumentationFailure(watcher, className,
14781                        "Unable to find instrumentation target package: " + ii.targetPackage);
14782                return false;
14783            }
14784
14785            int match = mContext.getPackageManager().checkSignatures(
14786                    ii.targetPackage, ii.packageName);
14787            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14788                String msg = "Permission Denial: starting instrumentation "
14789                        + className + " from pid="
14790                        + Binder.getCallingPid()
14791                        + ", uid=" + Binder.getCallingPid()
14792                        + " not allowed because package " + ii.packageName
14793                        + " does not have a signature matching the target "
14794                        + ii.targetPackage;
14795                reportStartInstrumentationFailure(watcher, className, msg);
14796                throw new SecurityException(msg);
14797            }
14798
14799            final long origId = Binder.clearCallingIdentity();
14800            // Instrumentation can kill and relaunch even persistent processes
14801            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14802                    "start instr");
14803            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14804            app.instrumentationClass = className;
14805            app.instrumentationInfo = ai;
14806            app.instrumentationProfileFile = profileFile;
14807            app.instrumentationArguments = arguments;
14808            app.instrumentationWatcher = watcher;
14809            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14810            app.instrumentationResultClass = className;
14811            Binder.restoreCallingIdentity(origId);
14812        }
14813
14814        return true;
14815    }
14816
14817    /**
14818     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14819     * error to the logs, but if somebody is watching, send the report there too.  This enables
14820     * the "am" command to report errors with more information.
14821     *
14822     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14823     * @param cn The component name of the instrumentation.
14824     * @param report The error report.
14825     */
14826    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14827            ComponentName cn, String report) {
14828        Slog.w(TAG, report);
14829        try {
14830            if (watcher != null) {
14831                Bundle results = new Bundle();
14832                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14833                results.putString("Error", report);
14834                watcher.instrumentationStatus(cn, -1, results);
14835            }
14836        } catch (RemoteException e) {
14837            Slog.w(TAG, e);
14838        }
14839    }
14840
14841    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14842        if (app.instrumentationWatcher != null) {
14843            try {
14844                // NOTE:  IInstrumentationWatcher *must* be oneway here
14845                app.instrumentationWatcher.instrumentationFinished(
14846                    app.instrumentationClass,
14847                    resultCode,
14848                    results);
14849            } catch (RemoteException e) {
14850            }
14851        }
14852        if (app.instrumentationUiAutomationConnection != null) {
14853            try {
14854                app.instrumentationUiAutomationConnection.shutdown();
14855            } catch (RemoteException re) {
14856                /* ignore */
14857            }
14858            // Only a UiAutomation can set this flag and now that
14859            // it is finished we make sure it is reset to its default.
14860            mUserIsMonkey = false;
14861        }
14862        app.instrumentationWatcher = null;
14863        app.instrumentationUiAutomationConnection = null;
14864        app.instrumentationClass = null;
14865        app.instrumentationInfo = null;
14866        app.instrumentationProfileFile = null;
14867        app.instrumentationArguments = null;
14868
14869        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14870                "finished inst");
14871    }
14872
14873    public void finishInstrumentation(IApplicationThread target,
14874            int resultCode, Bundle results) {
14875        int userId = UserHandle.getCallingUserId();
14876        // Refuse possible leaked file descriptors
14877        if (results != null && results.hasFileDescriptors()) {
14878            throw new IllegalArgumentException("File descriptors passed in Intent");
14879        }
14880
14881        synchronized(this) {
14882            ProcessRecord app = getRecordForAppLocked(target);
14883            if (app == null) {
14884                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14885                return;
14886            }
14887            final long origId = Binder.clearCallingIdentity();
14888            finishInstrumentationLocked(app, resultCode, results);
14889            Binder.restoreCallingIdentity(origId);
14890        }
14891    }
14892
14893    // =========================================================
14894    // CONFIGURATION
14895    // =========================================================
14896
14897    public ConfigurationInfo getDeviceConfigurationInfo() {
14898        ConfigurationInfo config = new ConfigurationInfo();
14899        synchronized (this) {
14900            config.reqTouchScreen = mConfiguration.touchscreen;
14901            config.reqKeyboardType = mConfiguration.keyboard;
14902            config.reqNavigation = mConfiguration.navigation;
14903            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14904                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14905                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14906            }
14907            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14908                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14909                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14910            }
14911            config.reqGlEsVersion = GL_ES_VERSION;
14912        }
14913        return config;
14914    }
14915
14916    ActivityStack getFocusedStack() {
14917        return mStackSupervisor.getFocusedStack();
14918    }
14919
14920    public Configuration getConfiguration() {
14921        Configuration ci;
14922        synchronized(this) {
14923            ci = new Configuration(mConfiguration);
14924        }
14925        return ci;
14926    }
14927
14928    public void updatePersistentConfiguration(Configuration values) {
14929        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14930                "updateConfiguration()");
14931        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14932                "updateConfiguration()");
14933        if (values == null) {
14934            throw new NullPointerException("Configuration must not be null");
14935        }
14936
14937        synchronized(this) {
14938            final long origId = Binder.clearCallingIdentity();
14939            updateConfigurationLocked(values, null, true, false);
14940            Binder.restoreCallingIdentity(origId);
14941        }
14942    }
14943
14944    public void updateConfiguration(Configuration values) {
14945        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14946                "updateConfiguration()");
14947
14948        synchronized(this) {
14949            if (values == null && mWindowManager != null) {
14950                // sentinel: fetch the current configuration from the window manager
14951                values = mWindowManager.computeNewConfiguration();
14952            }
14953
14954            if (mWindowManager != null) {
14955                mProcessList.applyDisplaySize(mWindowManager);
14956            }
14957
14958            final long origId = Binder.clearCallingIdentity();
14959            if (values != null) {
14960                Settings.System.clearConfiguration(values);
14961            }
14962            updateConfigurationLocked(values, null, false, false);
14963            Binder.restoreCallingIdentity(origId);
14964        }
14965    }
14966
14967    /**
14968     * Do either or both things: (1) change the current configuration, and (2)
14969     * make sure the given activity is running with the (now) current
14970     * configuration.  Returns true if the activity has been left running, or
14971     * false if <var>starting</var> is being destroyed to match the new
14972     * configuration.
14973     * @param persistent TODO
14974     */
14975    boolean updateConfigurationLocked(Configuration values,
14976            ActivityRecord starting, boolean persistent, boolean initLocale) {
14977        int changes = 0;
14978
14979        if (values != null) {
14980            Configuration newConfig = new Configuration(mConfiguration);
14981            changes = newConfig.updateFrom(values);
14982            if (changes != 0) {
14983                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14984                    Slog.i(TAG, "Updating configuration to: " + values);
14985                }
14986
14987                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14988
14989                if (values.locale != null && !initLocale) {
14990                    saveLocaleLocked(values.locale,
14991                                     !values.locale.equals(mConfiguration.locale),
14992                                     values.userSetLocale);
14993                }
14994
14995                mConfigurationSeq++;
14996                if (mConfigurationSeq <= 0) {
14997                    mConfigurationSeq = 1;
14998                }
14999                newConfig.seq = mConfigurationSeq;
15000                mConfiguration = newConfig;
15001                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15002                mUsageStatsService.noteStartConfig(newConfig);
15003
15004                final Configuration configCopy = new Configuration(mConfiguration);
15005
15006                // TODO: If our config changes, should we auto dismiss any currently
15007                // showing dialogs?
15008                mShowDialogs = shouldShowDialogs(newConfig);
15009
15010                AttributeCache ac = AttributeCache.instance();
15011                if (ac != null) {
15012                    ac.updateConfiguration(configCopy);
15013                }
15014
15015                // Make sure all resources in our process are updated
15016                // right now, so that anyone who is going to retrieve
15017                // resource values after we return will be sure to get
15018                // the new ones.  This is especially important during
15019                // boot, where the first config change needs to guarantee
15020                // all resources have that config before following boot
15021                // code is executed.
15022                mSystemThread.applyConfigurationToResources(configCopy);
15023
15024                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15025                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15026                    msg.obj = new Configuration(configCopy);
15027                    mHandler.sendMessage(msg);
15028                }
15029
15030                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15031                    ProcessRecord app = mLruProcesses.get(i);
15032                    try {
15033                        if (app.thread != null) {
15034                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15035                                    + app.processName + " new config " + mConfiguration);
15036                            app.thread.scheduleConfigurationChanged(configCopy);
15037                        }
15038                    } catch (Exception e) {
15039                    }
15040                }
15041                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15042                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15043                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15044                        | Intent.FLAG_RECEIVER_FOREGROUND);
15045                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15046                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15047                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15048                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15049                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15050                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15051                    broadcastIntentLocked(null, null, intent,
15052                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15053                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15054                }
15055            }
15056        }
15057
15058        boolean kept = true;
15059        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15060        // mainStack is null during startup.
15061        if (mainStack != null) {
15062            if (changes != 0 && starting == null) {
15063                // If the configuration changed, and the caller is not already
15064                // in the process of starting an activity, then find the top
15065                // activity to check if its configuration needs to change.
15066                starting = mainStack.topRunningActivityLocked(null);
15067            }
15068
15069            if (starting != null) {
15070                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15071                // And we need to make sure at this point that all other activities
15072                // are made visible with the correct configuration.
15073                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15074            }
15075        }
15076
15077        if (values != null && mWindowManager != null) {
15078            mWindowManager.setNewConfiguration(mConfiguration);
15079        }
15080
15081        return kept;
15082    }
15083
15084    /**
15085     * Decide based on the configuration whether we should shouw the ANR,
15086     * crash, etc dialogs.  The idea is that if there is no affordnace to
15087     * press the on-screen buttons, we shouldn't show the dialog.
15088     *
15089     * A thought: SystemUI might also want to get told about this, the Power
15090     * dialog / global actions also might want different behaviors.
15091     */
15092    private static final boolean shouldShowDialogs(Configuration config) {
15093        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15094                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15095    }
15096
15097    /**
15098     * Save the locale.  You must be inside a synchronized (this) block.
15099     */
15100    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15101        if(isDiff) {
15102            SystemProperties.set("user.language", l.getLanguage());
15103            SystemProperties.set("user.region", l.getCountry());
15104        }
15105
15106        if(isPersist) {
15107            SystemProperties.set("persist.sys.language", l.getLanguage());
15108            SystemProperties.set("persist.sys.country", l.getCountry());
15109            SystemProperties.set("persist.sys.localevar", l.getVariant());
15110        }
15111    }
15112
15113    @Override
15114    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
15115        ActivityRecord srec = ActivityRecord.forToken(token);
15116        return srec != null && srec.task.affinity != null &&
15117                srec.task.affinity.equals(destAffinity);
15118    }
15119
15120    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15121            Intent resultData) {
15122
15123        synchronized (this) {
15124            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15125            if (stack != null) {
15126                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15127            }
15128            return false;
15129        }
15130    }
15131
15132    public int getLaunchedFromUid(IBinder activityToken) {
15133        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15134        if (srec == null) {
15135            return -1;
15136        }
15137        return srec.launchedFromUid;
15138    }
15139
15140    public String getLaunchedFromPackage(IBinder activityToken) {
15141        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15142        if (srec == null) {
15143            return null;
15144        }
15145        return srec.launchedFromPackage;
15146    }
15147
15148    // =========================================================
15149    // LIFETIME MANAGEMENT
15150    // =========================================================
15151
15152    // Returns which broadcast queue the app is the current [or imminent] receiver
15153    // on, or 'null' if the app is not an active broadcast recipient.
15154    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
15155        BroadcastRecord r = app.curReceiver;
15156        if (r != null) {
15157            return r.queue;
15158        }
15159
15160        // It's not the current receiver, but it might be starting up to become one
15161        synchronized (this) {
15162            for (BroadcastQueue queue : mBroadcastQueues) {
15163                r = queue.mPendingBroadcast;
15164                if (r != null && r.curApp == app) {
15165                    // found it; report which queue it's in
15166                    return queue;
15167                }
15168            }
15169        }
15170
15171        return null;
15172    }
15173
15174    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
15175            boolean doingAll, long now) {
15176        if (mAdjSeq == app.adjSeq) {
15177            // This adjustment has already been computed.
15178            return app.curRawAdj;
15179        }
15180
15181        if (app.thread == null) {
15182            app.adjSeq = mAdjSeq;
15183            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15184            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15185            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
15186        }
15187
15188        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
15189        app.adjSource = null;
15190        app.adjTarget = null;
15191        app.empty = false;
15192        app.cached = false;
15193
15194        final int activitiesSize = app.activities.size();
15195
15196        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15197            // The max adjustment doesn't allow this app to be anything
15198            // below foreground, so it is not worth doing work for it.
15199            app.adjType = "fixed";
15200            app.adjSeq = mAdjSeq;
15201            app.curRawAdj = app.maxAdj;
15202            app.foregroundActivities = false;
15203            app.keeping = true;
15204            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
15205            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
15206            // System processes can do UI, and when they do we want to have
15207            // them trim their memory after the user leaves the UI.  To
15208            // facilitate this, here we need to determine whether or not it
15209            // is currently showing UI.
15210            app.systemNoUi = true;
15211            if (app == TOP_APP) {
15212                app.systemNoUi = false;
15213            } else if (activitiesSize > 0) {
15214                for (int j = 0; j < activitiesSize; j++) {
15215                    final ActivityRecord r = app.activities.get(j);
15216                    if (r.visible) {
15217                        app.systemNoUi = false;
15218                    }
15219                }
15220            }
15221            if (!app.systemNoUi) {
15222                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15223            }
15224            return (app.curAdj=app.maxAdj);
15225        }
15226
15227        app.keeping = false;
15228        app.systemNoUi = false;
15229
15230        // Determine the importance of the process, starting with most
15231        // important to least, and assign an appropriate OOM adjustment.
15232        int adj;
15233        int schedGroup;
15234        int procState;
15235        boolean foregroundActivities = false;
15236        BroadcastQueue queue;
15237        if (app == TOP_APP) {
15238            // The last app on the list is the foreground app.
15239            adj = ProcessList.FOREGROUND_APP_ADJ;
15240            schedGroup = Process.THREAD_GROUP_DEFAULT;
15241            app.adjType = "top-activity";
15242            foregroundActivities = true;
15243            procState = ActivityManager.PROCESS_STATE_TOP;
15244        } else if (app.instrumentationClass != null) {
15245            // Don't want to kill running instrumentation.
15246            adj = ProcessList.FOREGROUND_APP_ADJ;
15247            schedGroup = Process.THREAD_GROUP_DEFAULT;
15248            app.adjType = "instrumentation";
15249            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15250        } else if ((queue = isReceivingBroadcast(app)) != null) {
15251            // An app that is currently receiving a broadcast also
15252            // counts as being in the foreground for OOM killer purposes.
15253            // It's placed in a sched group based on the nature of the
15254            // broadcast as reflected by which queue it's active in.
15255            adj = ProcessList.FOREGROUND_APP_ADJ;
15256            schedGroup = (queue == mFgBroadcastQueue)
15257                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15258            app.adjType = "broadcast";
15259            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15260        } else if (app.executingServices.size() > 0) {
15261            // An app that is currently executing a service callback also
15262            // counts as being in the foreground.
15263            adj = ProcessList.FOREGROUND_APP_ADJ;
15264            schedGroup = app.execServicesFg ?
15265                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15266            app.adjType = "exec-service";
15267            procState = ActivityManager.PROCESS_STATE_SERVICE;
15268            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15269        } else {
15270            // As far as we know the process is empty.  We may change our mind later.
15271            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15272            // At this point we don't actually know the adjustment.  Use the cached adj
15273            // value that the caller wants us to.
15274            adj = cachedAdj;
15275            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15276            app.cached = true;
15277            app.empty = true;
15278            app.adjType = "cch-empty";
15279        }
15280
15281        // Examine all activities if not already foreground.
15282        if (!foregroundActivities && activitiesSize > 0) {
15283            for (int j = 0; j < activitiesSize; j++) {
15284                final ActivityRecord r = app.activities.get(j);
15285                if (r.app != app) {
15286                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15287                            + app + "?!?");
15288                    continue;
15289                }
15290                if (r.visible) {
15291                    // App has a visible activity; only upgrade adjustment.
15292                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15293                        adj = ProcessList.VISIBLE_APP_ADJ;
15294                        app.adjType = "visible";
15295                    }
15296                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15297                        procState = ActivityManager.PROCESS_STATE_TOP;
15298                    }
15299                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15300                    app.cached = false;
15301                    app.empty = false;
15302                    foregroundActivities = true;
15303                    break;
15304                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15305                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15306                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15307                        app.adjType = "pausing";
15308                    }
15309                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15310                        procState = ActivityManager.PROCESS_STATE_TOP;
15311                    }
15312                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15313                    app.cached = false;
15314                    app.empty = false;
15315                    foregroundActivities = true;
15316                } else if (r.state == ActivityState.STOPPING) {
15317                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15318                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15319                        app.adjType = "stopping";
15320                    }
15321                    // For the process state, we will at this point consider the
15322                    // process to be cached.  It will be cached either as an activity
15323                    // or empty depending on whether the activity is finishing.  We do
15324                    // this so that we can treat the process as cached for purposes of
15325                    // memory trimming (determing current memory level, trim command to
15326                    // send to process) since there can be an arbitrary number of stopping
15327                    // processes and they should soon all go into the cached state.
15328                    if (!r.finishing) {
15329                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15330                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15331                        }
15332                    }
15333                    app.cached = false;
15334                    app.empty = false;
15335                    foregroundActivities = true;
15336                } else {
15337                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15338                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15339                        app.adjType = "cch-act";
15340                    }
15341                }
15342            }
15343        }
15344
15345        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15346            if (app.foregroundServices) {
15347                // The user is aware of this app, so make it visible.
15348                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15349                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15350                app.cached = false;
15351                app.adjType = "fg-service";
15352                schedGroup = Process.THREAD_GROUP_DEFAULT;
15353            } else if (app.forcingToForeground != null) {
15354                // The user is aware of this app, so make it visible.
15355                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15356                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15357                app.cached = false;
15358                app.adjType = "force-fg";
15359                app.adjSource = app.forcingToForeground;
15360                schedGroup = Process.THREAD_GROUP_DEFAULT;
15361            }
15362        }
15363
15364        if (app == mHeavyWeightProcess) {
15365            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15366                // We don't want to kill the current heavy-weight process.
15367                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15368                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15369                app.cached = false;
15370                app.adjType = "heavy";
15371            }
15372            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15373                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15374            }
15375        }
15376
15377        if (app == mHomeProcess) {
15378            if (adj > ProcessList.HOME_APP_ADJ) {
15379                // This process is hosting what we currently consider to be the
15380                // home app, so we don't want to let it go into the background.
15381                adj = ProcessList.HOME_APP_ADJ;
15382                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15383                app.cached = false;
15384                app.adjType = "home";
15385            }
15386            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15387                procState = ActivityManager.PROCESS_STATE_HOME;
15388            }
15389        }
15390
15391        if (app == mPreviousProcess && app.activities.size() > 0) {
15392            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15393                // This was the previous process that showed UI to the user.
15394                // We want to try to keep it around more aggressively, to give
15395                // a good experience around switching between two apps.
15396                adj = ProcessList.PREVIOUS_APP_ADJ;
15397                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15398                app.cached = false;
15399                app.adjType = "previous";
15400            }
15401            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15402                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15403            }
15404        }
15405
15406        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15407                + " reason=" + app.adjType);
15408
15409        // By default, we use the computed adjustment.  It may be changed if
15410        // there are applications dependent on our services or providers, but
15411        // this gives us a baseline and makes sure we don't get into an
15412        // infinite recursion.
15413        app.adjSeq = mAdjSeq;
15414        app.curRawAdj = adj;
15415        app.hasStartedServices = false;
15416
15417        if (mBackupTarget != null && app == mBackupTarget.app) {
15418            // If possible we want to avoid killing apps while they're being backed up
15419            if (adj > ProcessList.BACKUP_APP_ADJ) {
15420                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15421                adj = ProcessList.BACKUP_APP_ADJ;
15422                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15423                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15424                }
15425                app.adjType = "backup";
15426                app.cached = false;
15427            }
15428            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15429                procState = ActivityManager.PROCESS_STATE_BACKUP;
15430            }
15431        }
15432
15433        boolean mayBeTop = false;
15434
15435        for (int is = app.services.size()-1;
15436                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15437                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15438                        || procState > ActivityManager.PROCESS_STATE_TOP);
15439                is--) {
15440            ServiceRecord s = app.services.valueAt(is);
15441            if (s.startRequested) {
15442                app.hasStartedServices = true;
15443                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15444                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15445                }
15446                if (app.hasShownUi && app != mHomeProcess) {
15447                    // If this process has shown some UI, let it immediately
15448                    // go to the LRU list because it may be pretty heavy with
15449                    // UI stuff.  We'll tag it with a label just to help
15450                    // debug and understand what is going on.
15451                    if (adj > ProcessList.SERVICE_ADJ) {
15452                        app.adjType = "cch-started-ui-services";
15453                    }
15454                } else {
15455                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15456                        // This service has seen some activity within
15457                        // recent memory, so we will keep its process ahead
15458                        // of the background processes.
15459                        if (adj > ProcessList.SERVICE_ADJ) {
15460                            adj = ProcessList.SERVICE_ADJ;
15461                            app.adjType = "started-services";
15462                            app.cached = false;
15463                        }
15464                    }
15465                    // If we have let the service slide into the background
15466                    // state, still have some text describing what it is doing
15467                    // even though the service no longer has an impact.
15468                    if (adj > ProcessList.SERVICE_ADJ) {
15469                        app.adjType = "cch-started-services";
15470                    }
15471                }
15472                // Don't kill this process because it is doing work; it
15473                // has said it is doing work.
15474                app.keeping = true;
15475            }
15476            for (int conni = s.connections.size()-1;
15477                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15478                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15479                            || procState > ActivityManager.PROCESS_STATE_TOP);
15480                    conni--) {
15481                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15482                for (int i = 0;
15483                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15484                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15485                                || procState > ActivityManager.PROCESS_STATE_TOP);
15486                        i++) {
15487                    // XXX should compute this based on the max of
15488                    // all connected clients.
15489                    ConnectionRecord cr = clist.get(i);
15490                    if (cr.binding.client == app) {
15491                        // Binding to ourself is not interesting.
15492                        continue;
15493                    }
15494                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15495                        ProcessRecord client = cr.binding.client;
15496                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15497                                TOP_APP, doingAll, now);
15498                        int clientProcState = client.curProcState;
15499                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15500                            // If the other app is cached for any reason, for purposes here
15501                            // we are going to consider it empty.  The specific cached state
15502                            // doesn't propagate except under certain conditions.
15503                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15504                        }
15505                        String adjType = null;
15506                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15507                            // Not doing bind OOM management, so treat
15508                            // this guy more like a started service.
15509                            if (app.hasShownUi && app != mHomeProcess) {
15510                                // If this process has shown some UI, let it immediately
15511                                // go to the LRU list because it may be pretty heavy with
15512                                // UI stuff.  We'll tag it with a label just to help
15513                                // debug and understand what is going on.
15514                                if (adj > clientAdj) {
15515                                    adjType = "cch-bound-ui-services";
15516                                }
15517                                app.cached = false;
15518                                clientAdj = adj;
15519                                clientProcState = procState;
15520                            } else {
15521                                if (now >= (s.lastActivity
15522                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15523                                    // This service has not seen activity within
15524                                    // recent memory, so allow it to drop to the
15525                                    // LRU list if there is no other reason to keep
15526                                    // it around.  We'll also tag it with a label just
15527                                    // to help debug and undertand what is going on.
15528                                    if (adj > clientAdj) {
15529                                        adjType = "cch-bound-services";
15530                                    }
15531                                    clientAdj = adj;
15532                                }
15533                            }
15534                        }
15535                        if (adj > clientAdj) {
15536                            // If this process has recently shown UI, and
15537                            // the process that is binding to it is less
15538                            // important than being visible, then we don't
15539                            // care about the binding as much as we care
15540                            // about letting this process get into the LRU
15541                            // list to be killed and restarted if needed for
15542                            // memory.
15543                            if (app.hasShownUi && app != mHomeProcess
15544                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15545                                adjType = "cch-bound-ui-services";
15546                            } else {
15547                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15548                                        |Context.BIND_IMPORTANT)) != 0) {
15549                                    adj = clientAdj;
15550                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15551                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15552                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15553                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15554                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15555                                    adj = clientAdj;
15556                                } else {
15557                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15558                                        adj = ProcessList.VISIBLE_APP_ADJ;
15559                                    }
15560                                }
15561                                if (!client.cached) {
15562                                    app.cached = false;
15563                                }
15564                                if (client.keeping) {
15565                                    app.keeping = true;
15566                                }
15567                                adjType = "service";
15568                            }
15569                        }
15570                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15571                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15572                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15573                            }
15574                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15575                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15576                                    // Special handling of clients who are in the top state.
15577                                    // We *may* want to consider this process to be in the
15578                                    // top state as well, but only if there is not another
15579                                    // reason for it to be running.  Being on the top is a
15580                                    // special state, meaning you are specifically running
15581                                    // for the current top app.  If the process is already
15582                                    // running in the background for some other reason, it
15583                                    // is more important to continue considering it to be
15584                                    // in the background state.
15585                                    mayBeTop = true;
15586                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15587                                } else {
15588                                    // Special handling for above-top states (persistent
15589                                    // processes).  These should not bring the current process
15590                                    // into the top state, since they are not on top.  Instead
15591                                    // give them the best state after that.
15592                                    clientProcState =
15593                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15594                                }
15595                            }
15596                        } else {
15597                            if (clientProcState <
15598                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15599                                clientProcState =
15600                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15601                            }
15602                        }
15603                        if (procState > clientProcState) {
15604                            procState = clientProcState;
15605                        }
15606                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15607                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15608                            app.pendingUiClean = true;
15609                        }
15610                        if (adjType != null) {
15611                            app.adjType = adjType;
15612                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15613                                    .REASON_SERVICE_IN_USE;
15614                            app.adjSource = cr.binding.client;
15615                            app.adjSourceOom = clientAdj;
15616                            app.adjTarget = s.name;
15617                        }
15618                    }
15619                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15620                        app.treatLikeActivity = true;
15621                    }
15622                    final ActivityRecord a = cr.activity;
15623                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15624                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15625                                (a.visible || a.state == ActivityState.RESUMED
15626                                 || a.state == ActivityState.PAUSING)) {
15627                            adj = ProcessList.FOREGROUND_APP_ADJ;
15628                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15629                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15630                            }
15631                            app.cached = false;
15632                            app.adjType = "service";
15633                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15634                                    .REASON_SERVICE_IN_USE;
15635                            app.adjSource = a;
15636                            app.adjSourceOom = adj;
15637                            app.adjTarget = s.name;
15638                        }
15639                    }
15640                }
15641            }
15642        }
15643
15644        for (int provi = app.pubProviders.size()-1;
15645                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15646                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15647                        || procState > ActivityManager.PROCESS_STATE_TOP);
15648                provi--) {
15649            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15650            for (int i = cpr.connections.size()-1;
15651                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15652                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15653                            || procState > ActivityManager.PROCESS_STATE_TOP);
15654                    i--) {
15655                ContentProviderConnection conn = cpr.connections.get(i);
15656                ProcessRecord client = conn.client;
15657                if (client == app) {
15658                    // Being our own client is not interesting.
15659                    continue;
15660                }
15661                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15662                int clientProcState = client.curProcState;
15663                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15664                    // If the other app is cached for any reason, for purposes here
15665                    // we are going to consider it empty.
15666                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15667                }
15668                if (adj > clientAdj) {
15669                    if (app.hasShownUi && app != mHomeProcess
15670                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15671                        app.adjType = "cch-ui-provider";
15672                    } else {
15673                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15674                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15675                        app.adjType = "provider";
15676                    }
15677                    app.cached &= client.cached;
15678                    app.keeping |= client.keeping;
15679                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15680                            .REASON_PROVIDER_IN_USE;
15681                    app.adjSource = client;
15682                    app.adjSourceOom = clientAdj;
15683                    app.adjTarget = cpr.name;
15684                }
15685                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15686                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15687                        // Special handling of clients who are in the top state.
15688                        // We *may* want to consider this process to be in the
15689                        // top state as well, but only if there is not another
15690                        // reason for it to be running.  Being on the top is a
15691                        // special state, meaning you are specifically running
15692                        // for the current top app.  If the process is already
15693                        // running in the background for some other reason, it
15694                        // is more important to continue considering it to be
15695                        // in the background state.
15696                        mayBeTop = true;
15697                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15698                    } else {
15699                        // Special handling for above-top states (persistent
15700                        // processes).  These should not bring the current process
15701                        // into the top state, since they are not on top.  Instead
15702                        // give them the best state after that.
15703                        clientProcState =
15704                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15705                    }
15706                }
15707                if (procState > clientProcState) {
15708                    procState = clientProcState;
15709                }
15710                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15711                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15712                }
15713            }
15714            // If the provider has external (non-framework) process
15715            // dependencies, ensure that its adjustment is at least
15716            // FOREGROUND_APP_ADJ.
15717            if (cpr.hasExternalProcessHandles()) {
15718                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15719                    adj = ProcessList.FOREGROUND_APP_ADJ;
15720                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15721                    app.cached = false;
15722                    app.keeping = true;
15723                    app.adjType = "provider";
15724                    app.adjTarget = cpr.name;
15725                }
15726                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15727                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15728                }
15729            }
15730        }
15731
15732        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15733            // A client of one of our services or providers is in the top state.  We
15734            // *may* want to be in the top state, but not if we are already running in
15735            // the background for some other reason.  For the decision here, we are going
15736            // to pick out a few specific states that we want to remain in when a client
15737            // is top (states that tend to be longer-term) and otherwise allow it to go
15738            // to the top state.
15739            switch (procState) {
15740                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15741                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15742                case ActivityManager.PROCESS_STATE_SERVICE:
15743                    // These all are longer-term states, so pull them up to the top
15744                    // of the background states, but not all the way to the top state.
15745                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15746                    break;
15747                default:
15748                    // Otherwise, top is a better choice, so take it.
15749                    procState = ActivityManager.PROCESS_STATE_TOP;
15750                    break;
15751            }
15752        }
15753
15754        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15755            if (app.hasClientActivities) {
15756                // This is a cached process, but with client activities.  Mark it so.
15757                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15758                app.adjType = "cch-client-act";
15759            } else if (app.treatLikeActivity) {
15760                // This is a cached process, but somebody wants us to treat it like it has
15761                // an activity, okay!
15762                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15763                app.adjType = "cch-as-act";
15764            }
15765        }
15766
15767        if (adj == ProcessList.SERVICE_ADJ) {
15768            if (doingAll) {
15769                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15770                mNewNumServiceProcs++;
15771                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15772                if (!app.serviceb) {
15773                    // This service isn't far enough down on the LRU list to
15774                    // normally be a B service, but if we are low on RAM and it
15775                    // is large we want to force it down since we would prefer to
15776                    // keep launcher over it.
15777                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15778                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15779                        app.serviceHighRam = true;
15780                        app.serviceb = true;
15781                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15782                    } else {
15783                        mNewNumAServiceProcs++;
15784                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15785                    }
15786                } else {
15787                    app.serviceHighRam = false;
15788                }
15789            }
15790            if (app.serviceb) {
15791                adj = ProcessList.SERVICE_B_ADJ;
15792            }
15793        }
15794
15795        app.curRawAdj = adj;
15796
15797        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15798        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15799        if (adj > app.maxAdj) {
15800            adj = app.maxAdj;
15801            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15802                schedGroup = Process.THREAD_GROUP_DEFAULT;
15803            }
15804        }
15805        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15806            app.keeping = true;
15807        }
15808
15809        // Do final modification to adj.  Everything we do between here and applying
15810        // the final setAdj must be done in this function, because we will also use
15811        // it when computing the final cached adj later.  Note that we don't need to
15812        // worry about this for max adj above, since max adj will always be used to
15813        // keep it out of the cached vaues.
15814        app.curAdj = app.modifyRawOomAdj(adj);
15815        app.curSchedGroup = schedGroup;
15816        app.curProcState = procState;
15817        app.foregroundActivities = foregroundActivities;
15818
15819        return app.curRawAdj;
15820    }
15821
15822    /**
15823     * Schedule PSS collection of a process.
15824     */
15825    void requestPssLocked(ProcessRecord proc, int procState) {
15826        if (mPendingPssProcesses.contains(proc)) {
15827            return;
15828        }
15829        if (mPendingPssProcesses.size() == 0) {
15830            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15831        }
15832        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15833        proc.pssProcState = procState;
15834        mPendingPssProcesses.add(proc);
15835    }
15836
15837    /**
15838     * Schedule PSS collection of all processes.
15839     */
15840    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15841        if (!always) {
15842            if (now < (mLastFullPssTime +
15843                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15844                return;
15845            }
15846        }
15847        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15848        mLastFullPssTime = now;
15849        mFullPssPending = true;
15850        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15851        mPendingPssProcesses.clear();
15852        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15853            ProcessRecord app = mLruProcesses.get(i);
15854            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15855                app.pssProcState = app.setProcState;
15856                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15857                        isSleeping(), now);
15858                mPendingPssProcesses.add(app);
15859            }
15860        }
15861        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15862    }
15863
15864    /**
15865     * Ask a given process to GC right now.
15866     */
15867    final void performAppGcLocked(ProcessRecord app) {
15868        try {
15869            app.lastRequestedGc = SystemClock.uptimeMillis();
15870            if (app.thread != null) {
15871                if (app.reportLowMemory) {
15872                    app.reportLowMemory = false;
15873                    app.thread.scheduleLowMemory();
15874                } else {
15875                    app.thread.processInBackground();
15876                }
15877            }
15878        } catch (Exception e) {
15879            // whatever.
15880        }
15881    }
15882
15883    /**
15884     * Returns true if things are idle enough to perform GCs.
15885     */
15886    private final boolean canGcNowLocked() {
15887        boolean processingBroadcasts = false;
15888        for (BroadcastQueue q : mBroadcastQueues) {
15889            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15890                processingBroadcasts = true;
15891            }
15892        }
15893        return !processingBroadcasts
15894                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15895    }
15896
15897    /**
15898     * Perform GCs on all processes that are waiting for it, but only
15899     * if things are idle.
15900     */
15901    final void performAppGcsLocked() {
15902        final int N = mProcessesToGc.size();
15903        if (N <= 0) {
15904            return;
15905        }
15906        if (canGcNowLocked()) {
15907            while (mProcessesToGc.size() > 0) {
15908                ProcessRecord proc = mProcessesToGc.remove(0);
15909                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15910                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15911                            <= SystemClock.uptimeMillis()) {
15912                        // To avoid spamming the system, we will GC processes one
15913                        // at a time, waiting a few seconds between each.
15914                        performAppGcLocked(proc);
15915                        scheduleAppGcsLocked();
15916                        return;
15917                    } else {
15918                        // It hasn't been long enough since we last GCed this
15919                        // process...  put it in the list to wait for its time.
15920                        addProcessToGcListLocked(proc);
15921                        break;
15922                    }
15923                }
15924            }
15925
15926            scheduleAppGcsLocked();
15927        }
15928    }
15929
15930    /**
15931     * If all looks good, perform GCs on all processes waiting for them.
15932     */
15933    final void performAppGcsIfAppropriateLocked() {
15934        if (canGcNowLocked()) {
15935            performAppGcsLocked();
15936            return;
15937        }
15938        // Still not idle, wait some more.
15939        scheduleAppGcsLocked();
15940    }
15941
15942    /**
15943     * Schedule the execution of all pending app GCs.
15944     */
15945    final void scheduleAppGcsLocked() {
15946        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15947
15948        if (mProcessesToGc.size() > 0) {
15949            // Schedule a GC for the time to the next process.
15950            ProcessRecord proc = mProcessesToGc.get(0);
15951            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15952
15953            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15954            long now = SystemClock.uptimeMillis();
15955            if (when < (now+GC_TIMEOUT)) {
15956                when = now + GC_TIMEOUT;
15957            }
15958            mHandler.sendMessageAtTime(msg, when);
15959        }
15960    }
15961
15962    /**
15963     * Add a process to the array of processes waiting to be GCed.  Keeps the
15964     * list in sorted order by the last GC time.  The process can't already be
15965     * on the list.
15966     */
15967    final void addProcessToGcListLocked(ProcessRecord proc) {
15968        boolean added = false;
15969        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15970            if (mProcessesToGc.get(i).lastRequestedGc <
15971                    proc.lastRequestedGc) {
15972                added = true;
15973                mProcessesToGc.add(i+1, proc);
15974                break;
15975            }
15976        }
15977        if (!added) {
15978            mProcessesToGc.add(0, proc);
15979        }
15980    }
15981
15982    /**
15983     * Set up to ask a process to GC itself.  This will either do it
15984     * immediately, or put it on the list of processes to gc the next
15985     * time things are idle.
15986     */
15987    final void scheduleAppGcLocked(ProcessRecord app) {
15988        long now = SystemClock.uptimeMillis();
15989        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15990            return;
15991        }
15992        if (!mProcessesToGc.contains(app)) {
15993            addProcessToGcListLocked(app);
15994            scheduleAppGcsLocked();
15995        }
15996    }
15997
15998    final void checkExcessivePowerUsageLocked(boolean doKills) {
15999        updateCpuStatsNow();
16000
16001        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16002        boolean doWakeKills = doKills;
16003        boolean doCpuKills = doKills;
16004        if (mLastPowerCheckRealtime == 0) {
16005            doWakeKills = false;
16006        }
16007        if (mLastPowerCheckUptime == 0) {
16008            doCpuKills = false;
16009        }
16010        if (stats.isScreenOn()) {
16011            doWakeKills = false;
16012        }
16013        final long curRealtime = SystemClock.elapsedRealtime();
16014        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16015        final long curUptime = SystemClock.uptimeMillis();
16016        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16017        mLastPowerCheckRealtime = curRealtime;
16018        mLastPowerCheckUptime = curUptime;
16019        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16020            doWakeKills = false;
16021        }
16022        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16023            doCpuKills = false;
16024        }
16025        int i = mLruProcesses.size();
16026        while (i > 0) {
16027            i--;
16028            ProcessRecord app = mLruProcesses.get(i);
16029            if (!app.keeping) {
16030                long wtime;
16031                synchronized (stats) {
16032                    wtime = stats.getProcessWakeTime(app.info.uid,
16033                            app.pid, curRealtime);
16034                }
16035                long wtimeUsed = wtime - app.lastWakeTime;
16036                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16037                if (DEBUG_POWER) {
16038                    StringBuilder sb = new StringBuilder(128);
16039                    sb.append("Wake for ");
16040                    app.toShortString(sb);
16041                    sb.append(": over ");
16042                    TimeUtils.formatDuration(realtimeSince, sb);
16043                    sb.append(" used ");
16044                    TimeUtils.formatDuration(wtimeUsed, sb);
16045                    sb.append(" (");
16046                    sb.append((wtimeUsed*100)/realtimeSince);
16047                    sb.append("%)");
16048                    Slog.i(TAG, sb.toString());
16049                    sb.setLength(0);
16050                    sb.append("CPU for ");
16051                    app.toShortString(sb);
16052                    sb.append(": over ");
16053                    TimeUtils.formatDuration(uptimeSince, sb);
16054                    sb.append(" used ");
16055                    TimeUtils.formatDuration(cputimeUsed, sb);
16056                    sb.append(" (");
16057                    sb.append((cputimeUsed*100)/uptimeSince);
16058                    sb.append("%)");
16059                    Slog.i(TAG, sb.toString());
16060                }
16061                // If a process has held a wake lock for more
16062                // than 50% of the time during this period,
16063                // that sounds bad.  Kill!
16064                if (doWakeKills && realtimeSince > 0
16065                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16066                    synchronized (stats) {
16067                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16068                                realtimeSince, wtimeUsed);
16069                    }
16070                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
16071                            + " during " + realtimeSince);
16072                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16073                } else if (doCpuKills && uptimeSince > 0
16074                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
16075                    synchronized (stats) {
16076                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16077                                uptimeSince, cputimeUsed);
16078                    }
16079                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
16080                            + " during " + uptimeSince);
16081                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16082                } else {
16083                    app.lastWakeTime = wtime;
16084                    app.lastCpuTime = app.curCpuTime;
16085                }
16086            }
16087        }
16088    }
16089
16090    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
16091            ProcessRecord TOP_APP, boolean doingAll, long now) {
16092        boolean success = true;
16093
16094        if (app.curRawAdj != app.setRawAdj) {
16095            if (wasKeeping && !app.keeping) {
16096                // This app is no longer something we want to keep.  Note
16097                // its current wake lock time to later know to kill it if
16098                // it is not behaving well.
16099                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16100                synchronized (stats) {
16101                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
16102                            app.pid, SystemClock.elapsedRealtime());
16103                }
16104                app.lastCpuTime = app.curCpuTime;
16105            }
16106
16107            app.setRawAdj = app.curRawAdj;
16108        }
16109
16110        int changes = 0;
16111
16112        if (app.curAdj != app.setAdj) {
16113            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16114            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16115                TAG, "Set " + app.pid + " " + app.processName +
16116                " adj " + app.curAdj + ": " + app.adjType);
16117            app.setAdj = app.curAdj;
16118        }
16119
16120        if (app.setSchedGroup != app.curSchedGroup) {
16121            app.setSchedGroup = app.curSchedGroup;
16122            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16123                    "Setting process group of " + app.processName
16124                    + " to " + app.curSchedGroup);
16125            if (app.waitingToKill != null &&
16126                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16127                killUnneededProcessLocked(app, app.waitingToKill);
16128                success = false;
16129            } else {
16130                if (true) {
16131                    long oldId = Binder.clearCallingIdentity();
16132                    try {
16133                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16134                    } catch (Exception e) {
16135                        Slog.w(TAG, "Failed setting process group of " + app.pid
16136                                + " to " + app.curSchedGroup);
16137                        e.printStackTrace();
16138                    } finally {
16139                        Binder.restoreCallingIdentity(oldId);
16140                    }
16141                } else {
16142                    if (app.thread != null) {
16143                        try {
16144                            app.thread.setSchedulingGroup(app.curSchedGroup);
16145                        } catch (RemoteException e) {
16146                        }
16147                    }
16148                }
16149                Process.setSwappiness(app.pid,
16150                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16151            }
16152        }
16153        if (app.repForegroundActivities != app.foregroundActivities) {
16154            app.repForegroundActivities = app.foregroundActivities;
16155            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16156        }
16157        if (app.repProcState != app.curProcState) {
16158            app.repProcState = app.curProcState;
16159            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16160            if (app.thread != null) {
16161                try {
16162                    if (false) {
16163                        //RuntimeException h = new RuntimeException("here");
16164                        Slog.i(TAG, "Sending new process state " + app.repProcState
16165                                + " to " + app /*, h*/);
16166                    }
16167                    app.thread.setProcessState(app.repProcState);
16168                } catch (RemoteException e) {
16169                }
16170            }
16171        }
16172        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16173                app.setProcState)) {
16174            app.lastStateTime = now;
16175            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16176                    isSleeping(), now);
16177            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16178                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16179                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16180                    + (app.nextPssTime-now) + ": " + app);
16181        } else {
16182            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16183                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16184                requestPssLocked(app, app.setProcState);
16185                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16186                        isSleeping(), now);
16187            } else if (false && DEBUG_PSS) {
16188                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16189            }
16190        }
16191        if (app.setProcState != app.curProcState) {
16192            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16193                    "Proc state change of " + app.processName
16194                    + " to " + app.curProcState);
16195            app.setProcState = app.curProcState;
16196            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16197                app.notCachedSinceIdle = false;
16198            }
16199            if (!doingAll) {
16200                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
16201            } else {
16202                app.procStateChanged = true;
16203            }
16204        }
16205
16206        if (changes != 0) {
16207            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16208            int i = mPendingProcessChanges.size()-1;
16209            ProcessChangeItem item = null;
16210            while (i >= 0) {
16211                item = mPendingProcessChanges.get(i);
16212                if (item.pid == app.pid) {
16213                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16214                    break;
16215                }
16216                i--;
16217            }
16218            if (i < 0) {
16219                // No existing item in pending changes; need a new one.
16220                final int NA = mAvailProcessChanges.size();
16221                if (NA > 0) {
16222                    item = mAvailProcessChanges.remove(NA-1);
16223                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16224                } else {
16225                    item = new ProcessChangeItem();
16226                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16227                }
16228                item.changes = 0;
16229                item.pid = app.pid;
16230                item.uid = app.info.uid;
16231                if (mPendingProcessChanges.size() == 0) {
16232                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16233                            "*** Enqueueing dispatch processes changed!");
16234                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16235                }
16236                mPendingProcessChanges.add(item);
16237            }
16238            item.changes |= changes;
16239            item.processState = app.repProcState;
16240            item.foregroundActivities = app.repForegroundActivities;
16241            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16242                    + Integer.toHexString(System.identityHashCode(item))
16243                    + " " + app.toShortString() + ": changes=" + item.changes
16244                    + " procState=" + item.processState
16245                    + " foreground=" + item.foregroundActivities
16246                    + " type=" + app.adjType + " source=" + app.adjSource
16247                    + " target=" + app.adjTarget);
16248        }
16249
16250        return success;
16251    }
16252
16253    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
16254        if (proc.thread != null) {
16255            if (proc.baseProcessTracker != null) {
16256                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16257            }
16258            if (proc.repProcState >= 0) {
16259                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
16260                        proc.repProcState);
16261            }
16262        }
16263    }
16264
16265    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16266            ProcessRecord TOP_APP, boolean doingAll, long now) {
16267        if (app.thread == null) {
16268            return false;
16269        }
16270
16271        final boolean wasKeeping = app.keeping;
16272
16273        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16274
16275        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
16276    }
16277
16278    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16279            boolean oomAdj) {
16280        if (isForeground != proc.foregroundServices) {
16281            proc.foregroundServices = isForeground;
16282            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16283                    proc.info.uid);
16284            if (isForeground) {
16285                if (curProcs == null) {
16286                    curProcs = new ArrayList<ProcessRecord>();
16287                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16288                }
16289                if (!curProcs.contains(proc)) {
16290                    curProcs.add(proc);
16291                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16292                            proc.info.packageName, proc.info.uid);
16293                }
16294            } else {
16295                if (curProcs != null) {
16296                    if (curProcs.remove(proc)) {
16297                        mBatteryStatsService.noteEvent(
16298                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16299                                proc.info.packageName, proc.info.uid);
16300                        if (curProcs.size() <= 0) {
16301                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16302                        }
16303                    }
16304                }
16305            }
16306            if (oomAdj) {
16307                updateOomAdjLocked();
16308            }
16309        }
16310    }
16311
16312    private final ActivityRecord resumedAppLocked() {
16313        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16314        String pkg;
16315        int uid;
16316        if (act != null) {
16317            pkg = act.packageName;
16318            uid = act.info.applicationInfo.uid;
16319        } else {
16320            pkg = null;
16321            uid = -1;
16322        }
16323        // Has the UID or resumed package name changed?
16324        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16325                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16326            if (mCurResumedPackage != null) {
16327                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16328                        mCurResumedPackage, mCurResumedUid);
16329            }
16330            mCurResumedPackage = pkg;
16331            mCurResumedUid = uid;
16332            if (mCurResumedPackage != null) {
16333                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16334                        mCurResumedPackage, mCurResumedUid);
16335            }
16336        }
16337        return act;
16338    }
16339
16340    final boolean updateOomAdjLocked(ProcessRecord app) {
16341        final ActivityRecord TOP_ACT = resumedAppLocked();
16342        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16343        final boolean wasCached = app.cached;
16344
16345        mAdjSeq++;
16346
16347        // This is the desired cached adjusment we want to tell it to use.
16348        // If our app is currently cached, we know it, and that is it.  Otherwise,
16349        // we don't know it yet, and it needs to now be cached we will then
16350        // need to do a complete oom adj.
16351        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16352                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16353        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16354                SystemClock.uptimeMillis());
16355        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16356            // Changed to/from cached state, so apps after it in the LRU
16357            // list may also be changed.
16358            updateOomAdjLocked();
16359        }
16360        return success;
16361    }
16362
16363    final void updateOomAdjLocked() {
16364        final ActivityRecord TOP_ACT = resumedAppLocked();
16365        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16366        final long now = SystemClock.uptimeMillis();
16367        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16368        final int N = mLruProcesses.size();
16369
16370        if (false) {
16371            RuntimeException e = new RuntimeException();
16372            e.fillInStackTrace();
16373            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16374        }
16375
16376        mAdjSeq++;
16377        mNewNumServiceProcs = 0;
16378        mNewNumAServiceProcs = 0;
16379
16380        final int emptyProcessLimit;
16381        final int cachedProcessLimit;
16382        if (mProcessLimit <= 0) {
16383            emptyProcessLimit = cachedProcessLimit = 0;
16384        } else if (mProcessLimit == 1) {
16385            emptyProcessLimit = 1;
16386            cachedProcessLimit = 0;
16387        } else {
16388            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16389            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16390        }
16391
16392        // Let's determine how many processes we have running vs.
16393        // how many slots we have for background processes; we may want
16394        // to put multiple processes in a slot of there are enough of
16395        // them.
16396        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16397                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16398        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16399        if (numEmptyProcs > cachedProcessLimit) {
16400            // If there are more empty processes than our limit on cached
16401            // processes, then use the cached process limit for the factor.
16402            // This ensures that the really old empty processes get pushed
16403            // down to the bottom, so if we are running low on memory we will
16404            // have a better chance at keeping around more cached processes
16405            // instead of a gazillion empty processes.
16406            numEmptyProcs = cachedProcessLimit;
16407        }
16408        int emptyFactor = numEmptyProcs/numSlots;
16409        if (emptyFactor < 1) emptyFactor = 1;
16410        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16411        if (cachedFactor < 1) cachedFactor = 1;
16412        int stepCached = 0;
16413        int stepEmpty = 0;
16414        int numCached = 0;
16415        int numEmpty = 0;
16416        int numTrimming = 0;
16417
16418        mNumNonCachedProcs = 0;
16419        mNumCachedHiddenProcs = 0;
16420
16421        // First update the OOM adjustment for each of the
16422        // application processes based on their current state.
16423        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16424        int nextCachedAdj = curCachedAdj+1;
16425        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16426        int nextEmptyAdj = curEmptyAdj+2;
16427        for (int i=N-1; i>=0; i--) {
16428            ProcessRecord app = mLruProcesses.get(i);
16429            if (!app.killedByAm && app.thread != null) {
16430                app.procStateChanged = false;
16431                final boolean wasKeeping = app.keeping;
16432                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16433
16434                // If we haven't yet assigned the final cached adj
16435                // to the process, do that now.
16436                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16437                    switch (app.curProcState) {
16438                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16439                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16440                            // This process is a cached process holding activities...
16441                            // assign it the next cached value for that type, and then
16442                            // step that cached level.
16443                            app.curRawAdj = curCachedAdj;
16444                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16445                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16446                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16447                                    + ")");
16448                            if (curCachedAdj != nextCachedAdj) {
16449                                stepCached++;
16450                                if (stepCached >= cachedFactor) {
16451                                    stepCached = 0;
16452                                    curCachedAdj = nextCachedAdj;
16453                                    nextCachedAdj += 2;
16454                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16455                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16456                                    }
16457                                }
16458                            }
16459                            break;
16460                        default:
16461                            // For everything else, assign next empty cached process
16462                            // level and bump that up.  Note that this means that
16463                            // long-running services that have dropped down to the
16464                            // cached level will be treated as empty (since their process
16465                            // state is still as a service), which is what we want.
16466                            app.curRawAdj = curEmptyAdj;
16467                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16468                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16469                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16470                                    + ")");
16471                            if (curEmptyAdj != nextEmptyAdj) {
16472                                stepEmpty++;
16473                                if (stepEmpty >= emptyFactor) {
16474                                    stepEmpty = 0;
16475                                    curEmptyAdj = nextEmptyAdj;
16476                                    nextEmptyAdj += 2;
16477                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16478                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16479                                    }
16480                                }
16481                            }
16482                            break;
16483                    }
16484                }
16485
16486                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
16487
16488                // Count the number of process types.
16489                switch (app.curProcState) {
16490                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16491                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16492                        mNumCachedHiddenProcs++;
16493                        numCached++;
16494                        if (numCached > cachedProcessLimit) {
16495                            killUnneededProcessLocked(app, "cached #" + numCached);
16496                        }
16497                        break;
16498                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16499                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16500                                && app.lastActivityTime < oldTime) {
16501                            killUnneededProcessLocked(app, "empty for "
16502                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16503                                    / 1000) + "s");
16504                        } else {
16505                            numEmpty++;
16506                            if (numEmpty > emptyProcessLimit) {
16507                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16508                            }
16509                        }
16510                        break;
16511                    default:
16512                        mNumNonCachedProcs++;
16513                        break;
16514                }
16515
16516                if (app.isolated && app.services.size() <= 0) {
16517                    // If this is an isolated process, and there are no
16518                    // services running in it, then the process is no longer
16519                    // needed.  We agressively kill these because we can by
16520                    // definition not re-use the same process again, and it is
16521                    // good to avoid having whatever code was running in them
16522                    // left sitting around after no longer needed.
16523                    killUnneededProcessLocked(app, "isolated not needed");
16524                }
16525
16526                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16527                        && !app.killedByAm) {
16528                    numTrimming++;
16529                }
16530            }
16531        }
16532
16533        mNumServiceProcs = mNewNumServiceProcs;
16534
16535        // Now determine the memory trimming level of background processes.
16536        // Unfortunately we need to start at the back of the list to do this
16537        // properly.  We only do this if the number of background apps we
16538        // are managing to keep around is less than half the maximum we desire;
16539        // if we are keeping a good number around, we'll let them use whatever
16540        // memory they want.
16541        final int numCachedAndEmpty = numCached + numEmpty;
16542        int memFactor;
16543        if (numCached <= ProcessList.TRIM_CACHED_APPS
16544                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16545            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16546                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16547            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16548                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16549            } else {
16550                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16551            }
16552        } else {
16553            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16554        }
16555        // We always allow the memory level to go up (better).  We only allow it to go
16556        // down if we are in a state where that is allowed, *and* the total number of processes
16557        // has gone down since last time.
16558        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16559                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16560                + " last=" + mLastNumProcesses);
16561        if (memFactor > mLastMemoryLevel) {
16562            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16563                memFactor = mLastMemoryLevel;
16564                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16565            }
16566        }
16567        mLastMemoryLevel = memFactor;
16568        mLastNumProcesses = mLruProcesses.size();
16569        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16570        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16571        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16572            if (mLowRamStartTime == 0) {
16573                mLowRamStartTime = now;
16574            }
16575            int step = 0;
16576            int fgTrimLevel;
16577            switch (memFactor) {
16578                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16579                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16580                    break;
16581                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16582                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16583                    break;
16584                default:
16585                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16586                    break;
16587            }
16588            int factor = numTrimming/3;
16589            int minFactor = 2;
16590            if (mHomeProcess != null) minFactor++;
16591            if (mPreviousProcess != null) minFactor++;
16592            if (factor < minFactor) factor = minFactor;
16593            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16594            for (int i=N-1; i>=0; i--) {
16595                ProcessRecord app = mLruProcesses.get(i);
16596                if (allChanged || app.procStateChanged) {
16597                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16598                    app.procStateChanged = false;
16599                }
16600                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16601                        && !app.killedByAm) {
16602                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16603                        try {
16604                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16605                                    "Trimming memory of " + app.processName
16606                                    + " to " + curLevel);
16607                            app.thread.scheduleTrimMemory(curLevel);
16608                        } catch (RemoteException e) {
16609                        }
16610                        if (false) {
16611                            // For now we won't do this; our memory trimming seems
16612                            // to be good enough at this point that destroying
16613                            // activities causes more harm than good.
16614                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16615                                    && app != mHomeProcess && app != mPreviousProcess) {
16616                                // Need to do this on its own message because the stack may not
16617                                // be in a consistent state at this point.
16618                                // For these apps we will also finish their activities
16619                                // to help them free memory.
16620                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16621                            }
16622                        }
16623                    }
16624                    app.trimMemoryLevel = curLevel;
16625                    step++;
16626                    if (step >= factor) {
16627                        step = 0;
16628                        switch (curLevel) {
16629                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16630                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16631                                break;
16632                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16633                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16634                                break;
16635                        }
16636                    }
16637                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16638                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16639                            && app.thread != null) {
16640                        try {
16641                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16642                                    "Trimming memory of heavy-weight " + app.processName
16643                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16644                            app.thread.scheduleTrimMemory(
16645                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16646                        } catch (RemoteException e) {
16647                        }
16648                    }
16649                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16650                } else {
16651                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16652                            || app.systemNoUi) && app.pendingUiClean) {
16653                        // If this application is now in the background and it
16654                        // had done UI, then give it the special trim level to
16655                        // have it free UI resources.
16656                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16657                        if (app.trimMemoryLevel < level && app.thread != null) {
16658                            try {
16659                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16660                                        "Trimming memory of bg-ui " + app.processName
16661                                        + " to " + level);
16662                                app.thread.scheduleTrimMemory(level);
16663                            } catch (RemoteException e) {
16664                            }
16665                        }
16666                        app.pendingUiClean = false;
16667                    }
16668                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16669                        try {
16670                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16671                                    "Trimming memory of fg " + app.processName
16672                                    + " to " + fgTrimLevel);
16673                            app.thread.scheduleTrimMemory(fgTrimLevel);
16674                        } catch (RemoteException e) {
16675                        }
16676                    }
16677                    app.trimMemoryLevel = fgTrimLevel;
16678                }
16679            }
16680        } else {
16681            if (mLowRamStartTime != 0) {
16682                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16683                mLowRamStartTime = 0;
16684            }
16685            for (int i=N-1; i>=0; i--) {
16686                ProcessRecord app = mLruProcesses.get(i);
16687                if (allChanged || app.procStateChanged) {
16688                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16689                    app.procStateChanged = false;
16690                }
16691                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16692                        || app.systemNoUi) && app.pendingUiClean) {
16693                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16694                            && app.thread != null) {
16695                        try {
16696                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16697                                    "Trimming memory of ui hidden " + app.processName
16698                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16699                            app.thread.scheduleTrimMemory(
16700                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16701                        } catch (RemoteException e) {
16702                        }
16703                    }
16704                    app.pendingUiClean = false;
16705                }
16706                app.trimMemoryLevel = 0;
16707            }
16708        }
16709
16710        if (mAlwaysFinishActivities) {
16711            // Need to do this on its own message because the stack may not
16712            // be in a consistent state at this point.
16713            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16714        }
16715
16716        if (allChanged) {
16717            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16718        }
16719
16720        if (mProcessStats.shouldWriteNowLocked(now)) {
16721            mHandler.post(new Runnable() {
16722                @Override public void run() {
16723                    synchronized (ActivityManagerService.this) {
16724                        mProcessStats.writeStateAsyncLocked();
16725                    }
16726                }
16727            });
16728        }
16729
16730        if (DEBUG_OOM_ADJ) {
16731            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16732        }
16733    }
16734
16735    final void trimApplications() {
16736        synchronized (this) {
16737            int i;
16738
16739            // First remove any unused application processes whose package
16740            // has been removed.
16741            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16742                final ProcessRecord app = mRemovedProcesses.get(i);
16743                if (app.activities.size() == 0
16744                        && app.curReceiver == null && app.services.size() == 0) {
16745                    Slog.i(
16746                        TAG, "Exiting empty application process "
16747                        + app.processName + " ("
16748                        + (app.thread != null ? app.thread.asBinder() : null)
16749                        + ")\n");
16750                    if (app.pid > 0 && app.pid != MY_PID) {
16751                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16752                                app.processName, app.setAdj, "empty");
16753                        app.killedByAm = true;
16754                        Process.killProcessQuiet(app.pid);
16755                        Process.killProcessGroup(app.info.uid, app.pid);
16756                    } else {
16757                        try {
16758                            app.thread.scheduleExit();
16759                        } catch (Exception e) {
16760                            // Ignore exceptions.
16761                        }
16762                    }
16763                    cleanUpApplicationRecordLocked(app, false, true, -1);
16764                    mRemovedProcesses.remove(i);
16765
16766                    if (app.persistent) {
16767                        addAppLocked(app.info, false, null /* ABI override */);
16768                    }
16769                }
16770            }
16771
16772            // Now update the oom adj for all processes.
16773            updateOomAdjLocked();
16774        }
16775    }
16776
16777    /** This method sends the specified signal to each of the persistent apps */
16778    public void signalPersistentProcesses(int sig) throws RemoteException {
16779        if (sig != Process.SIGNAL_USR1) {
16780            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16781        }
16782
16783        synchronized (this) {
16784            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16785                    != PackageManager.PERMISSION_GRANTED) {
16786                throw new SecurityException("Requires permission "
16787                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16788            }
16789
16790            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16791                ProcessRecord r = mLruProcesses.get(i);
16792                if (r.thread != null && r.persistent) {
16793                    Process.sendSignal(r.pid, sig);
16794                }
16795            }
16796        }
16797    }
16798
16799    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16800        if (proc == null || proc == mProfileProc) {
16801            proc = mProfileProc;
16802            path = mProfileFile;
16803            profileType = mProfileType;
16804            clearProfilerLocked();
16805        }
16806        if (proc == null) {
16807            return;
16808        }
16809        try {
16810            proc.thread.profilerControl(false, path, null, profileType);
16811        } catch (RemoteException e) {
16812            throw new IllegalStateException("Process disappeared");
16813        }
16814    }
16815
16816    private void clearProfilerLocked() {
16817        if (mProfileFd != null) {
16818            try {
16819                mProfileFd.close();
16820            } catch (IOException e) {
16821            }
16822        }
16823        mProfileApp = null;
16824        mProfileProc = null;
16825        mProfileFile = null;
16826        mProfileType = 0;
16827        mAutoStopProfiler = false;
16828    }
16829
16830    public boolean profileControl(String process, int userId, boolean start,
16831            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16832
16833        try {
16834            synchronized (this) {
16835                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16836                // its own permission.
16837                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16838                        != PackageManager.PERMISSION_GRANTED) {
16839                    throw new SecurityException("Requires permission "
16840                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16841                }
16842
16843                if (start && fd == null) {
16844                    throw new IllegalArgumentException("null fd");
16845                }
16846
16847                ProcessRecord proc = null;
16848                if (process != null) {
16849                    proc = findProcessLocked(process, userId, "profileControl");
16850                }
16851
16852                if (start && (proc == null || proc.thread == null)) {
16853                    throw new IllegalArgumentException("Unknown process: " + process);
16854                }
16855
16856                if (start) {
16857                    stopProfilerLocked(null, null, 0);
16858                    setProfileApp(proc.info, proc.processName, path, fd, false);
16859                    mProfileProc = proc;
16860                    mProfileType = profileType;
16861                    try {
16862                        fd = fd.dup();
16863                    } catch (IOException e) {
16864                        fd = null;
16865                    }
16866                    proc.thread.profilerControl(start, path, fd, profileType);
16867                    fd = null;
16868                    mProfileFd = null;
16869                } else {
16870                    stopProfilerLocked(proc, path, profileType);
16871                    if (fd != null) {
16872                        try {
16873                            fd.close();
16874                        } catch (IOException e) {
16875                        }
16876                    }
16877                }
16878
16879                return true;
16880            }
16881        } catch (RemoteException e) {
16882            throw new IllegalStateException("Process disappeared");
16883        } finally {
16884            if (fd != null) {
16885                try {
16886                    fd.close();
16887                } catch (IOException e) {
16888                }
16889            }
16890        }
16891    }
16892
16893    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16894        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16895                userId, true, ALLOW_FULL_ONLY, callName, null);
16896        ProcessRecord proc = null;
16897        try {
16898            int pid = Integer.parseInt(process);
16899            synchronized (mPidsSelfLocked) {
16900                proc = mPidsSelfLocked.get(pid);
16901            }
16902        } catch (NumberFormatException e) {
16903        }
16904
16905        if (proc == null) {
16906            ArrayMap<String, SparseArray<ProcessRecord>> all
16907                    = mProcessNames.getMap();
16908            SparseArray<ProcessRecord> procs = all.get(process);
16909            if (procs != null && procs.size() > 0) {
16910                proc = procs.valueAt(0);
16911                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16912                    for (int i=1; i<procs.size(); i++) {
16913                        ProcessRecord thisProc = procs.valueAt(i);
16914                        if (thisProc.userId == userId) {
16915                            proc = thisProc;
16916                            break;
16917                        }
16918                    }
16919                }
16920            }
16921        }
16922
16923        return proc;
16924    }
16925
16926    public boolean dumpHeap(String process, int userId, boolean managed,
16927            String path, ParcelFileDescriptor fd) throws RemoteException {
16928
16929        try {
16930            synchronized (this) {
16931                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16932                // its own permission (same as profileControl).
16933                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16934                        != PackageManager.PERMISSION_GRANTED) {
16935                    throw new SecurityException("Requires permission "
16936                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16937                }
16938
16939                if (fd == null) {
16940                    throw new IllegalArgumentException("null fd");
16941                }
16942
16943                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16944                if (proc == null || proc.thread == null) {
16945                    throw new IllegalArgumentException("Unknown process: " + process);
16946                }
16947
16948                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16949                if (!isDebuggable) {
16950                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16951                        throw new SecurityException("Process not debuggable: " + proc);
16952                    }
16953                }
16954
16955                proc.thread.dumpHeap(managed, path, fd);
16956                fd = null;
16957                return true;
16958            }
16959        } catch (RemoteException e) {
16960            throw new IllegalStateException("Process disappeared");
16961        } finally {
16962            if (fd != null) {
16963                try {
16964                    fd.close();
16965                } catch (IOException e) {
16966                }
16967            }
16968        }
16969    }
16970
16971    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16972    public void monitor() {
16973        synchronized (this) { }
16974    }
16975
16976    void onCoreSettingsChange(Bundle settings) {
16977        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16978            ProcessRecord processRecord = mLruProcesses.get(i);
16979            try {
16980                if (processRecord.thread != null) {
16981                    processRecord.thread.setCoreSettings(settings);
16982                }
16983            } catch (RemoteException re) {
16984                /* ignore */
16985            }
16986        }
16987    }
16988
16989    // Multi-user methods
16990
16991    /**
16992     * Start user, if its not already running, but don't bring it to foreground.
16993     */
16994    @Override
16995    public boolean startUserInBackground(final int userId) {
16996        return startUser(userId, /* foreground */ false);
16997    }
16998
16999    /**
17000     * Refreshes the list of users related to the current user when either a
17001     * user switch happens or when a new related user is started in the
17002     * background.
17003     */
17004    private void updateCurrentProfileIdsLocked() {
17005        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17006                mCurrentUserId, false /* enabledOnly */);
17007        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17008        for (int i = 0; i < currentProfileIds.length; i++) {
17009            currentProfileIds[i] = profiles.get(i).id;
17010        }
17011        mCurrentProfileIds = currentProfileIds;
17012
17013        synchronized (mUserProfileGroupIdsSelfLocked) {
17014            mUserProfileGroupIdsSelfLocked.clear();
17015            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17016            for (int i = 0; i < users.size(); i++) {
17017                UserInfo user = users.get(i);
17018                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17019                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17020                }
17021            }
17022        }
17023    }
17024
17025    private Set getProfileIdsLocked(int userId) {
17026        Set userIds = new HashSet<Integer>();
17027        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17028                userId, false /* enabledOnly */);
17029        for (UserInfo user : profiles) {
17030            userIds.add(Integer.valueOf(user.id));
17031        }
17032        return userIds;
17033    }
17034
17035    @Override
17036    public boolean switchUser(final int userId) {
17037        return startUser(userId, /* foregound */ true);
17038    }
17039
17040    private boolean startUser(final int userId, boolean foreground) {
17041        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17042                != PackageManager.PERMISSION_GRANTED) {
17043            String msg = "Permission Denial: switchUser() from pid="
17044                    + Binder.getCallingPid()
17045                    + ", uid=" + Binder.getCallingUid()
17046                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17047            Slog.w(TAG, msg);
17048            throw new SecurityException(msg);
17049        }
17050
17051        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17052
17053        final long ident = Binder.clearCallingIdentity();
17054        try {
17055            synchronized (this) {
17056                final int oldUserId = mCurrentUserId;
17057                if (oldUserId == userId) {
17058                    return true;
17059                }
17060
17061                mStackSupervisor.setLockTaskModeLocked(null, false);
17062
17063                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17064                if (userInfo == null) {
17065                    Slog.w(TAG, "No user info for user #" + userId);
17066                    return false;
17067                }
17068
17069                if (foreground) {
17070                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17071                            R.anim.screen_user_enter);
17072                }
17073
17074                boolean needStart = false;
17075
17076                // If the user we are switching to is not currently started, then
17077                // we need to start it now.
17078                if (mStartedUsers.get(userId) == null) {
17079                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17080                    updateStartedUserArrayLocked();
17081                    needStart = true;
17082                }
17083
17084                final Integer userIdInt = Integer.valueOf(userId);
17085                mUserLru.remove(userIdInt);
17086                mUserLru.add(userIdInt);
17087
17088                if (foreground) {
17089                    mCurrentUserId = userId;
17090                    updateCurrentProfileIdsLocked();
17091                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17092                    // Once the internal notion of the active user has switched, we lock the device
17093                    // with the option to show the user switcher on the keyguard.
17094                    mWindowManager.lockNow(null);
17095                } else {
17096                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17097                    updateCurrentProfileIdsLocked();
17098                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17099                    mUserLru.remove(currentUserIdInt);
17100                    mUserLru.add(currentUserIdInt);
17101                }
17102
17103                final UserStartedState uss = mStartedUsers.get(userId);
17104
17105                // Make sure user is in the started state.  If it is currently
17106                // stopping, we need to knock that off.
17107                if (uss.mState == UserStartedState.STATE_STOPPING) {
17108                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17109                    // so we can just fairly silently bring the user back from
17110                    // the almost-dead.
17111                    uss.mState = UserStartedState.STATE_RUNNING;
17112                    updateStartedUserArrayLocked();
17113                    needStart = true;
17114                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17115                    // This means ACTION_SHUTDOWN has been sent, so we will
17116                    // need to treat this as a new boot of the user.
17117                    uss.mState = UserStartedState.STATE_BOOTING;
17118                    updateStartedUserArrayLocked();
17119                    needStart = true;
17120                }
17121
17122                if (uss.mState == UserStartedState.STATE_BOOTING) {
17123                    // Booting up a new user, need to tell system services about it.
17124                    // Note that this is on the same handler as scheduling of broadcasts,
17125                    // which is important because it needs to go first.
17126                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
17127                }
17128
17129                if (foreground) {
17130                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
17131                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17132                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17133                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
17134                            oldUserId, userId, uss));
17135                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
17136                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
17137                }
17138
17139                if (needStart) {
17140                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
17141                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17142                            | Intent.FLAG_RECEIVER_FOREGROUND);
17143                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17144                    broadcastIntentLocked(null, null, intent,
17145                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17146                            false, false, MY_PID, Process.SYSTEM_UID, userId);
17147                }
17148
17149                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
17150                    if (userId != UserHandle.USER_OWNER) {
17151                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
17152                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17153                        broadcastIntentLocked(null, null, intent, null,
17154                                new IIntentReceiver.Stub() {
17155                                    public void performReceive(Intent intent, int resultCode,
17156                                            String data, Bundle extras, boolean ordered,
17157                                            boolean sticky, int sendingUser) {
17158                                        userInitialized(uss, userId);
17159                                    }
17160                                }, 0, null, null, null, AppOpsManager.OP_NONE,
17161                                true, false, MY_PID, Process.SYSTEM_UID,
17162                                userId);
17163                        uss.initializing = true;
17164                    } else {
17165                        getUserManagerLocked().makeInitialized(userInfo.id);
17166                    }
17167                }
17168
17169                if (foreground) {
17170                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
17171                    if (homeInFront) {
17172                        startHomeActivityLocked(userId);
17173                    } else {
17174                        mStackSupervisor.resumeTopActivitiesLocked();
17175                    }
17176                    EventLogTags.writeAmSwitchUser(userId);
17177                    getUserManagerLocked().userForeground(userId);
17178                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
17179                } else {
17180                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
17181                }
17182
17183                if (needStart) {
17184                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
17185                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17186                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17187                    broadcastIntentLocked(null, null, intent,
17188                            null, new IIntentReceiver.Stub() {
17189                                @Override
17190                                public void performReceive(Intent intent, int resultCode, String data,
17191                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
17192                                        throws RemoteException {
17193                                }
17194                            }, 0, null, null,
17195                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17196                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17197                }
17198            }
17199        } finally {
17200            Binder.restoreCallingIdentity(ident);
17201        }
17202
17203        return true;
17204    }
17205
17206    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
17207        long ident = Binder.clearCallingIdentity();
17208        try {
17209            Intent intent;
17210            if (oldUserId >= 0) {
17211                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
17212                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
17213                int count = profiles.size();
17214                for (int i = 0; i < count; i++) {
17215                    int profileUserId = profiles.get(i).id;
17216                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
17217                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17218                            | Intent.FLAG_RECEIVER_FOREGROUND);
17219                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17220                    broadcastIntentLocked(null, null, intent,
17221                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17222                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17223                }
17224            }
17225            if (newUserId >= 0) {
17226                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
17227                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
17228                int count = profiles.size();
17229                for (int i = 0; i < count; i++) {
17230                    int profileUserId = profiles.get(i).id;
17231                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
17232                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17233                            | Intent.FLAG_RECEIVER_FOREGROUND);
17234                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17235                    broadcastIntentLocked(null, null, intent,
17236                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17237                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17238                }
17239                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17240                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17241                        | Intent.FLAG_RECEIVER_FOREGROUND);
17242                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17243                broadcastIntentLocked(null, null, intent,
17244                        null, null, 0, null, null,
17245                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17246                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17247            }
17248        } finally {
17249            Binder.restoreCallingIdentity(ident);
17250        }
17251    }
17252
17253    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17254            final int newUserId) {
17255        final int N = mUserSwitchObservers.beginBroadcast();
17256        if (N > 0) {
17257            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17258                int mCount = 0;
17259                @Override
17260                public void sendResult(Bundle data) throws RemoteException {
17261                    synchronized (ActivityManagerService.this) {
17262                        if (mCurUserSwitchCallback == this) {
17263                            mCount++;
17264                            if (mCount == N) {
17265                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17266                            }
17267                        }
17268                    }
17269                }
17270            };
17271            synchronized (this) {
17272                uss.switching = true;
17273                mCurUserSwitchCallback = callback;
17274            }
17275            for (int i=0; i<N; i++) {
17276                try {
17277                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17278                            newUserId, callback);
17279                } catch (RemoteException e) {
17280                }
17281            }
17282        } else {
17283            synchronized (this) {
17284                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17285            }
17286        }
17287        mUserSwitchObservers.finishBroadcast();
17288    }
17289
17290    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17291        synchronized (this) {
17292            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17293            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17294        }
17295    }
17296
17297    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17298        mCurUserSwitchCallback = null;
17299        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17300        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17301                oldUserId, newUserId, uss));
17302    }
17303
17304    void userInitialized(UserStartedState uss, int newUserId) {
17305        completeSwitchAndInitalize(uss, newUserId, true, false);
17306    }
17307
17308    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17309        completeSwitchAndInitalize(uss, newUserId, false, true);
17310    }
17311
17312    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17313            boolean clearInitializing, boolean clearSwitching) {
17314        boolean unfrozen = false;
17315        synchronized (this) {
17316            if (clearInitializing) {
17317                uss.initializing = false;
17318                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17319            }
17320            if (clearSwitching) {
17321                uss.switching = false;
17322            }
17323            if (!uss.switching && !uss.initializing) {
17324                mWindowManager.stopFreezingScreen();
17325                unfrozen = true;
17326            }
17327        }
17328        if (unfrozen) {
17329            final int N = mUserSwitchObservers.beginBroadcast();
17330            for (int i=0; i<N; i++) {
17331                try {
17332                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17333                } catch (RemoteException e) {
17334                }
17335            }
17336            mUserSwitchObservers.finishBroadcast();
17337        }
17338    }
17339
17340    void scheduleStartProfilesLocked() {
17341        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17342            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17343                    DateUtils.SECOND_IN_MILLIS);
17344        }
17345    }
17346
17347    void startProfilesLocked() {
17348        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17349        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17350                mCurrentUserId, false /* enabledOnly */);
17351        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17352        for (UserInfo user : profiles) {
17353            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17354                    && user.id != mCurrentUserId) {
17355                toStart.add(user);
17356            }
17357        }
17358        final int n = toStart.size();
17359        int i = 0;
17360        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17361            startUserInBackground(toStart.get(i).id);
17362        }
17363        if (i < n) {
17364            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17365        }
17366    }
17367
17368    void finishUserBoot(UserStartedState uss) {
17369        synchronized (this) {
17370            if (uss.mState == UserStartedState.STATE_BOOTING
17371                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17372                uss.mState = UserStartedState.STATE_RUNNING;
17373                final int userId = uss.mHandle.getIdentifier();
17374                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17375                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17376                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17377                broadcastIntentLocked(null, null, intent,
17378                        null, null, 0, null, null,
17379                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17380                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17381            }
17382        }
17383    }
17384
17385    void finishUserSwitch(UserStartedState uss) {
17386        synchronized (this) {
17387            finishUserBoot(uss);
17388
17389            startProfilesLocked();
17390
17391            int num = mUserLru.size();
17392            int i = 0;
17393            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17394                Integer oldUserId = mUserLru.get(i);
17395                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17396                if (oldUss == null) {
17397                    // Shouldn't happen, but be sane if it does.
17398                    mUserLru.remove(i);
17399                    num--;
17400                    continue;
17401                }
17402                if (oldUss.mState == UserStartedState.STATE_STOPPING
17403                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17404                    // This user is already stopping, doesn't count.
17405                    num--;
17406                    i++;
17407                    continue;
17408                }
17409                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17410                    // Owner and current can't be stopped, but count as running.
17411                    i++;
17412                    continue;
17413                }
17414                // This is a user to be stopped.
17415                stopUserLocked(oldUserId, null);
17416                num--;
17417                i++;
17418            }
17419        }
17420    }
17421
17422    @Override
17423    public int stopUser(final int userId, final IStopUserCallback callback) {
17424        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17425                != PackageManager.PERMISSION_GRANTED) {
17426            String msg = "Permission Denial: switchUser() from pid="
17427                    + Binder.getCallingPid()
17428                    + ", uid=" + Binder.getCallingUid()
17429                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17430            Slog.w(TAG, msg);
17431            throw new SecurityException(msg);
17432        }
17433        if (userId <= 0) {
17434            throw new IllegalArgumentException("Can't stop primary user " + userId);
17435        }
17436        synchronized (this) {
17437            return stopUserLocked(userId, callback);
17438        }
17439    }
17440
17441    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17442        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17443        if (mCurrentUserId == userId) {
17444            return ActivityManager.USER_OP_IS_CURRENT;
17445        }
17446
17447        final UserStartedState uss = mStartedUsers.get(userId);
17448        if (uss == null) {
17449            // User is not started, nothing to do...  but we do need to
17450            // callback if requested.
17451            if (callback != null) {
17452                mHandler.post(new Runnable() {
17453                    @Override
17454                    public void run() {
17455                        try {
17456                            callback.userStopped(userId);
17457                        } catch (RemoteException e) {
17458                        }
17459                    }
17460                });
17461            }
17462            return ActivityManager.USER_OP_SUCCESS;
17463        }
17464
17465        if (callback != null) {
17466            uss.mStopCallbacks.add(callback);
17467        }
17468
17469        if (uss.mState != UserStartedState.STATE_STOPPING
17470                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17471            uss.mState = UserStartedState.STATE_STOPPING;
17472            updateStartedUserArrayLocked();
17473
17474            long ident = Binder.clearCallingIdentity();
17475            try {
17476                // We are going to broadcast ACTION_USER_STOPPING and then
17477                // once that is done send a final ACTION_SHUTDOWN and then
17478                // stop the user.
17479                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17480                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17481                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17482                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17483                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17484                // This is the result receiver for the final shutdown broadcast.
17485                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17486                    @Override
17487                    public void performReceive(Intent intent, int resultCode, String data,
17488                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17489                        finishUserStop(uss);
17490                    }
17491                };
17492                // This is the result receiver for the initial stopping broadcast.
17493                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17494                    @Override
17495                    public void performReceive(Intent intent, int resultCode, String data,
17496                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17497                        // On to the next.
17498                        synchronized (ActivityManagerService.this) {
17499                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17500                                // Whoops, we are being started back up.  Abort, abort!
17501                                return;
17502                            }
17503                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17504                        }
17505                        mSystemServiceManager.stopUser(userId);
17506                        broadcastIntentLocked(null, null, shutdownIntent,
17507                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17508                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17509                    }
17510                };
17511                // Kick things off.
17512                broadcastIntentLocked(null, null, stoppingIntent,
17513                        null, stoppingReceiver, 0, null, null,
17514                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17515                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17516            } finally {
17517                Binder.restoreCallingIdentity(ident);
17518            }
17519        }
17520
17521        return ActivityManager.USER_OP_SUCCESS;
17522    }
17523
17524    void finishUserStop(UserStartedState uss) {
17525        final int userId = uss.mHandle.getIdentifier();
17526        boolean stopped;
17527        ArrayList<IStopUserCallback> callbacks;
17528        synchronized (this) {
17529            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17530            if (mStartedUsers.get(userId) != uss) {
17531                stopped = false;
17532            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17533                stopped = false;
17534            } else {
17535                stopped = true;
17536                // User can no longer run.
17537                mStartedUsers.remove(userId);
17538                mUserLru.remove(Integer.valueOf(userId));
17539                updateStartedUserArrayLocked();
17540
17541                // Clean up all state and processes associated with the user.
17542                // Kill all the processes for the user.
17543                forceStopUserLocked(userId, "finish user");
17544            }
17545        }
17546
17547        for (int i=0; i<callbacks.size(); i++) {
17548            try {
17549                if (stopped) callbacks.get(i).userStopped(userId);
17550                else callbacks.get(i).userStopAborted(userId);
17551            } catch (RemoteException e) {
17552            }
17553        }
17554
17555        if (stopped) {
17556            mSystemServiceManager.cleanupUser(userId);
17557            synchronized (this) {
17558                mStackSupervisor.removeUserLocked(userId);
17559            }
17560        }
17561    }
17562
17563    @Override
17564    public UserInfo getCurrentUser() {
17565        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
17566                != PackageManager.PERMISSION_GRANTED) && (
17567                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17568                != PackageManager.PERMISSION_GRANTED)) {
17569            String msg = "Permission Denial: getCurrentUser() from pid="
17570                    + Binder.getCallingPid()
17571                    + ", uid=" + Binder.getCallingUid()
17572                    + " requires " + INTERACT_ACROSS_USERS;
17573            Slog.w(TAG, msg);
17574            throw new SecurityException(msg);
17575        }
17576        synchronized (this) {
17577            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17578        }
17579    }
17580
17581    int getCurrentUserIdLocked() {
17582        return mCurrentUserId;
17583    }
17584
17585    @Override
17586    public boolean isUserRunning(int userId, boolean orStopped) {
17587        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17588                != PackageManager.PERMISSION_GRANTED) {
17589            String msg = "Permission Denial: isUserRunning() from pid="
17590                    + Binder.getCallingPid()
17591                    + ", uid=" + Binder.getCallingUid()
17592                    + " requires " + INTERACT_ACROSS_USERS;
17593            Slog.w(TAG, msg);
17594            throw new SecurityException(msg);
17595        }
17596        synchronized (this) {
17597            return isUserRunningLocked(userId, orStopped);
17598        }
17599    }
17600
17601    boolean isUserRunningLocked(int userId, boolean orStopped) {
17602        UserStartedState state = mStartedUsers.get(userId);
17603        if (state == null) {
17604            return false;
17605        }
17606        if (orStopped) {
17607            return true;
17608        }
17609        return state.mState != UserStartedState.STATE_STOPPING
17610                && state.mState != UserStartedState.STATE_SHUTDOWN;
17611    }
17612
17613    @Override
17614    public int[] getRunningUserIds() {
17615        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17616                != PackageManager.PERMISSION_GRANTED) {
17617            String msg = "Permission Denial: isUserRunning() from pid="
17618                    + Binder.getCallingPid()
17619                    + ", uid=" + Binder.getCallingUid()
17620                    + " requires " + INTERACT_ACROSS_USERS;
17621            Slog.w(TAG, msg);
17622            throw new SecurityException(msg);
17623        }
17624        synchronized (this) {
17625            return mStartedUserArray;
17626        }
17627    }
17628
17629    private void updateStartedUserArrayLocked() {
17630        int num = 0;
17631        for (int i=0; i<mStartedUsers.size();  i++) {
17632            UserStartedState uss = mStartedUsers.valueAt(i);
17633            // This list does not include stopping users.
17634            if (uss.mState != UserStartedState.STATE_STOPPING
17635                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17636                num++;
17637            }
17638        }
17639        mStartedUserArray = new int[num];
17640        num = 0;
17641        for (int i=0; i<mStartedUsers.size();  i++) {
17642            UserStartedState uss = mStartedUsers.valueAt(i);
17643            if (uss.mState != UserStartedState.STATE_STOPPING
17644                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17645                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17646                num++;
17647            }
17648        }
17649    }
17650
17651    @Override
17652    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17653        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17654                != PackageManager.PERMISSION_GRANTED) {
17655            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17656                    + Binder.getCallingPid()
17657                    + ", uid=" + Binder.getCallingUid()
17658                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17659            Slog.w(TAG, msg);
17660            throw new SecurityException(msg);
17661        }
17662
17663        mUserSwitchObservers.register(observer);
17664    }
17665
17666    @Override
17667    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17668        mUserSwitchObservers.unregister(observer);
17669    }
17670
17671    private boolean userExists(int userId) {
17672        if (userId == 0) {
17673            return true;
17674        }
17675        UserManagerService ums = getUserManagerLocked();
17676        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17677    }
17678
17679    int[] getUsersLocked() {
17680        UserManagerService ums = getUserManagerLocked();
17681        return ums != null ? ums.getUserIds() : new int[] { 0 };
17682    }
17683
17684    UserManagerService getUserManagerLocked() {
17685        if (mUserManager == null) {
17686            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17687            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17688        }
17689        return mUserManager;
17690    }
17691
17692    private int applyUserId(int uid, int userId) {
17693        return UserHandle.getUid(userId, uid);
17694    }
17695
17696    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17697        if (info == null) return null;
17698        ApplicationInfo newInfo = new ApplicationInfo(info);
17699        newInfo.uid = applyUserId(info.uid, userId);
17700        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17701                + info.packageName;
17702        return newInfo;
17703    }
17704
17705    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17706        if (aInfo == null
17707                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17708            return aInfo;
17709        }
17710
17711        ActivityInfo info = new ActivityInfo(aInfo);
17712        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17713        return info;
17714    }
17715
17716    private final class LocalService extends ActivityManagerInternal {
17717        @Override
17718        public void goingToSleep() {
17719            ActivityManagerService.this.goingToSleep();
17720        }
17721
17722        @Override
17723        public void wakingUp() {
17724            ActivityManagerService.this.wakingUp();
17725        }
17726    }
17727
17728    /**
17729     * An implementation of IAppTask, that allows an app to manage its own tasks via
17730     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17731     * only the process that calls getAppTasks() can call the AppTask methods.
17732     */
17733    class AppTaskImpl extends IAppTask.Stub {
17734        private int mTaskId;
17735        private int mCallingUid;
17736
17737        public AppTaskImpl(int taskId, int callingUid) {
17738            mTaskId = taskId;
17739            mCallingUid = callingUid;
17740        }
17741
17742        @Override
17743        public void finishAndRemoveTask() {
17744            // Ensure that we are called from the same process that created this AppTask
17745            if (mCallingUid != Binder.getCallingUid()) {
17746                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17747                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17748                return;
17749            }
17750
17751            synchronized (ActivityManagerService.this) {
17752                long origId = Binder.clearCallingIdentity();
17753                try {
17754                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17755                    if (tr != null) {
17756                        // Only kill the process if we are not a new document
17757                        int flags = tr.getBaseIntent().getFlags();
17758                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17759                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17760                        removeTaskByIdLocked(mTaskId,
17761                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17762                    }
17763                } finally {
17764                    Binder.restoreCallingIdentity(origId);
17765                }
17766            }
17767        }
17768
17769        @Override
17770        public ActivityManager.RecentTaskInfo getTaskInfo() {
17771            // Ensure that we are called from the same process that created this AppTask
17772            if (mCallingUid != Binder.getCallingUid()) {
17773                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17774                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17775                return null;
17776            }
17777
17778            synchronized (ActivityManagerService.this) {
17779                long origId = Binder.clearCallingIdentity();
17780                try {
17781                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17782                    if (tr != null) {
17783                        return createRecentTaskInfoFromTaskRecord(tr);
17784                    }
17785                } finally {
17786                    Binder.restoreCallingIdentity(origId);
17787                }
17788                return null;
17789            }
17790        }
17791    }
17792}
17793