ActivityManagerService.java revision be7c50e0a14e91330ce13161bc14a33d34ff6aca
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_FULL;
20import static android.content.pm.PackageManager.PERMISSION_GRANTED;
21import static com.android.internal.util.XmlUtils.readBooleanAttribute;
22import static com.android.internal.util.XmlUtils.readIntAttribute;
23import static com.android.internal.util.XmlUtils.readLongAttribute;
24import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
25import static com.android.internal.util.XmlUtils.writeIntAttribute;
26import static com.android.internal.util.XmlUtils.writeLongAttribute;
27import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
28import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
29import static org.xmlpull.v1.XmlPullParser.START_TAG;
30import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
31
32import android.Manifest;
33import android.app.AppOpsManager;
34import android.app.IActivityContainer;
35import android.app.IActivityContainerCallback;
36import android.app.IAppTask;
37import android.app.admin.DevicePolicyManager;
38import android.appwidget.AppWidgetManager;
39import android.graphics.Rect;
40import android.os.BatteryStats;
41import android.os.PersistableBundle;
42import android.service.voice.IVoiceInteractionSession;
43import android.util.ArrayMap;
44
45import com.android.internal.R;
46import com.android.internal.annotations.GuardedBy;
47import com.android.internal.app.IAppOpsService;
48import com.android.internal.app.IVoiceInteractor;
49import com.android.internal.app.ProcessMap;
50import com.android.internal.app.ProcessStats;
51import com.android.internal.content.PackageMonitor;
52import com.android.internal.os.BackgroundThread;
53import com.android.internal.os.BatteryStatsImpl;
54import com.android.internal.os.ProcessCpuTracker;
55import com.android.internal.os.TransferPipe;
56import com.android.internal.os.Zygote;
57import com.android.internal.util.FastPrintWriter;
58import com.android.internal.util.FastXmlSerializer;
59import com.android.internal.util.MemInfoReader;
60import com.android.internal.util.Preconditions;
61import com.android.server.AppOpsService;
62import com.android.server.AttributeCache;
63import com.android.server.IntentResolver;
64import com.android.server.LocalServices;
65import com.android.server.ServiceThread;
66import com.android.server.SystemService;
67import com.android.server.SystemServiceManager;
68import com.android.server.Watchdog;
69import com.android.server.am.ActivityStack.ActivityState;
70import com.android.server.firewall.IntentFirewall;
71import com.android.server.pm.UserManagerService;
72import com.android.server.wm.AppTransition;
73import com.android.server.wm.WindowManagerService;
74import com.google.android.collect.Lists;
75import com.google.android.collect.Maps;
76
77import libcore.io.IoUtils;
78
79import org.xmlpull.v1.XmlPullParser;
80import org.xmlpull.v1.XmlPullParserException;
81import org.xmlpull.v1.XmlSerializer;
82
83import android.app.Activity;
84import android.app.ActivityManager;
85import android.app.ActivityManager.RunningTaskInfo;
86import android.app.ActivityManager.StackInfo;
87import android.app.ActivityManagerInternal;
88import android.app.ActivityManagerNative;
89import android.app.ActivityOptions;
90import android.app.ActivityThread;
91import android.app.AlertDialog;
92import android.app.AppGlobals;
93import android.app.ApplicationErrorReport;
94import android.app.Dialog;
95import android.app.IActivityController;
96import android.app.IApplicationThread;
97import android.app.IInstrumentationWatcher;
98import android.app.INotificationManager;
99import android.app.IProcessObserver;
100import android.app.IServiceConnection;
101import android.app.IStopUserCallback;
102import android.app.IUiAutomationConnection;
103import android.app.IUserSwitchObserver;
104import android.app.Instrumentation;
105import android.app.Notification;
106import android.app.NotificationManager;
107import android.app.PendingIntent;
108import android.app.backup.IBackupManager;
109import android.content.ActivityNotFoundException;
110import android.content.BroadcastReceiver;
111import android.content.ClipData;
112import android.content.ComponentCallbacks2;
113import android.content.ComponentName;
114import android.content.ContentProvider;
115import android.content.ContentResolver;
116import android.content.Context;
117import android.content.DialogInterface;
118import android.content.IContentProvider;
119import android.content.IIntentReceiver;
120import android.content.IIntentSender;
121import android.content.Intent;
122import android.content.IntentFilter;
123import android.content.IntentSender;
124import android.content.pm.ActivityInfo;
125import android.content.pm.ApplicationInfo;
126import android.content.pm.ConfigurationInfo;
127import android.content.pm.IPackageDataObserver;
128import android.content.pm.IPackageManager;
129import android.content.pm.InstrumentationInfo;
130import android.content.pm.PackageInfo;
131import android.content.pm.PackageManager;
132import android.content.pm.ParceledListSlice;
133import android.content.pm.UserInfo;
134import android.content.pm.PackageManager.NameNotFoundException;
135import android.content.pm.PathPermission;
136import android.content.pm.ProviderInfo;
137import android.content.pm.ResolveInfo;
138import android.content.pm.ServiceInfo;
139import android.content.res.CompatibilityInfo;
140import android.content.res.Configuration;
141import android.graphics.Bitmap;
142import android.net.Proxy;
143import android.net.ProxyInfo;
144import android.net.Uri;
145import android.os.Binder;
146import android.os.Build;
147import android.os.Bundle;
148import android.os.Debug;
149import android.os.DropBoxManager;
150import android.os.Environment;
151import android.os.FactoryTest;
152import android.os.FileObserver;
153import android.os.FileUtils;
154import android.os.Handler;
155import android.os.IBinder;
156import android.os.IPermissionController;
157import android.os.IRemoteCallback;
158import android.os.IUserManager;
159import android.os.Looper;
160import android.os.Message;
161import android.os.Parcel;
162import android.os.ParcelFileDescriptor;
163import android.os.Process;
164import android.os.RemoteCallbackList;
165import android.os.RemoteException;
166import android.os.SELinux;
167import android.os.ServiceManager;
168import android.os.StrictMode;
169import android.os.SystemClock;
170import android.os.SystemProperties;
171import android.os.UpdateLock;
172import android.os.UserHandle;
173import android.provider.Settings;
174import android.text.format.DateUtils;
175import android.text.format.Time;
176import android.util.AtomicFile;
177import android.util.EventLog;
178import android.util.Log;
179import android.util.Pair;
180import android.util.PrintWriterPrinter;
181import android.util.Slog;
182import android.util.SparseArray;
183import android.util.TimeUtils;
184import android.util.Xml;
185import android.view.Gravity;
186import android.view.LayoutInflater;
187import android.view.View;
188import android.view.WindowManager;
189
190import java.io.BufferedInputStream;
191import java.io.BufferedOutputStream;
192import java.io.DataInputStream;
193import java.io.DataOutputStream;
194import java.io.File;
195import java.io.FileDescriptor;
196import java.io.FileInputStream;
197import java.io.FileNotFoundException;
198import java.io.FileOutputStream;
199import java.io.IOException;
200import java.io.InputStreamReader;
201import java.io.PrintWriter;
202import java.io.StringWriter;
203import java.lang.ref.WeakReference;
204import java.util.ArrayList;
205import java.util.Arrays;
206import java.util.Collections;
207import java.util.Comparator;
208import java.util.HashMap;
209import java.util.HashSet;
210import java.util.Iterator;
211import java.util.List;
212import java.util.Locale;
213import java.util.Map;
214import java.util.Set;
215import java.util.concurrent.atomic.AtomicBoolean;
216import java.util.concurrent.atomic.AtomicLong;
217
218public final class ActivityManagerService extends ActivityManagerNative
219        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
220    private static final String USER_DATA_DIR = "/data/user/";
221    static final String TAG = "ActivityManager";
222    static final String TAG_MU = "ActivityManagerServiceMU";
223    static final boolean DEBUG = false;
224    static final boolean localLOGV = DEBUG;
225    static final boolean DEBUG_BACKUP = localLOGV || false;
226    static final boolean DEBUG_BROADCAST = localLOGV || false;
227    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
228    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
229    static final boolean DEBUG_CLEANUP = localLOGV || false;
230    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
231    static final boolean DEBUG_FOCUS = false;
232    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
233    static final boolean DEBUG_MU = localLOGV || false;
234    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
235    static final boolean DEBUG_LRU = localLOGV || false;
236    static final boolean DEBUG_PAUSE = localLOGV || false;
237    static final boolean DEBUG_POWER = localLOGV || false;
238    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
239    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
240    static final boolean DEBUG_PROCESSES = localLOGV || false;
241    static final boolean DEBUG_PROVIDER = localLOGV || false;
242    static final boolean DEBUG_RESULTS = localLOGV || false;
243    static final boolean DEBUG_SERVICE = localLOGV || false;
244    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
245    static final boolean DEBUG_STACK = localLOGV || false;
246    static final boolean DEBUG_SWITCH = localLOGV || false;
247    static final boolean DEBUG_TASKS = localLOGV || false;
248    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
249    static final boolean DEBUG_TRANSITION = localLOGV || false;
250    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
251    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
252    static final boolean DEBUG_VISBILITY = localLOGV || false;
253    static final boolean DEBUG_PSS = localLOGV || false;
254    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
255    static final boolean VALIDATE_TOKENS = false;
256    static final boolean SHOW_ACTIVITY_START_TIME = true;
257
258    // Control over CPU and battery monitoring.
259    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
260    static final boolean MONITOR_CPU_USAGE = true;
261    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
262    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
263    static final boolean MONITOR_THREAD_CPU_USAGE = false;
264
265    // The flags that are set for all calls we make to the package manager.
266    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
267
268    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
269
270    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
271
272    // Maximum number of recent tasks that we can remember.
273    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 200;
274
275    // Amount of time after a call to stopAppSwitches() during which we will
276    // prevent further untrusted switches from happening.
277    static final long APP_SWITCH_DELAY_TIME = 5*1000;
278
279    // How long we wait for a launched process to attach to the activity manager
280    // before we decide it's never going to come up for real.
281    static final int PROC_START_TIMEOUT = 10*1000;
282
283    // How long we wait for a launched process to attach to the activity manager
284    // before we decide it's never going to come up for real, when the process was
285    // started with a wrapper for instrumentation (such as Valgrind) because it
286    // could take much longer than usual.
287    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
288
289    // How long to wait after going idle before forcing apps to GC.
290    static final int GC_TIMEOUT = 5*1000;
291
292    // The minimum amount of time between successive GC requests for a process.
293    static final int GC_MIN_INTERVAL = 60*1000;
294
295    // The minimum amount of time between successive PSS requests for a process.
296    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
297
298    // The minimum amount of time between successive PSS requests for a process
299    // when the request is due to the memory state being lowered.
300    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
301
302    // The rate at which we check for apps using excessive power -- 15 mins.
303    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
304
305    // The minimum sample duration we will allow before deciding we have
306    // enough data on wake locks to start killing things.
307    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
308
309    // The minimum sample duration we will allow before deciding we have
310    // enough data on CPU usage to start killing things.
311    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
312
313    // How long we allow a receiver to run before giving up on it.
314    static final int BROADCAST_FG_TIMEOUT = 10*1000;
315    static final int BROADCAST_BG_TIMEOUT = 60*1000;
316
317    // How long we wait until we timeout on key dispatching.
318    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
319
320    // How long we wait until we timeout on key dispatching during instrumentation.
321    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
322
323    // Amount of time we wait for observers to handle a user switch before
324    // giving up on them and unfreezing the screen.
325    static final int USER_SWITCH_TIMEOUT = 2*1000;
326
327    // Maximum number of users we allow to be running at a time.
328    static final int MAX_RUNNING_USERS = 3;
329
330    // How long to wait in getAssistContextExtras for the activity and foreground services
331    // to respond with the result.
332    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
333
334    // Maximum number of persisted Uri grants a package is allowed
335    static final int MAX_PERSISTED_URI_GRANTS = 128;
336
337    static final int MY_PID = Process.myPid();
338
339    static final String[] EMPTY_STRING_ARRAY = new String[0];
340
341    // How many bytes to write into the dropbox log before truncating
342    static final int DROPBOX_MAX_SIZE = 256 * 1024;
343
344    /** All system services */
345    SystemServiceManager mSystemServiceManager;
346
347    /** Run all ActivityStacks through this */
348    ActivityStackSupervisor mStackSupervisor;
349
350    public IntentFirewall mIntentFirewall;
351
352    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
353    // default actuion automatically.  Important for devices without direct input
354    // devices.
355    private boolean mShowDialogs = true;
356
357    /**
358     * Description of a request to start a new activity, which has been held
359     * due to app switches being disabled.
360     */
361    static class PendingActivityLaunch {
362        final ActivityRecord r;
363        final ActivityRecord sourceRecord;
364        final int startFlags;
365        final ActivityStack stack;
366
367        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
368                int _startFlags, ActivityStack _stack) {
369            r = _r;
370            sourceRecord = _sourceRecord;
371            startFlags = _startFlags;
372            stack = _stack;
373        }
374    }
375
376    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
377            = new ArrayList<PendingActivityLaunch>();
378
379    BroadcastQueue mFgBroadcastQueue;
380    BroadcastQueue mBgBroadcastQueue;
381    // Convenient for easy iteration over the queues. Foreground is first
382    // so that dispatch of foreground broadcasts gets precedence.
383    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
384
385    BroadcastQueue broadcastQueueForIntent(Intent intent) {
386        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
387        if (DEBUG_BACKGROUND_BROADCAST) {
388            Slog.i(TAG, "Broadcast intent " + intent + " on "
389                    + (isFg ? "foreground" : "background")
390                    + " queue");
391        }
392        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
393    }
394
395    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
396        for (BroadcastQueue queue : mBroadcastQueues) {
397            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
398            if (r != null) {
399                return r;
400            }
401        }
402        return null;
403    }
404
405    /**
406     * Activity we have told the window manager to have key focus.
407     */
408    ActivityRecord mFocusedActivity = null;
409
410    /**
411     * List of intents that were used to start the most recent tasks.
412     */
413    ArrayList<TaskRecord> mRecentTasks;
414
415    public class PendingAssistExtras extends Binder implements Runnable {
416        public final ActivityRecord activity;
417        public boolean haveResult = false;
418        public Bundle result = null;
419        public PendingAssistExtras(ActivityRecord _activity) {
420            activity = _activity;
421        }
422        @Override
423        public void run() {
424            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
425            synchronized (this) {
426                haveResult = true;
427                notifyAll();
428            }
429        }
430    }
431
432    final ArrayList<PendingAssistExtras> mPendingAssistExtras
433            = new ArrayList<PendingAssistExtras>();
434
435    /**
436     * Process management.
437     */
438    final ProcessList mProcessList = new ProcessList();
439
440    /**
441     * All of the applications we currently have running organized by name.
442     * The keys are strings of the application package name (as
443     * returned by the package manager), and the keys are ApplicationRecord
444     * objects.
445     */
446    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
447
448    /**
449     * Tracking long-term execution of processes to look for abuse and other
450     * bad app behavior.
451     */
452    final ProcessStatsService mProcessStats;
453
454    /**
455     * The currently running isolated processes.
456     */
457    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
458
459    /**
460     * Counter for assigning isolated process uids, to avoid frequently reusing the
461     * same ones.
462     */
463    int mNextIsolatedProcessUid = 0;
464
465    /**
466     * The currently running heavy-weight process, if any.
467     */
468    ProcessRecord mHeavyWeightProcess = null;
469
470    /**
471     * The last time that various processes have crashed.
472     */
473    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
474
475    /**
476     * Information about a process that is currently marked as bad.
477     */
478    static final class BadProcessInfo {
479        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
480            this.time = time;
481            this.shortMsg = shortMsg;
482            this.longMsg = longMsg;
483            this.stack = stack;
484        }
485
486        final long time;
487        final String shortMsg;
488        final String longMsg;
489        final String stack;
490    }
491
492    /**
493     * Set of applications that we consider to be bad, and will reject
494     * incoming broadcasts from (which the user has no control over).
495     * Processes are added to this set when they have crashed twice within
496     * a minimum amount of time; they are removed from it when they are
497     * later restarted (hopefully due to some user action).  The value is the
498     * time it was added to the list.
499     */
500    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
501
502    /**
503     * All of the processes we currently have running organized by pid.
504     * The keys are the pid running the application.
505     *
506     * <p>NOTE: This object is protected by its own lock, NOT the global
507     * activity manager lock!
508     */
509    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
510
511    /**
512     * All of the processes that have been forced to be foreground.  The key
513     * is the pid of the caller who requested it (we hold a death
514     * link on it).
515     */
516    abstract class ForegroundToken implements IBinder.DeathRecipient {
517        int pid;
518        IBinder token;
519    }
520    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
521
522    /**
523     * List of records for processes that someone had tried to start before the
524     * system was ready.  We don't start them at that point, but ensure they
525     * are started by the time booting is complete.
526     */
527    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
528
529    /**
530     * List of persistent applications that are in the process
531     * of being started.
532     */
533    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
534
535    /**
536     * Processes that are being forcibly torn down.
537     */
538    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
539
540    /**
541     * List of running applications, sorted by recent usage.
542     * The first entry in the list is the least recently used.
543     */
544    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
545
546    /**
547     * Where in mLruProcesses that the processes hosting activities start.
548     */
549    int mLruProcessActivityStart = 0;
550
551    /**
552     * Where in mLruProcesses that the processes hosting services start.
553     * This is after (lower index) than mLruProcessesActivityStart.
554     */
555    int mLruProcessServiceStart = 0;
556
557    /**
558     * List of processes that should gc as soon as things are idle.
559     */
560    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
561
562    /**
563     * Processes we want to collect PSS data from.
564     */
565    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
566
567    /**
568     * Last time we requested PSS data of all processes.
569     */
570    long mLastFullPssTime = SystemClock.uptimeMillis();
571
572    /**
573     * If set, the next time we collect PSS data we should do a full collection
574     * with data from native processes and the kernel.
575     */
576    boolean mFullPssPending = false;
577
578    /**
579     * This is the process holding what we currently consider to be
580     * the "home" activity.
581     */
582    ProcessRecord mHomeProcess;
583
584    /**
585     * This is the process holding the activity the user last visited that
586     * is in a different process from the one they are currently in.
587     */
588    ProcessRecord mPreviousProcess;
589
590    /**
591     * The time at which the previous process was last visible.
592     */
593    long mPreviousProcessVisibleTime;
594
595    /**
596     * Which uses have been started, so are allowed to run code.
597     */
598    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
599
600    /**
601     * LRU list of history of current users.  Most recently current is at the end.
602     */
603    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
604
605    /**
606     * Constant array of the users that are currently started.
607     */
608    int[] mStartedUserArray = new int[] { 0 };
609
610    /**
611     * Registered observers of the user switching mechanics.
612     */
613    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
614            = new RemoteCallbackList<IUserSwitchObserver>();
615
616    /**
617     * Currently active user switch.
618     */
619    Object mCurUserSwitchCallback;
620
621    /**
622     * Packages that the user has asked to have run in screen size
623     * compatibility mode instead of filling the screen.
624     */
625    final CompatModePackages mCompatModePackages;
626
627    /**
628     * Set of IntentSenderRecord objects that are currently active.
629     */
630    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
631            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
632
633    /**
634     * Fingerprints (hashCode()) of stack traces that we've
635     * already logged DropBox entries for.  Guarded by itself.  If
636     * something (rogue user app) forces this over
637     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
638     */
639    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
640    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
641
642    /**
643     * Strict Mode background batched logging state.
644     *
645     * The string buffer is guarded by itself, and its lock is also
646     * used to determine if another batched write is already
647     * in-flight.
648     */
649    private final StringBuilder mStrictModeBuffer = new StringBuilder();
650
651    /**
652     * Keeps track of all IIntentReceivers that have been registered for
653     * broadcasts.  Hash keys are the receiver IBinder, hash value is
654     * a ReceiverList.
655     */
656    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
657            new HashMap<IBinder, ReceiverList>();
658
659    /**
660     * Resolver for broadcast intents to registered receivers.
661     * Holds BroadcastFilter (subclass of IntentFilter).
662     */
663    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
664            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
665        @Override
666        protected boolean allowFilterResult(
667                BroadcastFilter filter, List<BroadcastFilter> dest) {
668            IBinder target = filter.receiverList.receiver.asBinder();
669            for (int i=dest.size()-1; i>=0; i--) {
670                if (dest.get(i).receiverList.receiver.asBinder() == target) {
671                    return false;
672                }
673            }
674            return true;
675        }
676
677        @Override
678        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
679            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
680                    || userId == filter.owningUserId) {
681                return super.newResult(filter, match, userId);
682            }
683            return null;
684        }
685
686        @Override
687        protected BroadcastFilter[] newArray(int size) {
688            return new BroadcastFilter[size];
689        }
690
691        @Override
692        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
693            return packageName.equals(filter.packageName);
694        }
695    };
696
697    /**
698     * State of all active sticky broadcasts per user.  Keys are the action of the
699     * sticky Intent, values are an ArrayList of all broadcasted intents with
700     * that action (which should usually be one).  The SparseArray is keyed
701     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
702     * for stickies that are sent to all users.
703     */
704    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
705            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
706
707    final ActiveServices mServices;
708
709    /**
710     * Backup/restore process management
711     */
712    String mBackupAppName = null;
713    BackupRecord mBackupTarget = null;
714
715    final ProviderMap mProviderMap;
716
717    /**
718     * List of content providers who have clients waiting for them.  The
719     * application is currently being launched and the provider will be
720     * removed from this list once it is published.
721     */
722    final ArrayList<ContentProviderRecord> mLaunchingProviders
723            = new ArrayList<ContentProviderRecord>();
724
725    /**
726     * File storing persisted {@link #mGrantedUriPermissions}.
727     */
728    private final AtomicFile mGrantFile;
729
730    /** XML constants used in {@link #mGrantFile} */
731    private static final String TAG_URI_GRANTS = "uri-grants";
732    private static final String TAG_URI_GRANT = "uri-grant";
733    private static final String ATTR_USER_HANDLE = "userHandle";
734    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
735    private static final String ATTR_TARGET_USER_ID = "targetUserId";
736    private static final String ATTR_SOURCE_PKG = "sourcePkg";
737    private static final String ATTR_TARGET_PKG = "targetPkg";
738    private static final String ATTR_URI = "uri";
739    private static final String ATTR_MODE_FLAGS = "modeFlags";
740    private static final String ATTR_CREATED_TIME = "createdTime";
741    private static final String ATTR_PREFIX = "prefix";
742
743    /**
744     * Global set of specific {@link Uri} permissions that have been granted.
745     * This optimized lookup structure maps from {@link UriPermission#targetUid}
746     * to {@link UriPermission#uri} to {@link UriPermission}.
747     */
748    @GuardedBy("this")
749    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
750            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
751
752    public static class GrantUri {
753        public final int sourceUserId;
754        public final Uri uri;
755        public boolean prefix;
756
757        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
758            this.sourceUserId = sourceUserId;
759            this.uri = uri;
760            this.prefix = prefix;
761        }
762
763        @Override
764        public int hashCode() {
765            return toString().hashCode();
766        }
767
768        @Override
769        public boolean equals(Object o) {
770            if (o instanceof GrantUri) {
771                GrantUri other = (GrantUri) o;
772                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
773                        && prefix == other.prefix;
774            }
775            return false;
776        }
777
778        @Override
779        public String toString() {
780            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
781            if (prefix) result += " [prefix]";
782            return result;
783        }
784
785        public String toSafeString() {
786            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
787            if (prefix) result += " [prefix]";
788            return result;
789        }
790
791        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
792            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
793                    ContentProvider.getUriWithoutUserId(uri), false);
794        }
795    }
796
797    CoreSettingsObserver mCoreSettingsObserver;
798
799    /**
800     * Thread-local storage used to carry caller permissions over through
801     * indirect content-provider access.
802     */
803    private class Identity {
804        public int pid;
805        public int uid;
806
807        Identity(int _pid, int _uid) {
808            pid = _pid;
809            uid = _uid;
810        }
811    }
812
813    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
814
815    /**
816     * All information we have collected about the runtime performance of
817     * any user id that can impact battery performance.
818     */
819    final BatteryStatsService mBatteryStatsService;
820
821    /**
822     * Information about component usage
823     */
824    final UsageStatsService mUsageStatsService;
825
826    /**
827     * Information about and control over application operations
828     */
829    final AppOpsService mAppOpsService;
830
831    /**
832     * Save recent tasks information across reboots.
833     */
834    final TaskPersister mTaskPersister;
835
836    /**
837     * Current configuration information.  HistoryRecord objects are given
838     * a reference to this object to indicate which configuration they are
839     * currently running in, so this object must be kept immutable.
840     */
841    Configuration mConfiguration = new Configuration();
842
843    /**
844     * Current sequencing integer of the configuration, for skipping old
845     * configurations.
846     */
847    int mConfigurationSeq = 0;
848
849    /**
850     * Hardware-reported OpenGLES version.
851     */
852    final int GL_ES_VERSION;
853
854    /**
855     * List of initialization arguments to pass to all processes when binding applications to them.
856     * For example, references to the commonly used services.
857     */
858    HashMap<String, IBinder> mAppBindArgs;
859
860    /**
861     * Temporary to avoid allocations.  Protected by main lock.
862     */
863    final StringBuilder mStringBuilder = new StringBuilder(256);
864
865    /**
866     * Used to control how we initialize the service.
867     */
868    ComponentName mTopComponent;
869    String mTopAction = Intent.ACTION_MAIN;
870    String mTopData;
871    boolean mProcessesReady = false;
872    boolean mSystemReady = false;
873    boolean mBooting = false;
874    boolean mWaitingUpdate = false;
875    boolean mDidUpdate = false;
876    boolean mOnBattery = false;
877    boolean mLaunchWarningShown = false;
878
879    Context mContext;
880
881    int mFactoryTest;
882
883    boolean mCheckedForSetup;
884
885    /**
886     * The time at which we will allow normal application switches again,
887     * after a call to {@link #stopAppSwitches()}.
888     */
889    long mAppSwitchesAllowedTime;
890
891    /**
892     * This is set to true after the first switch after mAppSwitchesAllowedTime
893     * is set; any switches after that will clear the time.
894     */
895    boolean mDidAppSwitch;
896
897    /**
898     * Last time (in realtime) at which we checked for power usage.
899     */
900    long mLastPowerCheckRealtime;
901
902    /**
903     * Last time (in uptime) at which we checked for power usage.
904     */
905    long mLastPowerCheckUptime;
906
907    /**
908     * Set while we are wanting to sleep, to prevent any
909     * activities from being started/resumed.
910     */
911    private boolean mSleeping = false;
912
913    /**
914     * Set while we are running a voice interaction.  This overrides
915     * sleeping while it is active.
916     */
917    private boolean mRunningVoice = false;
918
919    /**
920     * State of external calls telling us if the device is asleep.
921     */
922    private boolean mWentToSleep = false;
923
924    /**
925     * State of external call telling us if the lock screen is shown.
926     */
927    private boolean mLockScreenShown = false;
928
929    /**
930     * Set if we are shutting down the system, similar to sleeping.
931     */
932    boolean mShuttingDown = false;
933
934    /**
935     * Current sequence id for oom_adj computation traversal.
936     */
937    int mAdjSeq = 0;
938
939    /**
940     * Current sequence id for process LRU updating.
941     */
942    int mLruSeq = 0;
943
944    /**
945     * Keep track of the non-cached/empty process we last found, to help
946     * determine how to distribute cached/empty processes next time.
947     */
948    int mNumNonCachedProcs = 0;
949
950    /**
951     * Keep track of the number of cached hidden procs, to balance oom adj
952     * distribution between those and empty procs.
953     */
954    int mNumCachedHiddenProcs = 0;
955
956    /**
957     * Keep track of the number of service processes we last found, to
958     * determine on the next iteration which should be B services.
959     */
960    int mNumServiceProcs = 0;
961    int mNewNumAServiceProcs = 0;
962    int mNewNumServiceProcs = 0;
963
964    /**
965     * Allow the current computed overall memory level of the system to go down?
966     * This is set to false when we are killing processes for reasons other than
967     * memory management, so that the now smaller process list will not be taken as
968     * an indication that memory is tighter.
969     */
970    boolean mAllowLowerMemLevel = false;
971
972    /**
973     * The last computed memory level, for holding when we are in a state that
974     * processes are going away for other reasons.
975     */
976    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
977
978    /**
979     * The last total number of process we have, to determine if changes actually look
980     * like a shrinking number of process due to lower RAM.
981     */
982    int mLastNumProcesses;
983
984    /**
985     * The uptime of the last time we performed idle maintenance.
986     */
987    long mLastIdleTime = SystemClock.uptimeMillis();
988
989    /**
990     * Total time spent with RAM that has been added in the past since the last idle time.
991     */
992    long mLowRamTimeSinceLastIdle = 0;
993
994    /**
995     * If RAM is currently low, when that horrible situation started.
996     */
997    long mLowRamStartTime = 0;
998
999    /**
1000     * For reporting to battery stats the current top application.
1001     */
1002    private String mCurResumedPackage = null;
1003    private int mCurResumedUid = -1;
1004
1005    /**
1006     * For reporting to battery stats the apps currently running foreground
1007     * service.  The ProcessMap is package/uid tuples; each of these contain
1008     * an array of the currently foreground processes.
1009     */
1010    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1011            = new ProcessMap<ArrayList<ProcessRecord>>();
1012
1013    /**
1014     * This is set if we had to do a delayed dexopt of an app before launching
1015     * it, to increase the ANR timeouts in that case.
1016     */
1017    boolean mDidDexOpt;
1018
1019    /**
1020     * Set if the systemServer made a call to enterSafeMode.
1021     */
1022    boolean mSafeMode;
1023
1024    String mDebugApp = null;
1025    boolean mWaitForDebugger = false;
1026    boolean mDebugTransient = false;
1027    String mOrigDebugApp = null;
1028    boolean mOrigWaitForDebugger = false;
1029    boolean mAlwaysFinishActivities = false;
1030    IActivityController mController = null;
1031    String mProfileApp = null;
1032    ProcessRecord mProfileProc = null;
1033    String mProfileFile;
1034    ParcelFileDescriptor mProfileFd;
1035    int mProfileType = 0;
1036    boolean mAutoStopProfiler = false;
1037    String mOpenGlTraceApp = null;
1038
1039    static class ProcessChangeItem {
1040        static final int CHANGE_ACTIVITIES = 1<<0;
1041        static final int CHANGE_PROCESS_STATE = 1<<1;
1042        int changes;
1043        int uid;
1044        int pid;
1045        int processState;
1046        boolean foregroundActivities;
1047    }
1048
1049    final RemoteCallbackList<IProcessObserver> mProcessObservers
1050            = new RemoteCallbackList<IProcessObserver>();
1051    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1052
1053    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1054            = new ArrayList<ProcessChangeItem>();
1055    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1056            = new ArrayList<ProcessChangeItem>();
1057
1058    /**
1059     * Runtime CPU use collection thread.  This object's lock is used to
1060     * protect all related state.
1061     */
1062    final Thread mProcessCpuThread;
1063
1064    /**
1065     * Used to collect process stats when showing not responding dialog.
1066     * Protected by mProcessCpuThread.
1067     */
1068    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1069            MONITOR_THREAD_CPU_USAGE);
1070    final AtomicLong mLastCpuTime = new AtomicLong(0);
1071    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1072
1073    long mLastWriteTime = 0;
1074
1075    /**
1076     * Used to retain an update lock when the foreground activity is in
1077     * immersive mode.
1078     */
1079    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1080
1081    /**
1082     * Set to true after the system has finished booting.
1083     */
1084    boolean mBooted = false;
1085
1086    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1087    int mProcessLimitOverride = -1;
1088
1089    WindowManagerService mWindowManager;
1090
1091    final ActivityThread mSystemThread;
1092
1093    int mCurrentUserId = 0;
1094    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1095    private UserManagerService mUserManager;
1096
1097    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1098        final ProcessRecord mApp;
1099        final int mPid;
1100        final IApplicationThread mAppThread;
1101
1102        AppDeathRecipient(ProcessRecord app, int pid,
1103                IApplicationThread thread) {
1104            if (localLOGV) Slog.v(
1105                TAG, "New death recipient " + this
1106                + " for thread " + thread.asBinder());
1107            mApp = app;
1108            mPid = pid;
1109            mAppThread = thread;
1110        }
1111
1112        @Override
1113        public void binderDied() {
1114            if (localLOGV) Slog.v(
1115                TAG, "Death received in " + this
1116                + " for thread " + mAppThread.asBinder());
1117            synchronized(ActivityManagerService.this) {
1118                appDiedLocked(mApp, mPid, mAppThread);
1119            }
1120        }
1121    }
1122
1123    static final int SHOW_ERROR_MSG = 1;
1124    static final int SHOW_NOT_RESPONDING_MSG = 2;
1125    static final int SHOW_FACTORY_ERROR_MSG = 3;
1126    static final int UPDATE_CONFIGURATION_MSG = 4;
1127    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1128    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1129    static final int SERVICE_TIMEOUT_MSG = 12;
1130    static final int UPDATE_TIME_ZONE = 13;
1131    static final int SHOW_UID_ERROR_MSG = 14;
1132    static final int IM_FEELING_LUCKY_MSG = 15;
1133    static final int PROC_START_TIMEOUT_MSG = 20;
1134    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1135    static final int KILL_APPLICATION_MSG = 22;
1136    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1137    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1138    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1139    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1140    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1141    static final int CLEAR_DNS_CACHE_MSG = 28;
1142    static final int UPDATE_HTTP_PROXY_MSG = 29;
1143    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1144    static final int DISPATCH_PROCESSES_CHANGED = 31;
1145    static final int DISPATCH_PROCESS_DIED = 32;
1146    static final int REPORT_MEM_USAGE_MSG = 33;
1147    static final int REPORT_USER_SWITCH_MSG = 34;
1148    static final int CONTINUE_USER_SWITCH_MSG = 35;
1149    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1150    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1151    static final int PERSIST_URI_GRANTS_MSG = 38;
1152    static final int REQUEST_ALL_PSS_MSG = 39;
1153    static final int START_PROFILES_MSG = 40;
1154    static final int UPDATE_TIME = 41;
1155    static final int SYSTEM_USER_START_MSG = 42;
1156    static final int SYSTEM_USER_CURRENT_MSG = 43;
1157
1158    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1159    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1160    static final int FIRST_COMPAT_MODE_MSG = 300;
1161    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1162
1163    AlertDialog mUidAlert;
1164    CompatModeDialog mCompatModeDialog;
1165    long mLastMemUsageReportTime = 0;
1166
1167    private LockToAppRequestDialog mLockToAppRequest;
1168
1169    /**
1170     * Flag whether the current user is a "monkey", i.e. whether
1171     * the UI is driven by a UI automation tool.
1172     */
1173    private boolean mUserIsMonkey;
1174
1175    final ServiceThread mHandlerThread;
1176    final MainHandler mHandler;
1177
1178    final class MainHandler extends Handler {
1179        public MainHandler(Looper looper) {
1180            super(looper, null, true);
1181        }
1182
1183        @Override
1184        public void handleMessage(Message msg) {
1185            switch (msg.what) {
1186            case SHOW_ERROR_MSG: {
1187                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1188                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1189                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1190                synchronized (ActivityManagerService.this) {
1191                    ProcessRecord proc = (ProcessRecord)data.get("app");
1192                    AppErrorResult res = (AppErrorResult) data.get("result");
1193                    if (proc != null && proc.crashDialog != null) {
1194                        Slog.e(TAG, "App already has crash dialog: " + proc);
1195                        if (res != null) {
1196                            res.set(0);
1197                        }
1198                        return;
1199                    }
1200                    if (!showBackground && UserHandle.getAppId(proc.uid)
1201                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1202                            && proc.pid != MY_PID) {
1203                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1204                        if (res != null) {
1205                            res.set(0);
1206                        }
1207                        return;
1208                    }
1209                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1210                        Dialog d = new AppErrorDialog(mContext,
1211                                ActivityManagerService.this, res, proc);
1212                        d.show();
1213                        proc.crashDialog = d;
1214                    } else {
1215                        // The device is asleep, so just pretend that the user
1216                        // saw a crash dialog and hit "force quit".
1217                        if (res != null) {
1218                            res.set(0);
1219                        }
1220                    }
1221                }
1222
1223                ensureBootCompleted();
1224            } break;
1225            case SHOW_NOT_RESPONDING_MSG: {
1226                synchronized (ActivityManagerService.this) {
1227                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1228                    ProcessRecord proc = (ProcessRecord)data.get("app");
1229                    if (proc != null && proc.anrDialog != null) {
1230                        Slog.e(TAG, "App already has anr dialog: " + proc);
1231                        return;
1232                    }
1233
1234                    Intent intent = new Intent("android.intent.action.ANR");
1235                    if (!mProcessesReady) {
1236                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1237                                | Intent.FLAG_RECEIVER_FOREGROUND);
1238                    }
1239                    broadcastIntentLocked(null, null, intent,
1240                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1241                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1242
1243                    if (mShowDialogs) {
1244                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1245                                mContext, proc, (ActivityRecord)data.get("activity"),
1246                                msg.arg1 != 0);
1247                        d.show();
1248                        proc.anrDialog = d;
1249                    } else {
1250                        // Just kill the app if there is no dialog to be shown.
1251                        killAppAtUsersRequest(proc, null);
1252                    }
1253                }
1254
1255                ensureBootCompleted();
1256            } break;
1257            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1258                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1259                synchronized (ActivityManagerService.this) {
1260                    ProcessRecord proc = (ProcessRecord) data.get("app");
1261                    if (proc == null) {
1262                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1263                        break;
1264                    }
1265                    if (proc.crashDialog != null) {
1266                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1267                        return;
1268                    }
1269                    AppErrorResult res = (AppErrorResult) data.get("result");
1270                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1271                        Dialog d = new StrictModeViolationDialog(mContext,
1272                                ActivityManagerService.this, res, proc);
1273                        d.show();
1274                        proc.crashDialog = d;
1275                    } else {
1276                        // The device is asleep, so just pretend that the user
1277                        // saw a crash dialog and hit "force quit".
1278                        res.set(0);
1279                    }
1280                }
1281                ensureBootCompleted();
1282            } break;
1283            case SHOW_FACTORY_ERROR_MSG: {
1284                Dialog d = new FactoryErrorDialog(
1285                    mContext, msg.getData().getCharSequence("msg"));
1286                d.show();
1287                ensureBootCompleted();
1288            } break;
1289            case UPDATE_CONFIGURATION_MSG: {
1290                final ContentResolver resolver = mContext.getContentResolver();
1291                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1292            } break;
1293            case GC_BACKGROUND_PROCESSES_MSG: {
1294                synchronized (ActivityManagerService.this) {
1295                    performAppGcsIfAppropriateLocked();
1296                }
1297            } break;
1298            case WAIT_FOR_DEBUGGER_MSG: {
1299                synchronized (ActivityManagerService.this) {
1300                    ProcessRecord app = (ProcessRecord)msg.obj;
1301                    if (msg.arg1 != 0) {
1302                        if (!app.waitedForDebugger) {
1303                            Dialog d = new AppWaitingForDebuggerDialog(
1304                                    ActivityManagerService.this,
1305                                    mContext, app);
1306                            app.waitDialog = d;
1307                            app.waitedForDebugger = true;
1308                            d.show();
1309                        }
1310                    } else {
1311                        if (app.waitDialog != null) {
1312                            app.waitDialog.dismiss();
1313                            app.waitDialog = null;
1314                        }
1315                    }
1316                }
1317            } break;
1318            case SERVICE_TIMEOUT_MSG: {
1319                if (mDidDexOpt) {
1320                    mDidDexOpt = false;
1321                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1322                    nmsg.obj = msg.obj;
1323                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1324                    return;
1325                }
1326                mServices.serviceTimeout((ProcessRecord)msg.obj);
1327            } break;
1328            case UPDATE_TIME_ZONE: {
1329                synchronized (ActivityManagerService.this) {
1330                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1331                        ProcessRecord r = mLruProcesses.get(i);
1332                        if (r.thread != null) {
1333                            try {
1334                                r.thread.updateTimeZone();
1335                            } catch (RemoteException ex) {
1336                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1337                            }
1338                        }
1339                    }
1340                }
1341            } break;
1342            case CLEAR_DNS_CACHE_MSG: {
1343                synchronized (ActivityManagerService.this) {
1344                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1345                        ProcessRecord r = mLruProcesses.get(i);
1346                        if (r.thread != null) {
1347                            try {
1348                                r.thread.clearDnsCache();
1349                            } catch (RemoteException ex) {
1350                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1351                            }
1352                        }
1353                    }
1354                }
1355            } break;
1356            case UPDATE_HTTP_PROXY_MSG: {
1357                ProxyInfo proxy = (ProxyInfo)msg.obj;
1358                String host = "";
1359                String port = "";
1360                String exclList = "";
1361                Uri pacFileUrl = Uri.EMPTY;
1362                if (proxy != null) {
1363                    host = proxy.getHost();
1364                    port = Integer.toString(proxy.getPort());
1365                    exclList = proxy.getExclusionListAsString();
1366                    pacFileUrl = proxy.getPacFileUrl();
1367                }
1368                synchronized (ActivityManagerService.this) {
1369                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1370                        ProcessRecord r = mLruProcesses.get(i);
1371                        if (r.thread != null) {
1372                            try {
1373                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1374                            } catch (RemoteException ex) {
1375                                Slog.w(TAG, "Failed to update http proxy for: " +
1376                                        r.info.processName);
1377                            }
1378                        }
1379                    }
1380                }
1381            } break;
1382            case SHOW_UID_ERROR_MSG: {
1383                String title = "System UIDs Inconsistent";
1384                String text = "UIDs on the system are inconsistent, you need to wipe your"
1385                        + " data partition or your device will be unstable.";
1386                Log.e(TAG, title + ": " + text);
1387                if (mShowDialogs) {
1388                    // XXX This is a temporary dialog, no need to localize.
1389                    AlertDialog d = new BaseErrorDialog(mContext);
1390                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1391                    d.setCancelable(false);
1392                    d.setTitle(title);
1393                    d.setMessage(text);
1394                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1395                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1396                    mUidAlert = d;
1397                    d.show();
1398                }
1399            } break;
1400            case IM_FEELING_LUCKY_MSG: {
1401                if (mUidAlert != null) {
1402                    mUidAlert.dismiss();
1403                    mUidAlert = null;
1404                }
1405            } break;
1406            case PROC_START_TIMEOUT_MSG: {
1407                if (mDidDexOpt) {
1408                    mDidDexOpt = false;
1409                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1410                    nmsg.obj = msg.obj;
1411                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1412                    return;
1413                }
1414                ProcessRecord app = (ProcessRecord)msg.obj;
1415                synchronized (ActivityManagerService.this) {
1416                    processStartTimedOutLocked(app);
1417                }
1418            } break;
1419            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1420                synchronized (ActivityManagerService.this) {
1421                    doPendingActivityLaunchesLocked(true);
1422                }
1423            } break;
1424            case KILL_APPLICATION_MSG: {
1425                synchronized (ActivityManagerService.this) {
1426                    int appid = msg.arg1;
1427                    boolean restart = (msg.arg2 == 1);
1428                    Bundle bundle = (Bundle)msg.obj;
1429                    String pkg = bundle.getString("pkg");
1430                    String reason = bundle.getString("reason");
1431                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1432                            false, UserHandle.USER_ALL, reason);
1433                }
1434            } break;
1435            case FINALIZE_PENDING_INTENT_MSG: {
1436                ((PendingIntentRecord)msg.obj).completeFinalize();
1437            } break;
1438            case POST_HEAVY_NOTIFICATION_MSG: {
1439                INotificationManager inm = NotificationManager.getService();
1440                if (inm == null) {
1441                    return;
1442                }
1443
1444                ActivityRecord root = (ActivityRecord)msg.obj;
1445                ProcessRecord process = root.app;
1446                if (process == null) {
1447                    return;
1448                }
1449
1450                try {
1451                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1452                    String text = mContext.getString(R.string.heavy_weight_notification,
1453                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1454                    Notification notification = new Notification();
1455                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1456                    notification.when = 0;
1457                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1458                    notification.tickerText = text;
1459                    notification.defaults = 0; // please be quiet
1460                    notification.sound = null;
1461                    notification.vibrate = null;
1462                    notification.setLatestEventInfo(context, text,
1463                            mContext.getText(R.string.heavy_weight_notification_detail),
1464                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1465                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1466                                    new UserHandle(root.userId)));
1467
1468                    try {
1469                        int[] outId = new int[1];
1470                        inm.enqueueNotificationWithTag("android", "android", null,
1471                                R.string.heavy_weight_notification,
1472                                notification, outId, root.userId);
1473                    } catch (RuntimeException e) {
1474                        Slog.w(ActivityManagerService.TAG,
1475                                "Error showing notification for heavy-weight app", e);
1476                    } catch (RemoteException e) {
1477                    }
1478                } catch (NameNotFoundException e) {
1479                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1480                }
1481            } break;
1482            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1483                INotificationManager inm = NotificationManager.getService();
1484                if (inm == null) {
1485                    return;
1486                }
1487                try {
1488                    inm.cancelNotificationWithTag("android", null,
1489                            R.string.heavy_weight_notification,  msg.arg1);
1490                } catch (RuntimeException e) {
1491                    Slog.w(ActivityManagerService.TAG,
1492                            "Error canceling notification for service", e);
1493                } catch (RemoteException e) {
1494                }
1495            } break;
1496            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1497                synchronized (ActivityManagerService.this) {
1498                    checkExcessivePowerUsageLocked(true);
1499                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1500                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1501                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1502                }
1503            } break;
1504            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1505                synchronized (ActivityManagerService.this) {
1506                    ActivityRecord ar = (ActivityRecord)msg.obj;
1507                    if (mCompatModeDialog != null) {
1508                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1509                                ar.info.applicationInfo.packageName)) {
1510                            return;
1511                        }
1512                        mCompatModeDialog.dismiss();
1513                        mCompatModeDialog = null;
1514                    }
1515                    if (ar != null && false) {
1516                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1517                                ar.packageName)) {
1518                            int mode = mCompatModePackages.computeCompatModeLocked(
1519                                    ar.info.applicationInfo);
1520                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1521                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1522                                mCompatModeDialog = new CompatModeDialog(
1523                                        ActivityManagerService.this, mContext,
1524                                        ar.info.applicationInfo);
1525                                mCompatModeDialog.show();
1526                            }
1527                        }
1528                    }
1529                }
1530                break;
1531            }
1532            case DISPATCH_PROCESSES_CHANGED: {
1533                dispatchProcessesChanged();
1534                break;
1535            }
1536            case DISPATCH_PROCESS_DIED: {
1537                final int pid = msg.arg1;
1538                final int uid = msg.arg2;
1539                dispatchProcessDied(pid, uid);
1540                break;
1541            }
1542            case REPORT_MEM_USAGE_MSG: {
1543                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1544                Thread thread = new Thread() {
1545                    @Override public void run() {
1546                        final SparseArray<ProcessMemInfo> infoMap
1547                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1548                        for (int i=0, N=memInfos.size(); i<N; i++) {
1549                            ProcessMemInfo mi = memInfos.get(i);
1550                            infoMap.put(mi.pid, mi);
1551                        }
1552                        updateCpuStatsNow();
1553                        synchronized (mProcessCpuThread) {
1554                            final int N = mProcessCpuTracker.countStats();
1555                            for (int i=0; i<N; i++) {
1556                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1557                                if (st.vsize > 0) {
1558                                    long pss = Debug.getPss(st.pid, null);
1559                                    if (pss > 0) {
1560                                        if (infoMap.indexOfKey(st.pid) < 0) {
1561                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1562                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1563                                            mi.pss = pss;
1564                                            memInfos.add(mi);
1565                                        }
1566                                    }
1567                                }
1568                            }
1569                        }
1570
1571                        long totalPss = 0;
1572                        for (int i=0, N=memInfos.size(); i<N; i++) {
1573                            ProcessMemInfo mi = memInfos.get(i);
1574                            if (mi.pss == 0) {
1575                                mi.pss = Debug.getPss(mi.pid, null);
1576                            }
1577                            totalPss += mi.pss;
1578                        }
1579                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1580                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1581                                if (lhs.oomAdj != rhs.oomAdj) {
1582                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1583                                }
1584                                if (lhs.pss != rhs.pss) {
1585                                    return lhs.pss < rhs.pss ? 1 : -1;
1586                                }
1587                                return 0;
1588                            }
1589                        });
1590
1591                        StringBuilder tag = new StringBuilder(128);
1592                        StringBuilder stack = new StringBuilder(128);
1593                        tag.append("Low on memory -- ");
1594                        appendMemBucket(tag, totalPss, "total", false);
1595                        appendMemBucket(stack, totalPss, "total", true);
1596
1597                        StringBuilder logBuilder = new StringBuilder(1024);
1598                        logBuilder.append("Low on memory:\n");
1599
1600                        boolean firstLine = true;
1601                        int lastOomAdj = Integer.MIN_VALUE;
1602                        for (int i=0, N=memInfos.size(); i<N; i++) {
1603                            ProcessMemInfo mi = memInfos.get(i);
1604
1605                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1606                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1607                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1608                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1609                                if (lastOomAdj != mi.oomAdj) {
1610                                    lastOomAdj = mi.oomAdj;
1611                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1612                                        tag.append(" / ");
1613                                    }
1614                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1615                                        if (firstLine) {
1616                                            stack.append(":");
1617                                            firstLine = false;
1618                                        }
1619                                        stack.append("\n\t at ");
1620                                    } else {
1621                                        stack.append("$");
1622                                    }
1623                                } else {
1624                                    tag.append(" ");
1625                                    stack.append("$");
1626                                }
1627                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1628                                    appendMemBucket(tag, mi.pss, mi.name, false);
1629                                }
1630                                appendMemBucket(stack, mi.pss, mi.name, true);
1631                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1632                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1633                                    stack.append("(");
1634                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1635                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1636                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1637                                            stack.append(":");
1638                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1639                                        }
1640                                    }
1641                                    stack.append(")");
1642                                }
1643                            }
1644
1645                            logBuilder.append("  ");
1646                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1647                            logBuilder.append(' ');
1648                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1649                            logBuilder.append(' ');
1650                            ProcessList.appendRamKb(logBuilder, mi.pss);
1651                            logBuilder.append(" kB: ");
1652                            logBuilder.append(mi.name);
1653                            logBuilder.append(" (");
1654                            logBuilder.append(mi.pid);
1655                            logBuilder.append(") ");
1656                            logBuilder.append(mi.adjType);
1657                            logBuilder.append('\n');
1658                            if (mi.adjReason != null) {
1659                                logBuilder.append("                      ");
1660                                logBuilder.append(mi.adjReason);
1661                                logBuilder.append('\n');
1662                            }
1663                        }
1664
1665                        logBuilder.append("           ");
1666                        ProcessList.appendRamKb(logBuilder, totalPss);
1667                        logBuilder.append(" kB: TOTAL\n");
1668
1669                        long[] infos = new long[Debug.MEMINFO_COUNT];
1670                        Debug.getMemInfo(infos);
1671                        logBuilder.append("  MemInfo: ");
1672                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1673                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1674                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1675                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1676                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1677                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1678                            logBuilder.append("  ZRAM: ");
1679                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1680                            logBuilder.append(" kB RAM, ");
1681                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1682                            logBuilder.append(" kB swap total, ");
1683                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1684                            logBuilder.append(" kB swap free\n");
1685                        }
1686                        Slog.i(TAG, logBuilder.toString());
1687
1688                        StringBuilder dropBuilder = new StringBuilder(1024);
1689                        /*
1690                        StringWriter oomSw = new StringWriter();
1691                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1692                        StringWriter catSw = new StringWriter();
1693                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1694                        String[] emptyArgs = new String[] { };
1695                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1696                        oomPw.flush();
1697                        String oomString = oomSw.toString();
1698                        */
1699                        dropBuilder.append(stack);
1700                        dropBuilder.append('\n');
1701                        dropBuilder.append('\n');
1702                        dropBuilder.append(logBuilder);
1703                        dropBuilder.append('\n');
1704                        /*
1705                        dropBuilder.append(oomString);
1706                        dropBuilder.append('\n');
1707                        */
1708                        StringWriter catSw = new StringWriter();
1709                        synchronized (ActivityManagerService.this) {
1710                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1711                            String[] emptyArgs = new String[] { };
1712                            catPw.println();
1713                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1714                            catPw.println();
1715                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1716                                    false, false, null);
1717                            catPw.println();
1718                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1719                            catPw.flush();
1720                        }
1721                        dropBuilder.append(catSw.toString());
1722                        addErrorToDropBox("lowmem", null, "system_server", null,
1723                                null, tag.toString(), dropBuilder.toString(), null, null);
1724                        //Slog.i(TAG, "Sent to dropbox:");
1725                        //Slog.i(TAG, dropBuilder.toString());
1726                        synchronized (ActivityManagerService.this) {
1727                            long now = SystemClock.uptimeMillis();
1728                            if (mLastMemUsageReportTime < now) {
1729                                mLastMemUsageReportTime = now;
1730                            }
1731                        }
1732                    }
1733                };
1734                thread.start();
1735                break;
1736            }
1737            case REPORT_USER_SWITCH_MSG: {
1738                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1739                break;
1740            }
1741            case CONTINUE_USER_SWITCH_MSG: {
1742                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1743                break;
1744            }
1745            case USER_SWITCH_TIMEOUT_MSG: {
1746                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1747                break;
1748            }
1749            case IMMERSIVE_MODE_LOCK_MSG: {
1750                final boolean nextState = (msg.arg1 != 0);
1751                if (mUpdateLock.isHeld() != nextState) {
1752                    if (DEBUG_IMMERSIVE) {
1753                        final ActivityRecord r = (ActivityRecord) msg.obj;
1754                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1755                    }
1756                    if (nextState) {
1757                        mUpdateLock.acquire();
1758                    } else {
1759                        mUpdateLock.release();
1760                    }
1761                }
1762                break;
1763            }
1764            case PERSIST_URI_GRANTS_MSG: {
1765                writeGrantedUriPermissions();
1766                break;
1767            }
1768            case REQUEST_ALL_PSS_MSG: {
1769                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1770                break;
1771            }
1772            case START_PROFILES_MSG: {
1773                synchronized (ActivityManagerService.this) {
1774                    startProfilesLocked();
1775                }
1776                break;
1777            }
1778            case UPDATE_TIME: {
1779                synchronized (ActivityManagerService.this) {
1780                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1781                        ProcessRecord r = mLruProcesses.get(i);
1782                        if (r.thread != null) {
1783                            try {
1784                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1785                            } catch (RemoteException ex) {
1786                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1787                            }
1788                        }
1789                    }
1790                }
1791                break;
1792            }
1793            case SYSTEM_USER_START_MSG: {
1794                mSystemServiceManager.startUser(msg.arg1);
1795                break;
1796            }
1797            case SYSTEM_USER_CURRENT_MSG: {
1798                mSystemServiceManager.switchUser(msg.arg1);
1799                break;
1800            }
1801            }
1802        }
1803    };
1804
1805    static final int COLLECT_PSS_BG_MSG = 1;
1806
1807    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1808        @Override
1809        public void handleMessage(Message msg) {
1810            switch (msg.what) {
1811            case COLLECT_PSS_BG_MSG: {
1812                long start = SystemClock.uptimeMillis();
1813                MemInfoReader memInfo = null;
1814                synchronized (ActivityManagerService.this) {
1815                    if (mFullPssPending) {
1816                        mFullPssPending = false;
1817                        memInfo = new MemInfoReader();
1818                    }
1819                }
1820                if (memInfo != null) {
1821                    updateCpuStatsNow();
1822                    long nativeTotalPss = 0;
1823                    synchronized (mProcessCpuThread) {
1824                        final int N = mProcessCpuTracker.countStats();
1825                        for (int j=0; j<N; j++) {
1826                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1827                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1828                                // This is definitely an application process; skip it.
1829                                continue;
1830                            }
1831                            synchronized (mPidsSelfLocked) {
1832                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1833                                    // This is one of our own processes; skip it.
1834                                    continue;
1835                                }
1836                            }
1837                            nativeTotalPss += Debug.getPss(st.pid, null);
1838                        }
1839                    }
1840                    memInfo.readMemInfo();
1841                    synchronized (this) {
1842                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1843                                + (SystemClock.uptimeMillis()-start) + "ms");
1844                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1845                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1846                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1847                                        +memInfo.getSlabSizeKb(),
1848                                nativeTotalPss);
1849                    }
1850                }
1851
1852                int i=0, num=0;
1853                long[] tmp = new long[1];
1854                do {
1855                    ProcessRecord proc;
1856                    int procState;
1857                    int pid;
1858                    synchronized (ActivityManagerService.this) {
1859                        if (i >= mPendingPssProcesses.size()) {
1860                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1861                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1862                            mPendingPssProcesses.clear();
1863                            return;
1864                        }
1865                        proc = mPendingPssProcesses.get(i);
1866                        procState = proc.pssProcState;
1867                        if (proc.thread != null && procState == proc.setProcState) {
1868                            pid = proc.pid;
1869                        } else {
1870                            proc = null;
1871                            pid = 0;
1872                        }
1873                        i++;
1874                    }
1875                    if (proc != null) {
1876                        long pss = Debug.getPss(pid, tmp);
1877                        synchronized (ActivityManagerService.this) {
1878                            if (proc.thread != null && proc.setProcState == procState
1879                                    && proc.pid == pid) {
1880                                num++;
1881                                proc.lastPssTime = SystemClock.uptimeMillis();
1882                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1883                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1884                                        + ": " + pss + " lastPss=" + proc.lastPss
1885                                        + " state=" + ProcessList.makeProcStateString(procState));
1886                                if (proc.initialIdlePss == 0) {
1887                                    proc.initialIdlePss = pss;
1888                                }
1889                                proc.lastPss = pss;
1890                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1891                                    proc.lastCachedPss = pss;
1892                                }
1893                            }
1894                        }
1895                    }
1896                } while (true);
1897            }
1898            }
1899        }
1900    };
1901
1902    /**
1903     * Monitor for package changes and update our internal state.
1904     */
1905    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1906        @Override
1907        public void onPackageRemoved(String packageName, int uid) {
1908            // Remove all tasks with activities in the specified package from the list of recent tasks
1909            synchronized (ActivityManagerService.this) {
1910                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1911                    TaskRecord tr = mRecentTasks.get(i);
1912                    ComponentName cn = tr.intent.getComponent();
1913                    if (cn != null && cn.getPackageName().equals(packageName)) {
1914                        // If the package name matches, remove the task and kill the process
1915                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1916                    }
1917                }
1918            }
1919        }
1920
1921        @Override
1922        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1923            onPackageModified(packageName);
1924            return true;
1925        }
1926
1927        @Override
1928        public void onPackageModified(String packageName) {
1929            final PackageManager pm = mContext.getPackageManager();
1930            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1931                    new ArrayList<Pair<Intent, Integer>>();
1932            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1933            // Copy the list of recent tasks so that we don't hold onto the lock on
1934            // ActivityManagerService for long periods while checking if components exist.
1935            synchronized (ActivityManagerService.this) {
1936                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1937                    TaskRecord tr = mRecentTasks.get(i);
1938                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1939                }
1940            }
1941            // Check the recent tasks and filter out all tasks with components that no longer exist.
1942            Intent tmpI = new Intent();
1943            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1944                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1945                ComponentName cn = p.first.getComponent();
1946                if (cn != null && cn.getPackageName().equals(packageName)) {
1947                    try {
1948                        // Add the task to the list to remove if the component no longer exists
1949                        tmpI.setComponent(cn);
1950                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1951                            tasksToRemove.add(p.second);
1952                        }
1953                    } catch (Exception e) {}
1954                }
1955            }
1956            // Prune all the tasks with removed components from the list of recent tasks
1957            synchronized (ActivityManagerService.this) {
1958                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1959                    // Remove the task but don't kill the process (since other components in that
1960                    // package may still be running and in the background)
1961                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1962                }
1963            }
1964        }
1965
1966        @Override
1967        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1968            // Force stop the specified packages
1969            if (packages != null) {
1970                for (String pkg : packages) {
1971                    synchronized (ActivityManagerService.this) {
1972                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
1973                                "finished booting")) {
1974                            return true;
1975                        }
1976                    }
1977                }
1978            }
1979            return false;
1980        }
1981    };
1982
1983    public void setSystemProcess() {
1984        try {
1985            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1986            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1987            ServiceManager.addService("meminfo", new MemBinder(this));
1988            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1989            ServiceManager.addService("dbinfo", new DbBinder(this));
1990            if (MONITOR_CPU_USAGE) {
1991                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1992            }
1993            ServiceManager.addService("permission", new PermissionController(this));
1994
1995            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1996                    "android", STOCK_PM_FLAGS);
1997            mSystemThread.installSystemApplicationInfo(info);
1998
1999            synchronized (this) {
2000                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
2001                app.persistent = true;
2002                app.pid = MY_PID;
2003                app.maxAdj = ProcessList.SYSTEM_ADJ;
2004                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2005                mProcessNames.put(app.processName, app.uid, app);
2006                synchronized (mPidsSelfLocked) {
2007                    mPidsSelfLocked.put(app.pid, app);
2008                }
2009                updateLruProcessLocked(app, false, null);
2010                updateOomAdjLocked();
2011            }
2012        } catch (PackageManager.NameNotFoundException e) {
2013            throw new RuntimeException(
2014                    "Unable to find android system package", e);
2015        }
2016    }
2017
2018    public void setWindowManager(WindowManagerService wm) {
2019        mWindowManager = wm;
2020        mStackSupervisor.setWindowManager(wm);
2021    }
2022
2023    public void startObservingNativeCrashes() {
2024        final NativeCrashListener ncl = new NativeCrashListener(this);
2025        ncl.start();
2026    }
2027
2028    public IAppOpsService getAppOpsService() {
2029        return mAppOpsService;
2030    }
2031
2032    static class MemBinder extends Binder {
2033        ActivityManagerService mActivityManagerService;
2034        MemBinder(ActivityManagerService activityManagerService) {
2035            mActivityManagerService = activityManagerService;
2036        }
2037
2038        @Override
2039        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2040            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2041                    != PackageManager.PERMISSION_GRANTED) {
2042                pw.println("Permission Denial: can't dump meminfo from from pid="
2043                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2044                        + " without permission " + android.Manifest.permission.DUMP);
2045                return;
2046            }
2047
2048            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2049        }
2050    }
2051
2052    static class GraphicsBinder extends Binder {
2053        ActivityManagerService mActivityManagerService;
2054        GraphicsBinder(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 gfxinfo from from pid="
2063                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2064                        + " without permission " + android.Manifest.permission.DUMP);
2065                return;
2066            }
2067
2068            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2069        }
2070    }
2071
2072    static class DbBinder extends Binder {
2073        ActivityManagerService mActivityManagerService;
2074        DbBinder(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 dbinfo from from pid="
2083                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2084                        + " without permission " + android.Manifest.permission.DUMP);
2085                return;
2086            }
2087
2088            mActivityManagerService.dumpDbInfo(fd, pw, args);
2089        }
2090    }
2091
2092    static class CpuBinder extends Binder {
2093        ActivityManagerService mActivityManagerService;
2094        CpuBinder(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 cpuinfo from from pid="
2103                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2104                        + " without permission " + android.Manifest.permission.DUMP);
2105                return;
2106            }
2107
2108            synchronized (mActivityManagerService.mProcessCpuThread) {
2109                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2110                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2111                        SystemClock.uptimeMillis()));
2112            }
2113        }
2114    }
2115
2116    public static final class Lifecycle extends SystemService {
2117        private final ActivityManagerService mService;
2118
2119        public Lifecycle(Context context) {
2120            super(context);
2121            mService = new ActivityManagerService(context);
2122        }
2123
2124        @Override
2125        public void onStart() {
2126            mService.start();
2127        }
2128
2129        public ActivityManagerService getService() {
2130            return mService;
2131        }
2132    }
2133
2134    // Note: This method is invoked on the main thread but may need to attach various
2135    // handlers to other threads.  So take care to be explicit about the looper.
2136    public ActivityManagerService(Context systemContext) {
2137        mContext = systemContext;
2138        mFactoryTest = FactoryTest.getMode();
2139        mSystemThread = ActivityThread.currentActivityThread();
2140
2141        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2142
2143        mHandlerThread = new ServiceThread(TAG,
2144                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2145        mHandlerThread.start();
2146        mHandler = new MainHandler(mHandlerThread.getLooper());
2147
2148        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2149                "foreground", BROADCAST_FG_TIMEOUT, false);
2150        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2151                "background", BROADCAST_BG_TIMEOUT, true);
2152        mBroadcastQueues[0] = mFgBroadcastQueue;
2153        mBroadcastQueues[1] = mBgBroadcastQueue;
2154
2155        mServices = new ActiveServices(this);
2156        mProviderMap = new ProviderMap(this);
2157
2158        // TODO: Move creation of battery stats service outside of activity manager service.
2159        File dataDir = Environment.getDataDirectory();
2160        File systemDir = new File(dataDir, "system");
2161        systemDir.mkdirs();
2162        mBatteryStatsService = new BatteryStatsService(new File(
2163                systemDir, "batterystats.bin").toString(), mHandler);
2164        mBatteryStatsService.getActiveStatistics().readLocked();
2165        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2166        mOnBattery = DEBUG_POWER ? true
2167                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2168        mBatteryStatsService.getActiveStatistics().setCallback(this);
2169
2170        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2171
2172        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
2173        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2174
2175        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2176
2177        // User 0 is the first and only user that runs at boot.
2178        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2179        mUserLru.add(Integer.valueOf(0));
2180        updateStartedUserArrayLocked();
2181
2182        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2183            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2184
2185        mConfiguration.setToDefaults();
2186        mConfiguration.setLocale(Locale.getDefault());
2187
2188        mConfigurationSeq = mConfiguration.seq = 1;
2189        mProcessCpuTracker.init();
2190
2191        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2192        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2193        mStackSupervisor = new ActivityStackSupervisor(this);
2194        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2195
2196        mProcessCpuThread = new Thread("CpuTracker") {
2197            @Override
2198            public void run() {
2199                while (true) {
2200                    try {
2201                        try {
2202                            synchronized(this) {
2203                                final long now = SystemClock.uptimeMillis();
2204                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2205                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2206                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2207                                //        + ", write delay=" + nextWriteDelay);
2208                                if (nextWriteDelay < nextCpuDelay) {
2209                                    nextCpuDelay = nextWriteDelay;
2210                                }
2211                                if (nextCpuDelay > 0) {
2212                                    mProcessCpuMutexFree.set(true);
2213                                    this.wait(nextCpuDelay);
2214                                }
2215                            }
2216                        } catch (InterruptedException e) {
2217                        }
2218                        updateCpuStatsNow();
2219                    } catch (Exception e) {
2220                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2221                    }
2222                }
2223            }
2224        };
2225
2226        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2227
2228        Watchdog.getInstance().addMonitor(this);
2229        Watchdog.getInstance().addThread(mHandler);
2230    }
2231
2232    public void setSystemServiceManager(SystemServiceManager mgr) {
2233        mSystemServiceManager = mgr;
2234    }
2235
2236    private void start() {
2237        mProcessCpuThread.start();
2238
2239        mBatteryStatsService.publish(mContext);
2240        mUsageStatsService.publish(mContext);
2241        mAppOpsService.publish(mContext);
2242        Slog.d("AppOps", "AppOpsService published");
2243        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2244    }
2245
2246    public void initPowerManagement() {
2247        mStackSupervisor.initPowerManagement();
2248        mBatteryStatsService.initPowerManagement();
2249    }
2250
2251    @Override
2252    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2253            throws RemoteException {
2254        if (code == SYSPROPS_TRANSACTION) {
2255            // We need to tell all apps about the system property change.
2256            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2257            synchronized(this) {
2258                final int NP = mProcessNames.getMap().size();
2259                for (int ip=0; ip<NP; ip++) {
2260                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2261                    final int NA = apps.size();
2262                    for (int ia=0; ia<NA; ia++) {
2263                        ProcessRecord app = apps.valueAt(ia);
2264                        if (app.thread != null) {
2265                            procs.add(app.thread.asBinder());
2266                        }
2267                    }
2268                }
2269            }
2270
2271            int N = procs.size();
2272            for (int i=0; i<N; i++) {
2273                Parcel data2 = Parcel.obtain();
2274                try {
2275                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2276                } catch (RemoteException e) {
2277                }
2278                data2.recycle();
2279            }
2280        }
2281        try {
2282            return super.onTransact(code, data, reply, flags);
2283        } catch (RuntimeException e) {
2284            // The activity manager only throws security exceptions, so let's
2285            // log all others.
2286            if (!(e instanceof SecurityException)) {
2287                Slog.wtf(TAG, "Activity Manager Crash", e);
2288            }
2289            throw e;
2290        }
2291    }
2292
2293    void updateCpuStats() {
2294        final long now = SystemClock.uptimeMillis();
2295        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2296            return;
2297        }
2298        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2299            synchronized (mProcessCpuThread) {
2300                mProcessCpuThread.notify();
2301            }
2302        }
2303    }
2304
2305    void updateCpuStatsNow() {
2306        synchronized (mProcessCpuThread) {
2307            mProcessCpuMutexFree.set(false);
2308            final long now = SystemClock.uptimeMillis();
2309            boolean haveNewCpuStats = false;
2310
2311            if (MONITOR_CPU_USAGE &&
2312                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2313                mLastCpuTime.set(now);
2314                haveNewCpuStats = true;
2315                mProcessCpuTracker.update();
2316                //Slog.i(TAG, mProcessCpu.printCurrentState());
2317                //Slog.i(TAG, "Total CPU usage: "
2318                //        + mProcessCpu.getTotalCpuPercent() + "%");
2319
2320                // Slog the cpu usage if the property is set.
2321                if ("true".equals(SystemProperties.get("events.cpu"))) {
2322                    int user = mProcessCpuTracker.getLastUserTime();
2323                    int system = mProcessCpuTracker.getLastSystemTime();
2324                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2325                    int irq = mProcessCpuTracker.getLastIrqTime();
2326                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2327                    int idle = mProcessCpuTracker.getLastIdleTime();
2328
2329                    int total = user + system + iowait + irq + softIrq + idle;
2330                    if (total == 0) total = 1;
2331
2332                    EventLog.writeEvent(EventLogTags.CPU,
2333                            ((user+system+iowait+irq+softIrq) * 100) / total,
2334                            (user * 100) / total,
2335                            (system * 100) / total,
2336                            (iowait * 100) / total,
2337                            (irq * 100) / total,
2338                            (softIrq * 100) / total);
2339                }
2340            }
2341
2342            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2343            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2344            synchronized(bstats) {
2345                synchronized(mPidsSelfLocked) {
2346                    if (haveNewCpuStats) {
2347                        if (mOnBattery) {
2348                            int perc = bstats.startAddingCpuLocked();
2349                            int totalUTime = 0;
2350                            int totalSTime = 0;
2351                            final int N = mProcessCpuTracker.countStats();
2352                            for (int i=0; i<N; i++) {
2353                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2354                                if (!st.working) {
2355                                    continue;
2356                                }
2357                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2358                                int otherUTime = (st.rel_utime*perc)/100;
2359                                int otherSTime = (st.rel_stime*perc)/100;
2360                                totalUTime += otherUTime;
2361                                totalSTime += otherSTime;
2362                                if (pr != null) {
2363                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2364                                    if (ps == null || !ps.isActive()) {
2365                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2366                                                pr.info.uid, pr.processName);
2367                                    }
2368                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2369                                            st.rel_stime-otherSTime);
2370                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2371                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2372                                } else {
2373                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2374                                    if (ps == null || !ps.isActive()) {
2375                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2376                                                bstats.mapUid(st.uid), st.name);
2377                                    }
2378                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2379                                            st.rel_stime-otherSTime);
2380                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2381                                }
2382                            }
2383                            bstats.finishAddingCpuLocked(perc, totalUTime,
2384                                    totalSTime, cpuSpeedTimes);
2385                        }
2386                    }
2387                }
2388
2389                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2390                    mLastWriteTime = now;
2391                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2392                }
2393            }
2394        }
2395    }
2396
2397    @Override
2398    public void batteryNeedsCpuUpdate() {
2399        updateCpuStatsNow();
2400    }
2401
2402    @Override
2403    public void batteryPowerChanged(boolean onBattery) {
2404        // When plugging in, update the CPU stats first before changing
2405        // the plug state.
2406        updateCpuStatsNow();
2407        synchronized (this) {
2408            synchronized(mPidsSelfLocked) {
2409                mOnBattery = DEBUG_POWER ? true : onBattery;
2410            }
2411        }
2412    }
2413
2414    /**
2415     * Initialize the application bind args. These are passed to each
2416     * process when the bindApplication() IPC is sent to the process. They're
2417     * lazily setup to make sure the services are running when they're asked for.
2418     */
2419    private HashMap<String, IBinder> getCommonServicesLocked() {
2420        if (mAppBindArgs == null) {
2421            mAppBindArgs = new HashMap<String, IBinder>();
2422
2423            // Setup the application init args
2424            mAppBindArgs.put("package", ServiceManager.getService("package"));
2425            mAppBindArgs.put("window", ServiceManager.getService("window"));
2426            mAppBindArgs.put(Context.ALARM_SERVICE,
2427                    ServiceManager.getService(Context.ALARM_SERVICE));
2428        }
2429        return mAppBindArgs;
2430    }
2431
2432    final void setFocusedActivityLocked(ActivityRecord r) {
2433        if (mFocusedActivity != r) {
2434            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2435            mFocusedActivity = r;
2436            if (r.task != null && r.task.voiceInteractor != null) {
2437                startRunningVoiceLocked();
2438            } else {
2439                finishRunningVoiceLocked();
2440            }
2441            mStackSupervisor.setFocusedStack(r);
2442            if (r != null) {
2443                mWindowManager.setFocusedApp(r.appToken, true);
2444            }
2445            applyUpdateLockStateLocked(r);
2446        }
2447    }
2448
2449    final void clearFocusedActivity(ActivityRecord r) {
2450        if (mFocusedActivity == r) {
2451            mFocusedActivity = null;
2452        }
2453    }
2454
2455    @Override
2456    public void setFocusedStack(int stackId) {
2457        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2458        synchronized (ActivityManagerService.this) {
2459            ActivityStack stack = mStackSupervisor.getStack(stackId);
2460            if (stack != null) {
2461                ActivityRecord r = stack.topRunningActivityLocked(null);
2462                if (r != null) {
2463                    setFocusedActivityLocked(r);
2464                }
2465            }
2466        }
2467    }
2468
2469    @Override
2470    public void notifyActivityDrawn(IBinder token) {
2471        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2472        synchronized (this) {
2473            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2474            if (r != null) {
2475                r.task.stack.notifyActivityDrawnLocked(r);
2476            }
2477        }
2478    }
2479
2480    final void applyUpdateLockStateLocked(ActivityRecord r) {
2481        // Modifications to the UpdateLock state are done on our handler, outside
2482        // the activity manager's locks.  The new state is determined based on the
2483        // state *now* of the relevant activity record.  The object is passed to
2484        // the handler solely for logging detail, not to be consulted/modified.
2485        final boolean nextState = r != null && r.immersive;
2486        mHandler.sendMessage(
2487                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2488    }
2489
2490    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2491        Message msg = Message.obtain();
2492        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2493        msg.obj = r.task.askedCompatMode ? null : r;
2494        mHandler.sendMessage(msg);
2495    }
2496
2497    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2498            String what, Object obj, ProcessRecord srcApp) {
2499        app.lastActivityTime = now;
2500
2501        if (app.activities.size() > 0) {
2502            // Don't want to touch dependent processes that are hosting activities.
2503            return index;
2504        }
2505
2506        int lrui = mLruProcesses.lastIndexOf(app);
2507        if (lrui < 0) {
2508            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2509                    + what + " " + obj + " from " + srcApp);
2510            return index;
2511        }
2512
2513        if (lrui >= index) {
2514            // Don't want to cause this to move dependent processes *back* in the
2515            // list as if they were less frequently used.
2516            return index;
2517        }
2518
2519        if (lrui >= mLruProcessActivityStart) {
2520            // Don't want to touch dependent processes that are hosting activities.
2521            return index;
2522        }
2523
2524        mLruProcesses.remove(lrui);
2525        if (index > 0) {
2526            index--;
2527        }
2528        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2529                + " in LRU list: " + app);
2530        mLruProcesses.add(index, app);
2531        return index;
2532    }
2533
2534    final void removeLruProcessLocked(ProcessRecord app) {
2535        int lrui = mLruProcesses.lastIndexOf(app);
2536        if (lrui >= 0) {
2537            if (lrui <= mLruProcessActivityStart) {
2538                mLruProcessActivityStart--;
2539            }
2540            if (lrui <= mLruProcessServiceStart) {
2541                mLruProcessServiceStart--;
2542            }
2543            mLruProcesses.remove(lrui);
2544        }
2545    }
2546
2547    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2548            ProcessRecord client) {
2549        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2550                || app.treatLikeActivity;
2551        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2552        if (!activityChange && hasActivity) {
2553            // The process has activities, so we are only allowing activity-based adjustments
2554            // to move it.  It should be kept in the front of the list with other
2555            // processes that have activities, and we don't want those to change their
2556            // order except due to activity operations.
2557            return;
2558        }
2559
2560        mLruSeq++;
2561        final long now = SystemClock.uptimeMillis();
2562        app.lastActivityTime = now;
2563
2564        // First a quick reject: if the app is already at the position we will
2565        // put it, then there is nothing to do.
2566        if (hasActivity) {
2567            final int N = mLruProcesses.size();
2568            if (N > 0 && mLruProcesses.get(N-1) == app) {
2569                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2570                return;
2571            }
2572        } else {
2573            if (mLruProcessServiceStart > 0
2574                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2575                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2576                return;
2577            }
2578        }
2579
2580        int lrui = mLruProcesses.lastIndexOf(app);
2581
2582        if (app.persistent && lrui >= 0) {
2583            // We don't care about the position of persistent processes, as long as
2584            // they are in the list.
2585            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2586            return;
2587        }
2588
2589        /* In progress: compute new position first, so we can avoid doing work
2590           if the process is not actually going to move.  Not yet working.
2591        int addIndex;
2592        int nextIndex;
2593        boolean inActivity = false, inService = false;
2594        if (hasActivity) {
2595            // Process has activities, put it at the very tipsy-top.
2596            addIndex = mLruProcesses.size();
2597            nextIndex = mLruProcessServiceStart;
2598            inActivity = true;
2599        } else if (hasService) {
2600            // Process has services, put it at the top of the service list.
2601            addIndex = mLruProcessActivityStart;
2602            nextIndex = mLruProcessServiceStart;
2603            inActivity = true;
2604            inService = true;
2605        } else  {
2606            // Process not otherwise of interest, it goes to the top of the non-service area.
2607            addIndex = mLruProcessServiceStart;
2608            if (client != null) {
2609                int clientIndex = mLruProcesses.lastIndexOf(client);
2610                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2611                        + app);
2612                if (clientIndex >= 0 && addIndex > clientIndex) {
2613                    addIndex = clientIndex;
2614                }
2615            }
2616            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2617        }
2618
2619        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2620                + mLruProcessActivityStart + "): " + app);
2621        */
2622
2623        if (lrui >= 0) {
2624            if (lrui < mLruProcessActivityStart) {
2625                mLruProcessActivityStart--;
2626            }
2627            if (lrui < mLruProcessServiceStart) {
2628                mLruProcessServiceStart--;
2629            }
2630            /*
2631            if (addIndex > lrui) {
2632                addIndex--;
2633            }
2634            if (nextIndex > lrui) {
2635                nextIndex--;
2636            }
2637            */
2638            mLruProcesses.remove(lrui);
2639        }
2640
2641        /*
2642        mLruProcesses.add(addIndex, app);
2643        if (inActivity) {
2644            mLruProcessActivityStart++;
2645        }
2646        if (inService) {
2647            mLruProcessActivityStart++;
2648        }
2649        */
2650
2651        int nextIndex;
2652        if (hasActivity) {
2653            final int N = mLruProcesses.size();
2654            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2655                // Process doesn't have activities, but has clients with
2656                // activities...  move it up, but one below the top (the top
2657                // should always have a real activity).
2658                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2659                mLruProcesses.add(N-1, app);
2660                // To keep it from spamming the LRU list (by making a bunch of clients),
2661                // we will push down any other entries owned by the app.
2662                final int uid = app.info.uid;
2663                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2664                    ProcessRecord subProc = mLruProcesses.get(i);
2665                    if (subProc.info.uid == uid) {
2666                        // We want to push this one down the list.  If the process after
2667                        // it is for the same uid, however, don't do so, because we don't
2668                        // want them internally to be re-ordered.
2669                        if (mLruProcesses.get(i-1).info.uid != uid) {
2670                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2671                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2672                            ProcessRecord tmp = mLruProcesses.get(i);
2673                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2674                            mLruProcesses.set(i-1, tmp);
2675                            i--;
2676                        }
2677                    } else {
2678                        // A gap, we can stop here.
2679                        break;
2680                    }
2681                }
2682            } else {
2683                // Process has activities, put it at the very tipsy-top.
2684                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2685                mLruProcesses.add(app);
2686            }
2687            nextIndex = mLruProcessServiceStart;
2688        } else if (hasService) {
2689            // Process has services, put it at the top of the service list.
2690            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2691            mLruProcesses.add(mLruProcessActivityStart, app);
2692            nextIndex = mLruProcessServiceStart;
2693            mLruProcessActivityStart++;
2694        } else  {
2695            // Process not otherwise of interest, it goes to the top of the non-service area.
2696            int index = mLruProcessServiceStart;
2697            if (client != null) {
2698                // If there is a client, don't allow the process to be moved up higher
2699                // in the list than that client.
2700                int clientIndex = mLruProcesses.lastIndexOf(client);
2701                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2702                        + " when updating " + app);
2703                if (clientIndex <= lrui) {
2704                    // Don't allow the client index restriction to push it down farther in the
2705                    // list than it already is.
2706                    clientIndex = lrui;
2707                }
2708                if (clientIndex >= 0 && index > clientIndex) {
2709                    index = clientIndex;
2710                }
2711            }
2712            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2713            mLruProcesses.add(index, app);
2714            nextIndex = index-1;
2715            mLruProcessActivityStart++;
2716            mLruProcessServiceStart++;
2717        }
2718
2719        // If the app is currently using a content provider or service,
2720        // bump those processes as well.
2721        for (int j=app.connections.size()-1; j>=0; j--) {
2722            ConnectionRecord cr = app.connections.valueAt(j);
2723            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2724                    && cr.binding.service.app != null
2725                    && cr.binding.service.app.lruSeq != mLruSeq
2726                    && !cr.binding.service.app.persistent) {
2727                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2728                        "service connection", cr, app);
2729            }
2730        }
2731        for (int j=app.conProviders.size()-1; j>=0; j--) {
2732            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2733            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2734                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2735                        "provider reference", cpr, app);
2736            }
2737        }
2738    }
2739
2740    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2741        if (uid == Process.SYSTEM_UID) {
2742            // The system gets to run in any process.  If there are multiple
2743            // processes with the same uid, just pick the first (this
2744            // should never happen).
2745            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2746            if (procs == null) return null;
2747            final int N = procs.size();
2748            for (int i = 0; i < N; i++) {
2749                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2750            }
2751        }
2752        ProcessRecord proc = mProcessNames.get(processName, uid);
2753        if (false && proc != null && !keepIfLarge
2754                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2755                && proc.lastCachedPss >= 4000) {
2756            // Turn this condition on to cause killing to happen regularly, for testing.
2757            if (proc.baseProcessTracker != null) {
2758                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2759            }
2760            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2761                    + "k from cached");
2762        } else if (proc != null && !keepIfLarge
2763                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2764                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2765            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2766            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2767                if (proc.baseProcessTracker != null) {
2768                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2769                }
2770                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2771                        + "k from cached");
2772            }
2773        }
2774        return proc;
2775    }
2776
2777    void ensurePackageDexOpt(String packageName) {
2778        IPackageManager pm = AppGlobals.getPackageManager();
2779        try {
2780            if (pm.performDexOpt(packageName)) {
2781                mDidDexOpt = true;
2782            }
2783        } catch (RemoteException e) {
2784        }
2785    }
2786
2787    boolean isNextTransitionForward() {
2788        int transit = mWindowManager.getPendingAppTransition();
2789        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2790                || transit == AppTransition.TRANSIT_TASK_OPEN
2791                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2792    }
2793
2794    final ProcessRecord startProcessLocked(String processName,
2795            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2796            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2797            boolean isolated, boolean keepIfLarge) {
2798        ProcessRecord app;
2799        if (!isolated) {
2800            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2801        } else {
2802            // If this is an isolated process, it can't re-use an existing process.
2803            app = null;
2804        }
2805        // We don't have to do anything more if:
2806        // (1) There is an existing application record; and
2807        // (2) The caller doesn't think it is dead, OR there is no thread
2808        //     object attached to it so we know it couldn't have crashed; and
2809        // (3) There is a pid assigned to it, so it is either starting or
2810        //     already running.
2811        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2812                + " app=" + app + " knownToBeDead=" + knownToBeDead
2813                + " thread=" + (app != null ? app.thread : null)
2814                + " pid=" + (app != null ? app.pid : -1));
2815        if (app != null && app.pid > 0) {
2816            if (!knownToBeDead || app.thread == null) {
2817                // We already have the app running, or are waiting for it to
2818                // come up (we have a pid but not yet its thread), so keep it.
2819                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2820                // If this is a new package in the process, add the package to the list
2821                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2822                return app;
2823            }
2824
2825            // An application record is attached to a previous process,
2826            // clean it up now.
2827            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2828            handleAppDiedLocked(app, true, true);
2829        }
2830
2831        String hostingNameStr = hostingName != null
2832                ? hostingName.flattenToShortString() : null;
2833
2834        if (!isolated) {
2835            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2836                // If we are in the background, then check to see if this process
2837                // is bad.  If so, we will just silently fail.
2838                if (mBadProcesses.get(info.processName, info.uid) != null) {
2839                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2840                            + "/" + info.processName);
2841                    return null;
2842                }
2843            } else {
2844                // When the user is explicitly starting a process, then clear its
2845                // crash count so that we won't make it bad until they see at
2846                // least one crash dialog again, and make the process good again
2847                // if it had been bad.
2848                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2849                        + "/" + info.processName);
2850                mProcessCrashTimes.remove(info.processName, info.uid);
2851                if (mBadProcesses.get(info.processName, info.uid) != null) {
2852                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2853                            UserHandle.getUserId(info.uid), info.uid,
2854                            info.processName);
2855                    mBadProcesses.remove(info.processName, info.uid);
2856                    if (app != null) {
2857                        app.bad = false;
2858                    }
2859                }
2860            }
2861        }
2862
2863        if (app == null) {
2864            app = newProcessRecordLocked(info, processName, isolated);
2865            if (app == null) {
2866                Slog.w(TAG, "Failed making new process record for "
2867                        + processName + "/" + info.uid + " isolated=" + isolated);
2868                return null;
2869            }
2870            mProcessNames.put(processName, app.uid, app);
2871            if (isolated) {
2872                mIsolatedProcesses.put(app.uid, app);
2873            }
2874        } else {
2875            // If this is a new package in the process, add the package to the list
2876            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2877        }
2878
2879        // If the system is not ready yet, then hold off on starting this
2880        // process until it is.
2881        if (!mProcessesReady
2882                && !isAllowedWhileBooting(info)
2883                && !allowWhileBooting) {
2884            if (!mProcessesOnHold.contains(app)) {
2885                mProcessesOnHold.add(app);
2886            }
2887            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2888            return app;
2889        }
2890
2891        startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */);
2892        return (app.pid != 0) ? app : null;
2893    }
2894
2895    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2896        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2897    }
2898
2899    private final void startProcessLocked(ProcessRecord app,
2900            String hostingType, String hostingNameStr, String abiOverride) {
2901        if (app.pid > 0 && app.pid != MY_PID) {
2902            synchronized (mPidsSelfLocked) {
2903                mPidsSelfLocked.remove(app.pid);
2904                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2905            }
2906            app.setPid(0);
2907        }
2908
2909        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2910                "startProcessLocked removing on hold: " + app);
2911        mProcessesOnHold.remove(app);
2912
2913        updateCpuStats();
2914
2915        try {
2916            int uid = app.uid;
2917
2918            int[] gids = null;
2919            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2920            if (!app.isolated) {
2921                int[] permGids = null;
2922                try {
2923                    final PackageManager pm = mContext.getPackageManager();
2924                    permGids = pm.getPackageGids(app.info.packageName);
2925
2926                    if (Environment.isExternalStorageEmulated()) {
2927                        if (pm.checkPermission(
2928                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2929                                app.info.packageName) == PERMISSION_GRANTED) {
2930                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2931                        } else {
2932                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2933                        }
2934                    }
2935                } catch (PackageManager.NameNotFoundException e) {
2936                    Slog.w(TAG, "Unable to retrieve gids", e);
2937                }
2938
2939                /*
2940                 * Add shared application and profile GIDs so applications can share some
2941                 * resources like shared libraries and access user-wide resources
2942                 */
2943                if (permGids == null) {
2944                    gids = new int[2];
2945                } else {
2946                    gids = new int[permGids.length + 2];
2947                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2948                }
2949                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2950                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2951            }
2952            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2953                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2954                        && mTopComponent != null
2955                        && app.processName.equals(mTopComponent.getPackageName())) {
2956                    uid = 0;
2957                }
2958                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2959                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2960                    uid = 0;
2961                }
2962            }
2963            int debugFlags = 0;
2964            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2965                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2966                // Also turn on CheckJNI for debuggable apps. It's quite
2967                // awkward to turn on otherwise.
2968                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2969            }
2970            // Run the app in safe mode if its manifest requests so or the
2971            // system is booted in safe mode.
2972            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2973                mSafeMode == true) {
2974                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2975            }
2976            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2977                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2978            }
2979            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2980                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2981            }
2982            if ("1".equals(SystemProperties.get("debug.assert"))) {
2983                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2984            }
2985
2986            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.cpuAbi;
2987            if (requiredAbi == null) {
2988                requiredAbi = Build.SUPPORTED_ABIS[0];
2989            }
2990
2991            // Start the process.  It will either succeed and return a result containing
2992            // the PID of the new process, or else throw a RuntimeException.
2993            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2994                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2995                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
2996
2997            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2998            synchronized (bs) {
2999                if (bs.isOnBattery()) {
3000                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
3001                }
3002            }
3003
3004            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3005                    UserHandle.getUserId(uid), startResult.pid, uid,
3006                    app.processName, hostingType,
3007                    hostingNameStr != null ? hostingNameStr : "");
3008
3009            if (app.persistent) {
3010                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3011            }
3012
3013            StringBuilder buf = mStringBuilder;
3014            buf.setLength(0);
3015            buf.append("Start proc ");
3016            buf.append(app.processName);
3017            buf.append(" for ");
3018            buf.append(hostingType);
3019            if (hostingNameStr != null) {
3020                buf.append(" ");
3021                buf.append(hostingNameStr);
3022            }
3023            buf.append(": pid=");
3024            buf.append(startResult.pid);
3025            buf.append(" uid=");
3026            buf.append(uid);
3027            buf.append(" gids={");
3028            if (gids != null) {
3029                for (int gi=0; gi<gids.length; gi++) {
3030                    if (gi != 0) buf.append(", ");
3031                    buf.append(gids[gi]);
3032
3033                }
3034            }
3035            buf.append("}");
3036            if (requiredAbi != null) {
3037                buf.append(" abi=");
3038                buf.append(requiredAbi);
3039            }
3040            Slog.i(TAG, buf.toString());
3041            app.setPid(startResult.pid);
3042            app.usingWrapper = startResult.usingWrapper;
3043            app.removed = false;
3044            synchronized (mPidsSelfLocked) {
3045                this.mPidsSelfLocked.put(startResult.pid, app);
3046                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3047                msg.obj = app;
3048                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3049                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3050            }
3051            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
3052                    app.processName, app.info.uid);
3053            if (app.isolated) {
3054                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3055            }
3056        } catch (RuntimeException e) {
3057            // XXX do better error recovery.
3058            app.setPid(0);
3059            Slog.e(TAG, "Failure starting process " + app.processName, e);
3060        }
3061    }
3062
3063    void updateUsageStats(ActivityRecord component, boolean resumed) {
3064        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3065        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3066        if (resumed) {
3067            mUsageStatsService.noteResumeComponent(component.realActivity);
3068            synchronized (stats) {
3069                stats.noteActivityResumedLocked(component.app.uid);
3070            }
3071        } else {
3072            mUsageStatsService.notePauseComponent(component.realActivity);
3073            synchronized (stats) {
3074                stats.noteActivityPausedLocked(component.app.uid);
3075            }
3076        }
3077    }
3078
3079    Intent getHomeIntent() {
3080        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3081        intent.setComponent(mTopComponent);
3082        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3083            intent.addCategory(Intent.CATEGORY_HOME);
3084        }
3085        return intent;
3086    }
3087
3088    boolean startHomeActivityLocked(int userId) {
3089        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3090                && mTopAction == null) {
3091            // We are running in factory test mode, but unable to find
3092            // the factory test app, so just sit around displaying the
3093            // error message and don't try to start anything.
3094            return false;
3095        }
3096        Intent intent = getHomeIntent();
3097        ActivityInfo aInfo =
3098            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3099        if (aInfo != null) {
3100            intent.setComponent(new ComponentName(
3101                    aInfo.applicationInfo.packageName, aInfo.name));
3102            // Don't do this if the home app is currently being
3103            // instrumented.
3104            aInfo = new ActivityInfo(aInfo);
3105            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3106            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3107                    aInfo.applicationInfo.uid, true);
3108            if (app == null || app.instrumentationClass == null) {
3109                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3110                mStackSupervisor.startHomeActivity(intent, aInfo);
3111            }
3112        }
3113
3114        return true;
3115    }
3116
3117    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3118        ActivityInfo ai = null;
3119        ComponentName comp = intent.getComponent();
3120        try {
3121            if (comp != null) {
3122                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3123            } else {
3124                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3125                        intent,
3126                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3127                            flags, userId);
3128
3129                if (info != null) {
3130                    ai = info.activityInfo;
3131                }
3132            }
3133        } catch (RemoteException e) {
3134            // ignore
3135        }
3136
3137        return ai;
3138    }
3139
3140    /**
3141     * Starts the "new version setup screen" if appropriate.
3142     */
3143    void startSetupActivityLocked() {
3144        // Only do this once per boot.
3145        if (mCheckedForSetup) {
3146            return;
3147        }
3148
3149        // We will show this screen if the current one is a different
3150        // version than the last one shown, and we are not running in
3151        // low-level factory test mode.
3152        final ContentResolver resolver = mContext.getContentResolver();
3153        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3154                Settings.Global.getInt(resolver,
3155                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3156            mCheckedForSetup = true;
3157
3158            // See if we should be showing the platform update setup UI.
3159            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3160            List<ResolveInfo> ris = mContext.getPackageManager()
3161                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3162
3163            // We don't allow third party apps to replace this.
3164            ResolveInfo ri = null;
3165            for (int i=0; ris != null && i<ris.size(); i++) {
3166                if ((ris.get(i).activityInfo.applicationInfo.flags
3167                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3168                    ri = ris.get(i);
3169                    break;
3170                }
3171            }
3172
3173            if (ri != null) {
3174                String vers = ri.activityInfo.metaData != null
3175                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3176                        : null;
3177                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3178                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3179                            Intent.METADATA_SETUP_VERSION);
3180                }
3181                String lastVers = Settings.Secure.getString(
3182                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3183                if (vers != null && !vers.equals(lastVers)) {
3184                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3185                    intent.setComponent(new ComponentName(
3186                            ri.activityInfo.packageName, ri.activityInfo.name));
3187                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3188                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3189                }
3190            }
3191        }
3192    }
3193
3194    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3195        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3196    }
3197
3198    void enforceNotIsolatedCaller(String caller) {
3199        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3200            throw new SecurityException("Isolated process not allowed to call " + caller);
3201        }
3202    }
3203
3204    @Override
3205    public int getFrontActivityScreenCompatMode() {
3206        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3207        synchronized (this) {
3208            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3209        }
3210    }
3211
3212    @Override
3213    public void setFrontActivityScreenCompatMode(int mode) {
3214        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3215                "setFrontActivityScreenCompatMode");
3216        synchronized (this) {
3217            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3218        }
3219    }
3220
3221    @Override
3222    public int getPackageScreenCompatMode(String packageName) {
3223        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3224        synchronized (this) {
3225            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3226        }
3227    }
3228
3229    @Override
3230    public void setPackageScreenCompatMode(String packageName, int mode) {
3231        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3232                "setPackageScreenCompatMode");
3233        synchronized (this) {
3234            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3235        }
3236    }
3237
3238    @Override
3239    public boolean getPackageAskScreenCompat(String packageName) {
3240        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3241        synchronized (this) {
3242            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3243        }
3244    }
3245
3246    @Override
3247    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3248        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3249                "setPackageAskScreenCompat");
3250        synchronized (this) {
3251            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3252        }
3253    }
3254
3255    private void dispatchProcessesChanged() {
3256        int N;
3257        synchronized (this) {
3258            N = mPendingProcessChanges.size();
3259            if (mActiveProcessChanges.length < N) {
3260                mActiveProcessChanges = new ProcessChangeItem[N];
3261            }
3262            mPendingProcessChanges.toArray(mActiveProcessChanges);
3263            mAvailProcessChanges.addAll(mPendingProcessChanges);
3264            mPendingProcessChanges.clear();
3265            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3266        }
3267
3268        int i = mProcessObservers.beginBroadcast();
3269        while (i > 0) {
3270            i--;
3271            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3272            if (observer != null) {
3273                try {
3274                    for (int j=0; j<N; j++) {
3275                        ProcessChangeItem item = mActiveProcessChanges[j];
3276                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3277                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3278                                    + item.pid + " uid=" + item.uid + ": "
3279                                    + item.foregroundActivities);
3280                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3281                                    item.foregroundActivities);
3282                        }
3283                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3284                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3285                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3286                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3287                        }
3288                    }
3289                } catch (RemoteException e) {
3290                }
3291            }
3292        }
3293        mProcessObservers.finishBroadcast();
3294    }
3295
3296    private void dispatchProcessDied(int pid, int uid) {
3297        int i = mProcessObservers.beginBroadcast();
3298        while (i > 0) {
3299            i--;
3300            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3301            if (observer != null) {
3302                try {
3303                    observer.onProcessDied(pid, uid);
3304                } catch (RemoteException e) {
3305                }
3306            }
3307        }
3308        mProcessObservers.finishBroadcast();
3309    }
3310
3311    final void doPendingActivityLaunchesLocked(boolean doResume) {
3312        final int N = mPendingActivityLaunches.size();
3313        if (N <= 0) {
3314            return;
3315        }
3316        for (int i=0; i<N; i++) {
3317            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3318            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3319                    doResume && i == (N-1), null);
3320        }
3321        mPendingActivityLaunches.clear();
3322    }
3323
3324    @Override
3325    public final int startActivity(IApplicationThread caller, String callingPackage,
3326            Intent intent, String resolvedType, IBinder resultTo,
3327            String resultWho, int requestCode, int startFlags,
3328            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3329        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3330                resultWho, requestCode,
3331                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3332    }
3333
3334    @Override
3335    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3336            Intent intent, String resolvedType, IBinder resultTo,
3337            String resultWho, int requestCode, int startFlags,
3338            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3339        enforceNotIsolatedCaller("startActivity");
3340        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3341                false, true, "startActivity", null);
3342        // TODO: Switch to user app stacks here.
3343        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3344                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3345                null, null, options, userId, null);
3346    }
3347
3348    @Override
3349    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3350            Intent intent, String resolvedType, IBinder resultTo,
3351            String resultWho, int requestCode, int startFlags, String profileFile,
3352            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3353        enforceNotIsolatedCaller("startActivityAndWait");
3354        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3355                false, true, "startActivityAndWait", null);
3356        WaitResult res = new WaitResult();
3357        // TODO: Switch to user app stacks here.
3358        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3359                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3360                res, null, options, UserHandle.getCallingUserId(), null);
3361        return res;
3362    }
3363
3364    @Override
3365    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3366            Intent intent, String resolvedType, IBinder resultTo,
3367            String resultWho, int requestCode, int startFlags, Configuration config,
3368            Bundle options, int userId) {
3369        enforceNotIsolatedCaller("startActivityWithConfig");
3370        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3371                false, true, "startActivityWithConfig", null);
3372        // TODO: Switch to user app stacks here.
3373        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3374                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3375                null, null, null, config, options, userId, null);
3376        return ret;
3377    }
3378
3379    @Override
3380    public int startActivityIntentSender(IApplicationThread caller,
3381            IntentSender intent, Intent fillInIntent, String resolvedType,
3382            IBinder resultTo, String resultWho, int requestCode,
3383            int flagsMask, int flagsValues, Bundle options) {
3384        enforceNotIsolatedCaller("startActivityIntentSender");
3385        // Refuse possible leaked file descriptors
3386        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3387            throw new IllegalArgumentException("File descriptors passed in Intent");
3388        }
3389
3390        IIntentSender sender = intent.getTarget();
3391        if (!(sender instanceof PendingIntentRecord)) {
3392            throw new IllegalArgumentException("Bad PendingIntent object");
3393        }
3394
3395        PendingIntentRecord pir = (PendingIntentRecord)sender;
3396
3397        synchronized (this) {
3398            // If this is coming from the currently resumed activity, it is
3399            // effectively saying that app switches are allowed at this point.
3400            final ActivityStack stack = getFocusedStack();
3401            if (stack.mResumedActivity != null &&
3402                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3403                mAppSwitchesAllowedTime = 0;
3404            }
3405        }
3406        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3407                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3408        return ret;
3409    }
3410
3411    @Override
3412    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3413            Intent intent, String resolvedType, IVoiceInteractionSession session,
3414            IVoiceInteractor interactor, int startFlags, String profileFile,
3415            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3416        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3417                != PackageManager.PERMISSION_GRANTED) {
3418            String msg = "Permission Denial: startVoiceActivity() from pid="
3419                    + Binder.getCallingPid()
3420                    + ", uid=" + Binder.getCallingUid()
3421                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3422            Slog.w(TAG, msg);
3423            throw new SecurityException(msg);
3424        }
3425        if (session == null || interactor == null) {
3426            throw new NullPointerException("null session or interactor");
3427        }
3428        userId = handleIncomingUser(callingPid, callingUid, userId,
3429                false, true, "startVoiceActivity", null);
3430        // TODO: Switch to user app stacks here.
3431        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3432                resolvedType, session, interactor, null, null, 0, startFlags,
3433                profileFile, profileFd, null, null, options, userId, null);
3434    }
3435
3436    @Override
3437    public boolean startNextMatchingActivity(IBinder callingActivity,
3438            Intent intent, Bundle options) {
3439        // Refuse possible leaked file descriptors
3440        if (intent != null && intent.hasFileDescriptors() == true) {
3441            throw new IllegalArgumentException("File descriptors passed in Intent");
3442        }
3443
3444        synchronized (this) {
3445            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3446            if (r == null) {
3447                ActivityOptions.abort(options);
3448                return false;
3449            }
3450            if (r.app == null || r.app.thread == null) {
3451                // The caller is not running...  d'oh!
3452                ActivityOptions.abort(options);
3453                return false;
3454            }
3455            intent = new Intent(intent);
3456            // The caller is not allowed to change the data.
3457            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3458            // And we are resetting to find the next component...
3459            intent.setComponent(null);
3460
3461            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3462
3463            ActivityInfo aInfo = null;
3464            try {
3465                List<ResolveInfo> resolves =
3466                    AppGlobals.getPackageManager().queryIntentActivities(
3467                            intent, r.resolvedType,
3468                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3469                            UserHandle.getCallingUserId());
3470
3471                // Look for the original activity in the list...
3472                final int N = resolves != null ? resolves.size() : 0;
3473                for (int i=0; i<N; i++) {
3474                    ResolveInfo rInfo = resolves.get(i);
3475                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3476                            && rInfo.activityInfo.name.equals(r.info.name)) {
3477                        // We found the current one...  the next matching is
3478                        // after it.
3479                        i++;
3480                        if (i<N) {
3481                            aInfo = resolves.get(i).activityInfo;
3482                        }
3483                        if (debug) {
3484                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3485                                    + "/" + r.info.name);
3486                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3487                                    + "/" + aInfo.name);
3488                        }
3489                        break;
3490                    }
3491                }
3492            } catch (RemoteException e) {
3493            }
3494
3495            if (aInfo == null) {
3496                // Nobody who is next!
3497                ActivityOptions.abort(options);
3498                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3499                return false;
3500            }
3501
3502            intent.setComponent(new ComponentName(
3503                    aInfo.applicationInfo.packageName, aInfo.name));
3504            intent.setFlags(intent.getFlags()&~(
3505                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3506                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3507                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3508                    Intent.FLAG_ACTIVITY_NEW_TASK));
3509
3510            // Okay now we need to start the new activity, replacing the
3511            // currently running activity.  This is a little tricky because
3512            // we want to start the new one as if the current one is finished,
3513            // but not finish the current one first so that there is no flicker.
3514            // And thus...
3515            final boolean wasFinishing = r.finishing;
3516            r.finishing = true;
3517
3518            // Propagate reply information over to the new activity.
3519            final ActivityRecord resultTo = r.resultTo;
3520            final String resultWho = r.resultWho;
3521            final int requestCode = r.requestCode;
3522            r.resultTo = null;
3523            if (resultTo != null) {
3524                resultTo.removeResultsLocked(r, resultWho, requestCode);
3525            }
3526
3527            final long origId = Binder.clearCallingIdentity();
3528            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3529                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3530                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3531                    options, false, null, null);
3532            Binder.restoreCallingIdentity(origId);
3533
3534            r.finishing = wasFinishing;
3535            if (res != ActivityManager.START_SUCCESS) {
3536                return false;
3537            }
3538            return true;
3539        }
3540    }
3541
3542    final int startActivityInPackage(int uid, String callingPackage,
3543            Intent intent, String resolvedType, IBinder resultTo,
3544            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3545                    IActivityContainer container) {
3546
3547        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3548                false, true, "startActivityInPackage", null);
3549
3550        // TODO: Switch to user app stacks here.
3551        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3552                null, null, resultTo, resultWho, requestCode, startFlags,
3553                null, null, null, null, options, userId, container);
3554        return ret;
3555    }
3556
3557    @Override
3558    public final int startActivities(IApplicationThread caller, String callingPackage,
3559            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3560            int userId) {
3561        enforceNotIsolatedCaller("startActivities");
3562        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3563                false, true, "startActivity", null);
3564        // TODO: Switch to user app stacks here.
3565        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3566                resolvedTypes, resultTo, options, userId);
3567        return ret;
3568    }
3569
3570    final int startActivitiesInPackage(int uid, String callingPackage,
3571            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3572            Bundle options, int userId) {
3573
3574        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3575                false, true, "startActivityInPackage", null);
3576        // TODO: Switch to user app stacks here.
3577        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3578                resultTo, options, userId);
3579        return ret;
3580    }
3581
3582    final void addRecentTaskLocked(TaskRecord task) {
3583        int N = mRecentTasks.size();
3584        // Quick case: check if the top-most recent task is the same.
3585        if (N > 0 && mRecentTasks.get(0) == task) {
3586            return;
3587        }
3588        // Another quick case: never add voice sessions.
3589        if (task.voiceSession != null) {
3590            return;
3591        }
3592        // Remove any existing entries that are the same kind of task.
3593        final Intent intent = task.intent;
3594        final boolean document = intent != null && intent.isDocument();
3595        final ComponentName comp = intent.getComponent();
3596
3597        int maxRecents = task.maxRecents - 1;
3598        for (int i=0; i<N; i++) {
3599            TaskRecord tr = mRecentTasks.get(i);
3600            if (task != tr) {
3601                if (task.userId != tr.userId) {
3602                    continue;
3603                }
3604                final Intent trIntent = tr.intent;
3605                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3606                    (intent == null || !intent.filterEquals(trIntent))) {
3607                    continue;
3608                }
3609                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3610                if (document && trIsDocument) {
3611                    // These are the same document activity (not necessarily the same doc).
3612                    if (maxRecents > 0) {
3613                        --maxRecents;
3614                        continue;
3615                    }
3616                    // Hit the maximum number of documents for this task. Fall through
3617                    // and remove this document from recents.
3618                } else if (document || trIsDocument) {
3619                    // Only one of these is a document. Not the droid we're looking for.
3620                    continue;
3621                }
3622            }
3623
3624            // Either task and tr are the same or, their affinities match or their intents match
3625            // and neither of them is a document, or they are documents using the same activity
3626            // and their maxRecents has been reached.
3627            tr.disposeThumbnail();
3628            mRecentTasks.remove(i);
3629            i--;
3630            N--;
3631            if (task.intent == null) {
3632                // If the new recent task we are adding is not fully
3633                // specified, then replace it with the existing recent task.
3634                task = tr;
3635            }
3636            mTaskPersister.notify(tr, false);
3637        }
3638        if (N >= MAX_RECENT_TASKS) {
3639            mRecentTasks.remove(N-1).disposeThumbnail();
3640        }
3641        mRecentTasks.add(0, task);
3642    }
3643
3644    @Override
3645    public void reportActivityFullyDrawn(IBinder token) {
3646        synchronized (this) {
3647            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3648            if (r == null) {
3649                return;
3650            }
3651            r.reportFullyDrawnLocked();
3652        }
3653    }
3654
3655    @Override
3656    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3657        synchronized (this) {
3658            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3659            if (r == null) {
3660                return;
3661            }
3662            final long origId = Binder.clearCallingIdentity();
3663            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3664            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3665                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3666            if (config != null) {
3667                r.frozenBeforeDestroy = true;
3668                if (!updateConfigurationLocked(config, r, false, false)) {
3669                    mStackSupervisor.resumeTopActivitiesLocked();
3670                }
3671            }
3672            Binder.restoreCallingIdentity(origId);
3673        }
3674    }
3675
3676    @Override
3677    public int getRequestedOrientation(IBinder token) {
3678        synchronized (this) {
3679            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3680            if (r == null) {
3681                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3682            }
3683            return mWindowManager.getAppOrientation(r.appToken);
3684        }
3685    }
3686
3687    /**
3688     * This is the internal entry point for handling Activity.finish().
3689     *
3690     * @param token The Binder token referencing the Activity we want to finish.
3691     * @param resultCode Result code, if any, from this Activity.
3692     * @param resultData Result data (Intent), if any, from this Activity.
3693     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3694     *            the root Activity in the task.
3695     *
3696     * @return Returns true if the activity successfully finished, or false if it is still running.
3697     */
3698    @Override
3699    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3700            boolean finishTask) {
3701        // Refuse possible leaked file descriptors
3702        if (resultData != null && resultData.hasFileDescriptors() == true) {
3703            throw new IllegalArgumentException("File descriptors passed in Intent");
3704        }
3705
3706        synchronized(this) {
3707            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3708            if (r == null) {
3709                return true;
3710            }
3711            // Keep track of the root activity of the task before we finish it
3712            TaskRecord tr = r.task;
3713            ActivityRecord rootR = tr.getRootActivity();
3714            // Do not allow task to finish in Lock Task mode.
3715            if (tr == mStackSupervisor.mLockTaskModeTask) {
3716                if (rootR == r) {
3717                    return false;
3718                }
3719            }
3720            if (mController != null) {
3721                // Find the first activity that is not finishing.
3722                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3723                if (next != null) {
3724                    // ask watcher if this is allowed
3725                    boolean resumeOK = true;
3726                    try {
3727                        resumeOK = mController.activityResuming(next.packageName);
3728                    } catch (RemoteException e) {
3729                        mController = null;
3730                        Watchdog.getInstance().setActivityController(null);
3731                    }
3732
3733                    if (!resumeOK) {
3734                        return false;
3735                    }
3736                }
3737            }
3738            final long origId = Binder.clearCallingIdentity();
3739            try {
3740                boolean res;
3741                if (finishTask && r == rootR) {
3742                    // If requested, remove the task that is associated to this activity only if it
3743                    // was the root activity in the task.  The result code and data is ignored because
3744                    // we don't support returning them across task boundaries.
3745                    res = removeTaskByIdLocked(tr.taskId, 0);
3746                } else {
3747                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3748                            resultData, "app-request", true);
3749                }
3750                return res;
3751            } finally {
3752                Binder.restoreCallingIdentity(origId);
3753            }
3754        }
3755    }
3756
3757    @Override
3758    public final void finishHeavyWeightApp() {
3759        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3760                != PackageManager.PERMISSION_GRANTED) {
3761            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3762                    + Binder.getCallingPid()
3763                    + ", uid=" + Binder.getCallingUid()
3764                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3765            Slog.w(TAG, msg);
3766            throw new SecurityException(msg);
3767        }
3768
3769        synchronized(this) {
3770            if (mHeavyWeightProcess == null) {
3771                return;
3772            }
3773
3774            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3775                    mHeavyWeightProcess.activities);
3776            for (int i=0; i<activities.size(); i++) {
3777                ActivityRecord r = activities.get(i);
3778                if (!r.finishing) {
3779                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3780                            null, "finish-heavy", true);
3781                }
3782            }
3783
3784            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3785                    mHeavyWeightProcess.userId, 0));
3786            mHeavyWeightProcess = null;
3787        }
3788    }
3789
3790    @Override
3791    public void crashApplication(int uid, int initialPid, String packageName,
3792            String message) {
3793        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3794                != PackageManager.PERMISSION_GRANTED) {
3795            String msg = "Permission Denial: crashApplication() from pid="
3796                    + Binder.getCallingPid()
3797                    + ", uid=" + Binder.getCallingUid()
3798                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3799            Slog.w(TAG, msg);
3800            throw new SecurityException(msg);
3801        }
3802
3803        synchronized(this) {
3804            ProcessRecord proc = null;
3805
3806            // Figure out which process to kill.  We don't trust that initialPid
3807            // still has any relation to current pids, so must scan through the
3808            // list.
3809            synchronized (mPidsSelfLocked) {
3810                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3811                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3812                    if (p.uid != uid) {
3813                        continue;
3814                    }
3815                    if (p.pid == initialPid) {
3816                        proc = p;
3817                        break;
3818                    }
3819                    if (p.pkgList.containsKey(packageName)) {
3820                        proc = p;
3821                    }
3822                }
3823            }
3824
3825            if (proc == null) {
3826                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3827                        + " initialPid=" + initialPid
3828                        + " packageName=" + packageName);
3829                return;
3830            }
3831
3832            if (proc.thread != null) {
3833                if (proc.pid == Process.myPid()) {
3834                    Log.w(TAG, "crashApplication: trying to crash self!");
3835                    return;
3836                }
3837                long ident = Binder.clearCallingIdentity();
3838                try {
3839                    proc.thread.scheduleCrash(message);
3840                } catch (RemoteException e) {
3841                }
3842                Binder.restoreCallingIdentity(ident);
3843            }
3844        }
3845    }
3846
3847    @Override
3848    public final void finishSubActivity(IBinder token, String resultWho,
3849            int requestCode) {
3850        synchronized(this) {
3851            final long origId = Binder.clearCallingIdentity();
3852            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3853            if (r != null) {
3854                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3855            }
3856            Binder.restoreCallingIdentity(origId);
3857        }
3858    }
3859
3860    @Override
3861    public boolean finishActivityAffinity(IBinder token) {
3862        synchronized(this) {
3863            final long origId = Binder.clearCallingIdentity();
3864            try {
3865                ActivityRecord r = ActivityRecord.isInStackLocked(token);
3866
3867                ActivityRecord rootR = r.task.getRootActivity();
3868                // Do not allow task to finish in Lock Task mode.
3869                if (r.task == mStackSupervisor.mLockTaskModeTask) {
3870                    if (rootR == r) {
3871                        Binder.restoreCallingIdentity(origId);
3872                        return false;
3873                    }
3874                }
3875                boolean res = false;
3876                if (r != null) {
3877                    res = r.task.stack.finishActivityAffinityLocked(r);
3878                }
3879                return res;
3880            } finally {
3881                Binder.restoreCallingIdentity(origId);
3882            }
3883        }
3884    }
3885
3886    @Override
3887    public boolean willActivityBeVisible(IBinder token) {
3888        synchronized(this) {
3889            ActivityStack stack = ActivityRecord.getStackLocked(token);
3890            if (stack != null) {
3891                return stack.willActivityBeVisibleLocked(token);
3892            }
3893            return false;
3894        }
3895    }
3896
3897    @Override
3898    public void overridePendingTransition(IBinder token, String packageName,
3899            int enterAnim, int exitAnim) {
3900        synchronized(this) {
3901            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3902            if (self == null) {
3903                return;
3904            }
3905
3906            final long origId = Binder.clearCallingIdentity();
3907
3908            if (self.state == ActivityState.RESUMED
3909                    || self.state == ActivityState.PAUSING) {
3910                mWindowManager.overridePendingAppTransition(packageName,
3911                        enterAnim, exitAnim, null);
3912            }
3913
3914            Binder.restoreCallingIdentity(origId);
3915        }
3916    }
3917
3918    /**
3919     * Main function for removing an existing process from the activity manager
3920     * as a result of that process going away.  Clears out all connections
3921     * to the process.
3922     */
3923    private final void handleAppDiedLocked(ProcessRecord app,
3924            boolean restarting, boolean allowRestart) {
3925        int pid = app.pid;
3926        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3927        if (!restarting) {
3928            removeLruProcessLocked(app);
3929            if (pid > 0) {
3930                ProcessList.remove(pid);
3931            }
3932        }
3933
3934        if (mProfileProc == app) {
3935            clearProfilerLocked();
3936        }
3937
3938        // Remove this application's activities from active lists.
3939        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3940
3941        app.activities.clear();
3942
3943        if (app.instrumentationClass != null) {
3944            Slog.w(TAG, "Crash of app " + app.processName
3945                  + " running instrumentation " + app.instrumentationClass);
3946            Bundle info = new Bundle();
3947            info.putString("shortMsg", "Process crashed.");
3948            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3949        }
3950
3951        if (!restarting) {
3952            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3953                // If there was nothing to resume, and we are not already
3954                // restarting this process, but there is a visible activity that
3955                // is hosted by the process...  then make sure all visible
3956                // activities are running, taking care of restarting this
3957                // process.
3958                if (hasVisibleActivities) {
3959                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3960                }
3961            }
3962        }
3963    }
3964
3965    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3966        IBinder threadBinder = thread.asBinder();
3967        // Find the application record.
3968        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3969            ProcessRecord rec = mLruProcesses.get(i);
3970            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3971                return i;
3972            }
3973        }
3974        return -1;
3975    }
3976
3977    final ProcessRecord getRecordForAppLocked(
3978            IApplicationThread thread) {
3979        if (thread == null) {
3980            return null;
3981        }
3982
3983        int appIndex = getLRURecordIndexForAppLocked(thread);
3984        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3985    }
3986
3987    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3988        // If there are no longer any background processes running,
3989        // and the app that died was not running instrumentation,
3990        // then tell everyone we are now low on memory.
3991        boolean haveBg = false;
3992        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3993            ProcessRecord rec = mLruProcesses.get(i);
3994            if (rec.thread != null
3995                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3996                haveBg = true;
3997                break;
3998            }
3999        }
4000
4001        if (!haveBg) {
4002            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4003            if (doReport) {
4004                long now = SystemClock.uptimeMillis();
4005                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4006                    doReport = false;
4007                } else {
4008                    mLastMemUsageReportTime = now;
4009                }
4010            }
4011            final ArrayList<ProcessMemInfo> memInfos
4012                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4013            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4014            long now = SystemClock.uptimeMillis();
4015            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4016                ProcessRecord rec = mLruProcesses.get(i);
4017                if (rec == dyingProc || rec.thread == null) {
4018                    continue;
4019                }
4020                if (doReport) {
4021                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4022                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4023                }
4024                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4025                    // The low memory report is overriding any current
4026                    // state for a GC request.  Make sure to do
4027                    // heavy/important/visible/foreground processes first.
4028                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4029                        rec.lastRequestedGc = 0;
4030                    } else {
4031                        rec.lastRequestedGc = rec.lastLowMemory;
4032                    }
4033                    rec.reportLowMemory = true;
4034                    rec.lastLowMemory = now;
4035                    mProcessesToGc.remove(rec);
4036                    addProcessToGcListLocked(rec);
4037                }
4038            }
4039            if (doReport) {
4040                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4041                mHandler.sendMessage(msg);
4042            }
4043            scheduleAppGcsLocked();
4044        }
4045    }
4046
4047    final void appDiedLocked(ProcessRecord app, int pid,
4048            IApplicationThread thread) {
4049
4050        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4051        synchronized (stats) {
4052            stats.noteProcessDiedLocked(app.info.uid, pid);
4053        }
4054
4055        // Clean up already done if the process has been re-started.
4056        if (app.pid == pid && app.thread != null &&
4057                app.thread.asBinder() == thread.asBinder()) {
4058            boolean doLowMem = app.instrumentationClass == null;
4059            boolean doOomAdj = doLowMem;
4060            if (!app.killedByAm) {
4061                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4062                        + ") has died.");
4063                mAllowLowerMemLevel = true;
4064            } else {
4065                // Note that we always want to do oom adj to update our state with the
4066                // new number of procs.
4067                mAllowLowerMemLevel = false;
4068                doLowMem = false;
4069            }
4070            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4071            if (DEBUG_CLEANUP) Slog.v(
4072                TAG, "Dying app: " + app + ", pid: " + pid
4073                + ", thread: " + thread.asBinder());
4074            handleAppDiedLocked(app, false, true);
4075
4076            if (doOomAdj) {
4077                updateOomAdjLocked();
4078            }
4079            if (doLowMem) {
4080                doLowMemReportIfNeededLocked(app);
4081            }
4082        } else if (app.pid != pid) {
4083            // A new process has already been started.
4084            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4085                    + ") has died and restarted (pid " + app.pid + ").");
4086            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4087        } else if (DEBUG_PROCESSES) {
4088            Slog.d(TAG, "Received spurious death notification for thread "
4089                    + thread.asBinder());
4090        }
4091    }
4092
4093    /**
4094     * If a stack trace dump file is configured, dump process stack traces.
4095     * @param clearTraces causes the dump file to be erased prior to the new
4096     *    traces being written, if true; when false, the new traces will be
4097     *    appended to any existing file content.
4098     * @param firstPids of dalvik VM processes to dump stack traces for first
4099     * @param lastPids of dalvik VM processes to dump stack traces for last
4100     * @param nativeProcs optional list of native process names to dump stack crawls
4101     * @return file containing stack traces, or null if no dump file is configured
4102     */
4103    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4104            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4105        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4106        if (tracesPath == null || tracesPath.length() == 0) {
4107            return null;
4108        }
4109
4110        File tracesFile = new File(tracesPath);
4111        try {
4112            File tracesDir = tracesFile.getParentFile();
4113            if (!tracesDir.exists()) {
4114                tracesFile.mkdirs();
4115                if (!SELinux.restorecon(tracesDir)) {
4116                    return null;
4117                }
4118            }
4119            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4120
4121            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4122            tracesFile.createNewFile();
4123            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4124        } catch (IOException e) {
4125            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4126            return null;
4127        }
4128
4129        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4130        return tracesFile;
4131    }
4132
4133    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4134            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4135        // Use a FileObserver to detect when traces finish writing.
4136        // The order of traces is considered important to maintain for legibility.
4137        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4138            @Override
4139            public synchronized void onEvent(int event, String path) { notify(); }
4140        };
4141
4142        try {
4143            observer.startWatching();
4144
4145            // First collect all of the stacks of the most important pids.
4146            if (firstPids != null) {
4147                try {
4148                    int num = firstPids.size();
4149                    for (int i = 0; i < num; i++) {
4150                        synchronized (observer) {
4151                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4152                            observer.wait(200);  // Wait for write-close, give up after 200msec
4153                        }
4154                    }
4155                } catch (InterruptedException e) {
4156                    Log.wtf(TAG, e);
4157                }
4158            }
4159
4160            // Next collect the stacks of the native pids
4161            if (nativeProcs != null) {
4162                int[] pids = Process.getPidsForCommands(nativeProcs);
4163                if (pids != null) {
4164                    for (int pid : pids) {
4165                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4166                    }
4167                }
4168            }
4169
4170            // Lastly, measure CPU usage.
4171            if (processCpuTracker != null) {
4172                processCpuTracker.init();
4173                System.gc();
4174                processCpuTracker.update();
4175                try {
4176                    synchronized (processCpuTracker) {
4177                        processCpuTracker.wait(500); // measure over 1/2 second.
4178                    }
4179                } catch (InterruptedException e) {
4180                }
4181                processCpuTracker.update();
4182
4183                // We'll take the stack crawls of just the top apps using CPU.
4184                final int N = processCpuTracker.countWorkingStats();
4185                int numProcs = 0;
4186                for (int i=0; i<N && numProcs<5; i++) {
4187                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4188                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4189                        numProcs++;
4190                        try {
4191                            synchronized (observer) {
4192                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4193                                observer.wait(200);  // Wait for write-close, give up after 200msec
4194                            }
4195                        } catch (InterruptedException e) {
4196                            Log.wtf(TAG, e);
4197                        }
4198
4199                    }
4200                }
4201            }
4202        } finally {
4203            observer.stopWatching();
4204        }
4205    }
4206
4207    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4208        if (true || IS_USER_BUILD) {
4209            return;
4210        }
4211        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4212        if (tracesPath == null || tracesPath.length() == 0) {
4213            return;
4214        }
4215
4216        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4217        StrictMode.allowThreadDiskWrites();
4218        try {
4219            final File tracesFile = new File(tracesPath);
4220            final File tracesDir = tracesFile.getParentFile();
4221            final File tracesTmp = new File(tracesDir, "__tmp__");
4222            try {
4223                if (!tracesDir.exists()) {
4224                    tracesFile.mkdirs();
4225                    if (!SELinux.restorecon(tracesDir.getPath())) {
4226                        return;
4227                    }
4228                }
4229                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4230
4231                if (tracesFile.exists()) {
4232                    tracesTmp.delete();
4233                    tracesFile.renameTo(tracesTmp);
4234                }
4235                StringBuilder sb = new StringBuilder();
4236                Time tobj = new Time();
4237                tobj.set(System.currentTimeMillis());
4238                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4239                sb.append(": ");
4240                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4241                sb.append(" since ");
4242                sb.append(msg);
4243                FileOutputStream fos = new FileOutputStream(tracesFile);
4244                fos.write(sb.toString().getBytes());
4245                if (app == null) {
4246                    fos.write("\n*** No application process!".getBytes());
4247                }
4248                fos.close();
4249                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4250            } catch (IOException e) {
4251                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4252                return;
4253            }
4254
4255            if (app != null) {
4256                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4257                firstPids.add(app.pid);
4258                dumpStackTraces(tracesPath, firstPids, null, null, null);
4259            }
4260
4261            File lastTracesFile = null;
4262            File curTracesFile = null;
4263            for (int i=9; i>=0; i--) {
4264                String name = String.format(Locale.US, "slow%02d.txt", i);
4265                curTracesFile = new File(tracesDir, name);
4266                if (curTracesFile.exists()) {
4267                    if (lastTracesFile != null) {
4268                        curTracesFile.renameTo(lastTracesFile);
4269                    } else {
4270                        curTracesFile.delete();
4271                    }
4272                }
4273                lastTracesFile = curTracesFile;
4274            }
4275            tracesFile.renameTo(curTracesFile);
4276            if (tracesTmp.exists()) {
4277                tracesTmp.renameTo(tracesFile);
4278            }
4279        } finally {
4280            StrictMode.setThreadPolicy(oldPolicy);
4281        }
4282    }
4283
4284    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4285            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4286        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4287        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4288
4289        if (mController != null) {
4290            try {
4291                // 0 == continue, -1 = kill process immediately
4292                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4293                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4294            } catch (RemoteException e) {
4295                mController = null;
4296                Watchdog.getInstance().setActivityController(null);
4297            }
4298        }
4299
4300        long anrTime = SystemClock.uptimeMillis();
4301        if (MONITOR_CPU_USAGE) {
4302            updateCpuStatsNow();
4303        }
4304
4305        synchronized (this) {
4306            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4307            if (mShuttingDown) {
4308                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4309                return;
4310            } else if (app.notResponding) {
4311                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4312                return;
4313            } else if (app.crashing) {
4314                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4315                return;
4316            }
4317
4318            // In case we come through here for the same app before completing
4319            // this one, mark as anring now so we will bail out.
4320            app.notResponding = true;
4321
4322            // Log the ANR to the event log.
4323            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4324                    app.processName, app.info.flags, annotation);
4325
4326            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4327            firstPids.add(app.pid);
4328
4329            int parentPid = app.pid;
4330            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4331            if (parentPid != app.pid) firstPids.add(parentPid);
4332
4333            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4334
4335            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4336                ProcessRecord r = mLruProcesses.get(i);
4337                if (r != null && r.thread != null) {
4338                    int pid = r.pid;
4339                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4340                        if (r.persistent) {
4341                            firstPids.add(pid);
4342                        } else {
4343                            lastPids.put(pid, Boolean.TRUE);
4344                        }
4345                    }
4346                }
4347            }
4348        }
4349
4350        // Log the ANR to the main log.
4351        StringBuilder info = new StringBuilder();
4352        info.setLength(0);
4353        info.append("ANR in ").append(app.processName);
4354        if (activity != null && activity.shortComponentName != null) {
4355            info.append(" (").append(activity.shortComponentName).append(")");
4356        }
4357        info.append("\n");
4358        info.append("PID: ").append(app.pid).append("\n");
4359        if (annotation != null) {
4360            info.append("Reason: ").append(annotation).append("\n");
4361        }
4362        if (parent != null && parent != activity) {
4363            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4364        }
4365
4366        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4367
4368        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4369                NATIVE_STACKS_OF_INTEREST);
4370
4371        String cpuInfo = null;
4372        if (MONITOR_CPU_USAGE) {
4373            updateCpuStatsNow();
4374            synchronized (mProcessCpuThread) {
4375                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4376            }
4377            info.append(processCpuTracker.printCurrentLoad());
4378            info.append(cpuInfo);
4379        }
4380
4381        info.append(processCpuTracker.printCurrentState(anrTime));
4382
4383        Slog.e(TAG, info.toString());
4384        if (tracesFile == null) {
4385            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4386            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4387        }
4388
4389        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4390                cpuInfo, tracesFile, null);
4391
4392        if (mController != null) {
4393            try {
4394                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4395                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4396                if (res != 0) {
4397                    if (res < 0 && app.pid != MY_PID) {
4398                        Process.killProcess(app.pid);
4399                    } else {
4400                        synchronized (this) {
4401                            mServices.scheduleServiceTimeoutLocked(app);
4402                        }
4403                    }
4404                    return;
4405                }
4406            } catch (RemoteException e) {
4407                mController = null;
4408                Watchdog.getInstance().setActivityController(null);
4409            }
4410        }
4411
4412        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4413        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4414                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4415
4416        synchronized (this) {
4417            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4418                killUnneededProcessLocked(app, "background ANR");
4419                return;
4420            }
4421
4422            // Set the app's notResponding state, and look up the errorReportReceiver
4423            makeAppNotRespondingLocked(app,
4424                    activity != null ? activity.shortComponentName : null,
4425                    annotation != null ? "ANR " + annotation : "ANR",
4426                    info.toString());
4427
4428            // Bring up the infamous App Not Responding dialog
4429            Message msg = Message.obtain();
4430            HashMap<String, Object> map = new HashMap<String, Object>();
4431            msg.what = SHOW_NOT_RESPONDING_MSG;
4432            msg.obj = map;
4433            msg.arg1 = aboveSystem ? 1 : 0;
4434            map.put("app", app);
4435            if (activity != null) {
4436                map.put("activity", activity);
4437            }
4438
4439            mHandler.sendMessage(msg);
4440        }
4441    }
4442
4443    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4444        if (!mLaunchWarningShown) {
4445            mLaunchWarningShown = true;
4446            mHandler.post(new Runnable() {
4447                @Override
4448                public void run() {
4449                    synchronized (ActivityManagerService.this) {
4450                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4451                        d.show();
4452                        mHandler.postDelayed(new Runnable() {
4453                            @Override
4454                            public void run() {
4455                                synchronized (ActivityManagerService.this) {
4456                                    d.dismiss();
4457                                    mLaunchWarningShown = false;
4458                                }
4459                            }
4460                        }, 4000);
4461                    }
4462                }
4463            });
4464        }
4465    }
4466
4467    @Override
4468    public boolean clearApplicationUserData(final String packageName,
4469            final IPackageDataObserver observer, int userId) {
4470        enforceNotIsolatedCaller("clearApplicationUserData");
4471        int uid = Binder.getCallingUid();
4472        int pid = Binder.getCallingPid();
4473        userId = handleIncomingUser(pid, uid,
4474                userId, false, true, "clearApplicationUserData", null);
4475        long callingId = Binder.clearCallingIdentity();
4476        try {
4477            IPackageManager pm = AppGlobals.getPackageManager();
4478            int pkgUid = -1;
4479            synchronized(this) {
4480                try {
4481                    pkgUid = pm.getPackageUid(packageName, userId);
4482                } catch (RemoteException e) {
4483                }
4484                if (pkgUid == -1) {
4485                    Slog.w(TAG, "Invalid packageName: " + packageName);
4486                    if (observer != null) {
4487                        try {
4488                            observer.onRemoveCompleted(packageName, false);
4489                        } catch (RemoteException e) {
4490                            Slog.i(TAG, "Observer no longer exists.");
4491                        }
4492                    }
4493                    return false;
4494                }
4495                if (uid == pkgUid || checkComponentPermission(
4496                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4497                        pid, uid, -1, true)
4498                        == PackageManager.PERMISSION_GRANTED) {
4499                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4500                } else {
4501                    throw new SecurityException("PID " + pid + " does not have permission "
4502                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4503                                    + " of package " + packageName);
4504                }
4505            }
4506
4507            try {
4508                // Clear application user data
4509                pm.clearApplicationUserData(packageName, observer, userId);
4510
4511                // Remove all permissions granted from/to this package
4512                removeUriPermissionsForPackageLocked(packageName, userId, true);
4513
4514                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4515                        Uri.fromParts("package", packageName, null));
4516                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4517                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4518                        null, null, 0, null, null, null, false, false, userId);
4519            } catch (RemoteException e) {
4520            }
4521        } finally {
4522            Binder.restoreCallingIdentity(callingId);
4523        }
4524        return true;
4525    }
4526
4527    @Override
4528    public void killBackgroundProcesses(final String packageName, int userId) {
4529        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4530                != PackageManager.PERMISSION_GRANTED &&
4531                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4532                        != PackageManager.PERMISSION_GRANTED) {
4533            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4534                    + Binder.getCallingPid()
4535                    + ", uid=" + Binder.getCallingUid()
4536                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4537            Slog.w(TAG, msg);
4538            throw new SecurityException(msg);
4539        }
4540
4541        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4542                userId, true, true, "killBackgroundProcesses", null);
4543        long callingId = Binder.clearCallingIdentity();
4544        try {
4545            IPackageManager pm = AppGlobals.getPackageManager();
4546            synchronized(this) {
4547                int appId = -1;
4548                try {
4549                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4550                } catch (RemoteException e) {
4551                }
4552                if (appId == -1) {
4553                    Slog.w(TAG, "Invalid packageName: " + packageName);
4554                    return;
4555                }
4556                killPackageProcessesLocked(packageName, appId, userId,
4557                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4558            }
4559        } finally {
4560            Binder.restoreCallingIdentity(callingId);
4561        }
4562    }
4563
4564    @Override
4565    public void killAllBackgroundProcesses() {
4566        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4567                != PackageManager.PERMISSION_GRANTED) {
4568            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4569                    + Binder.getCallingPid()
4570                    + ", uid=" + Binder.getCallingUid()
4571                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4572            Slog.w(TAG, msg);
4573            throw new SecurityException(msg);
4574        }
4575
4576        long callingId = Binder.clearCallingIdentity();
4577        try {
4578            synchronized(this) {
4579                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4580                final int NP = mProcessNames.getMap().size();
4581                for (int ip=0; ip<NP; ip++) {
4582                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4583                    final int NA = apps.size();
4584                    for (int ia=0; ia<NA; ia++) {
4585                        ProcessRecord app = apps.valueAt(ia);
4586                        if (app.persistent) {
4587                            // we don't kill persistent processes
4588                            continue;
4589                        }
4590                        if (app.removed) {
4591                            procs.add(app);
4592                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4593                            app.removed = true;
4594                            procs.add(app);
4595                        }
4596                    }
4597                }
4598
4599                int N = procs.size();
4600                for (int i=0; i<N; i++) {
4601                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4602                }
4603                mAllowLowerMemLevel = true;
4604                updateOomAdjLocked();
4605                doLowMemReportIfNeededLocked(null);
4606            }
4607        } finally {
4608            Binder.restoreCallingIdentity(callingId);
4609        }
4610    }
4611
4612    @Override
4613    public void forceStopPackage(final String packageName, int userId) {
4614        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4615                != PackageManager.PERMISSION_GRANTED) {
4616            String msg = "Permission Denial: forceStopPackage() from pid="
4617                    + Binder.getCallingPid()
4618                    + ", uid=" + Binder.getCallingUid()
4619                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4620            Slog.w(TAG, msg);
4621            throw new SecurityException(msg);
4622        }
4623        final int callingPid = Binder.getCallingPid();
4624        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4625                userId, true, true, "forceStopPackage", null);
4626        long callingId = Binder.clearCallingIdentity();
4627        try {
4628            IPackageManager pm = AppGlobals.getPackageManager();
4629            synchronized(this) {
4630                int[] users = userId == UserHandle.USER_ALL
4631                        ? getUsersLocked() : new int[] { userId };
4632                for (int user : users) {
4633                    int pkgUid = -1;
4634                    try {
4635                        pkgUid = pm.getPackageUid(packageName, user);
4636                    } catch (RemoteException e) {
4637                    }
4638                    if (pkgUid == -1) {
4639                        Slog.w(TAG, "Invalid packageName: " + packageName);
4640                        continue;
4641                    }
4642                    try {
4643                        pm.setPackageStoppedState(packageName, true, user);
4644                    } catch (RemoteException e) {
4645                    } catch (IllegalArgumentException e) {
4646                        Slog.w(TAG, "Failed trying to unstop package "
4647                                + packageName + ": " + e);
4648                    }
4649                    if (isUserRunningLocked(user, false)) {
4650                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4651                    }
4652                }
4653            }
4654        } finally {
4655            Binder.restoreCallingIdentity(callingId);
4656        }
4657    }
4658
4659    /*
4660     * The pkg name and app id have to be specified.
4661     */
4662    @Override
4663    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4664        if (pkg == null) {
4665            return;
4666        }
4667        // Make sure the uid is valid.
4668        if (appid < 0) {
4669            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4670            return;
4671        }
4672        int callerUid = Binder.getCallingUid();
4673        // Only the system server can kill an application
4674        if (callerUid == Process.SYSTEM_UID) {
4675            // Post an aysnc message to kill the application
4676            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4677            msg.arg1 = appid;
4678            msg.arg2 = 0;
4679            Bundle bundle = new Bundle();
4680            bundle.putString("pkg", pkg);
4681            bundle.putString("reason", reason);
4682            msg.obj = bundle;
4683            mHandler.sendMessage(msg);
4684        } else {
4685            throw new SecurityException(callerUid + " cannot kill pkg: " +
4686                    pkg);
4687        }
4688    }
4689
4690    @Override
4691    public void closeSystemDialogs(String reason) {
4692        enforceNotIsolatedCaller("closeSystemDialogs");
4693
4694        final int pid = Binder.getCallingPid();
4695        final int uid = Binder.getCallingUid();
4696        final long origId = Binder.clearCallingIdentity();
4697        try {
4698            synchronized (this) {
4699                // Only allow this from foreground processes, so that background
4700                // applications can't abuse it to prevent system UI from being shown.
4701                if (uid >= Process.FIRST_APPLICATION_UID) {
4702                    ProcessRecord proc;
4703                    synchronized (mPidsSelfLocked) {
4704                        proc = mPidsSelfLocked.get(pid);
4705                    }
4706                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4707                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4708                                + " from background process " + proc);
4709                        return;
4710                    }
4711                }
4712                closeSystemDialogsLocked(reason);
4713            }
4714        } finally {
4715            Binder.restoreCallingIdentity(origId);
4716        }
4717    }
4718
4719    void closeSystemDialogsLocked(String reason) {
4720        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4721        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4722                | Intent.FLAG_RECEIVER_FOREGROUND);
4723        if (reason != null) {
4724            intent.putExtra("reason", reason);
4725        }
4726        mWindowManager.closeSystemDialogs(reason);
4727
4728        mStackSupervisor.closeSystemDialogsLocked();
4729
4730        broadcastIntentLocked(null, null, intent, null,
4731                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4732                Process.SYSTEM_UID, UserHandle.USER_ALL);
4733    }
4734
4735    @Override
4736    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4737        enforceNotIsolatedCaller("getProcessMemoryInfo");
4738        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4739        for (int i=pids.length-1; i>=0; i--) {
4740            ProcessRecord proc;
4741            int oomAdj;
4742            synchronized (this) {
4743                synchronized (mPidsSelfLocked) {
4744                    proc = mPidsSelfLocked.get(pids[i]);
4745                    oomAdj = proc != null ? proc.setAdj : 0;
4746                }
4747            }
4748            infos[i] = new Debug.MemoryInfo();
4749            Debug.getMemoryInfo(pids[i], infos[i]);
4750            if (proc != null) {
4751                synchronized (this) {
4752                    if (proc.thread != null && proc.setAdj == oomAdj) {
4753                        // Record this for posterity if the process has been stable.
4754                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4755                                infos[i].getTotalUss(), false, proc.pkgList);
4756                    }
4757                }
4758            }
4759        }
4760        return infos;
4761    }
4762
4763    @Override
4764    public long[] getProcessPss(int[] pids) {
4765        enforceNotIsolatedCaller("getProcessPss");
4766        long[] pss = new long[pids.length];
4767        for (int i=pids.length-1; i>=0; i--) {
4768            ProcessRecord proc;
4769            int oomAdj;
4770            synchronized (this) {
4771                synchronized (mPidsSelfLocked) {
4772                    proc = mPidsSelfLocked.get(pids[i]);
4773                    oomAdj = proc != null ? proc.setAdj : 0;
4774                }
4775            }
4776            long[] tmpUss = new long[1];
4777            pss[i] = Debug.getPss(pids[i], tmpUss);
4778            if (proc != null) {
4779                synchronized (this) {
4780                    if (proc.thread != null && proc.setAdj == oomAdj) {
4781                        // Record this for posterity if the process has been stable.
4782                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4783                    }
4784                }
4785            }
4786        }
4787        return pss;
4788    }
4789
4790    @Override
4791    public void killApplicationProcess(String processName, int uid) {
4792        if (processName == null) {
4793            return;
4794        }
4795
4796        int callerUid = Binder.getCallingUid();
4797        // Only the system server can kill an application
4798        if (callerUid == Process.SYSTEM_UID) {
4799            synchronized (this) {
4800                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4801                if (app != null && app.thread != null) {
4802                    try {
4803                        app.thread.scheduleSuicide();
4804                    } catch (RemoteException e) {
4805                        // If the other end already died, then our work here is done.
4806                    }
4807                } else {
4808                    Slog.w(TAG, "Process/uid not found attempting kill of "
4809                            + processName + " / " + uid);
4810                }
4811            }
4812        } else {
4813            throw new SecurityException(callerUid + " cannot kill app process: " +
4814                    processName);
4815        }
4816    }
4817
4818    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4819        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4820                false, true, false, false, UserHandle.getUserId(uid), reason);
4821        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4822                Uri.fromParts("package", packageName, null));
4823        if (!mProcessesReady) {
4824            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4825                    | Intent.FLAG_RECEIVER_FOREGROUND);
4826        }
4827        intent.putExtra(Intent.EXTRA_UID, uid);
4828        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4829        broadcastIntentLocked(null, null, intent,
4830                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4831                false, false,
4832                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4833    }
4834
4835    private void forceStopUserLocked(int userId, String reason) {
4836        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4837        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4838        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4839                | Intent.FLAG_RECEIVER_FOREGROUND);
4840        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4841        broadcastIntentLocked(null, null, intent,
4842                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4843                false, false,
4844                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4845    }
4846
4847    private final boolean killPackageProcessesLocked(String packageName, int appId,
4848            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4849            boolean doit, boolean evenPersistent, String reason) {
4850        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4851
4852        // Remove all processes this package may have touched: all with the
4853        // same UID (except for the system or root user), and all whose name
4854        // matches the package name.
4855        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4856        final int NP = mProcessNames.getMap().size();
4857        for (int ip=0; ip<NP; ip++) {
4858            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4859            final int NA = apps.size();
4860            for (int ia=0; ia<NA; ia++) {
4861                ProcessRecord app = apps.valueAt(ia);
4862                if (app.persistent && !evenPersistent) {
4863                    // we don't kill persistent processes
4864                    continue;
4865                }
4866                if (app.removed) {
4867                    if (doit) {
4868                        procs.add(app);
4869                    }
4870                    continue;
4871                }
4872
4873                // Skip process if it doesn't meet our oom adj requirement.
4874                if (app.setAdj < minOomAdj) {
4875                    continue;
4876                }
4877
4878                // If no package is specified, we call all processes under the
4879                // give user id.
4880                if (packageName == null) {
4881                    if (app.userId != userId) {
4882                        continue;
4883                    }
4884                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4885                        continue;
4886                    }
4887                // Package has been specified, we want to hit all processes
4888                // that match it.  We need to qualify this by the processes
4889                // that are running under the specified app and user ID.
4890                } else {
4891                    if (UserHandle.getAppId(app.uid) != appId) {
4892                        continue;
4893                    }
4894                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4895                        continue;
4896                    }
4897                    if (!app.pkgList.containsKey(packageName)) {
4898                        continue;
4899                    }
4900                }
4901
4902                // Process has passed all conditions, kill it!
4903                if (!doit) {
4904                    return true;
4905                }
4906                app.removed = true;
4907                procs.add(app);
4908            }
4909        }
4910
4911        int N = procs.size();
4912        for (int i=0; i<N; i++) {
4913            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4914        }
4915        updateOomAdjLocked();
4916        return N > 0;
4917    }
4918
4919    private final boolean forceStopPackageLocked(String name, int appId,
4920            boolean callerWillRestart, boolean purgeCache, boolean doit,
4921            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4922        int i;
4923        int N;
4924
4925        if (userId == UserHandle.USER_ALL && name == null) {
4926            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4927        }
4928
4929        if (appId < 0 && name != null) {
4930            try {
4931                appId = UserHandle.getAppId(
4932                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4933            } catch (RemoteException e) {
4934            }
4935        }
4936
4937        if (doit) {
4938            if (name != null) {
4939                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4940                        + " user=" + userId + ": " + reason);
4941            } else {
4942                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4943            }
4944
4945            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4946            for (int ip=pmap.size()-1; ip>=0; ip--) {
4947                SparseArray<Long> ba = pmap.valueAt(ip);
4948                for (i=ba.size()-1; i>=0; i--) {
4949                    boolean remove = false;
4950                    final int entUid = ba.keyAt(i);
4951                    if (name != null) {
4952                        if (userId == UserHandle.USER_ALL) {
4953                            if (UserHandle.getAppId(entUid) == appId) {
4954                                remove = true;
4955                            }
4956                        } else {
4957                            if (entUid == UserHandle.getUid(userId, appId)) {
4958                                remove = true;
4959                            }
4960                        }
4961                    } else if (UserHandle.getUserId(entUid) == userId) {
4962                        remove = true;
4963                    }
4964                    if (remove) {
4965                        ba.removeAt(i);
4966                    }
4967                }
4968                if (ba.size() == 0) {
4969                    pmap.removeAt(ip);
4970                }
4971            }
4972        }
4973
4974        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4975                -100, callerWillRestart, true, doit, evenPersistent,
4976                name == null ? ("stop user " + userId) : ("stop " + name));
4977
4978        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4979            if (!doit) {
4980                return true;
4981            }
4982            didSomething = true;
4983        }
4984
4985        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4986            if (!doit) {
4987                return true;
4988            }
4989            didSomething = true;
4990        }
4991
4992        if (name == null) {
4993            // Remove all sticky broadcasts from this user.
4994            mStickyBroadcasts.remove(userId);
4995        }
4996
4997        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4998        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4999                userId, providers)) {
5000            if (!doit) {
5001                return true;
5002            }
5003            didSomething = true;
5004        }
5005        N = providers.size();
5006        for (i=0; i<N; i++) {
5007            removeDyingProviderLocked(null, providers.get(i), true);
5008        }
5009
5010        // Remove transient permissions granted from/to this package/user
5011        removeUriPermissionsForPackageLocked(name, userId, false);
5012
5013        if (name == null || uninstalling) {
5014            // Remove pending intents.  For now we only do this when force
5015            // stopping users, because we have some problems when doing this
5016            // for packages -- app widgets are not currently cleaned up for
5017            // such packages, so they can be left with bad pending intents.
5018            if (mIntentSenderRecords.size() > 0) {
5019                Iterator<WeakReference<PendingIntentRecord>> it
5020                        = mIntentSenderRecords.values().iterator();
5021                while (it.hasNext()) {
5022                    WeakReference<PendingIntentRecord> wpir = it.next();
5023                    if (wpir == null) {
5024                        it.remove();
5025                        continue;
5026                    }
5027                    PendingIntentRecord pir = wpir.get();
5028                    if (pir == null) {
5029                        it.remove();
5030                        continue;
5031                    }
5032                    if (name == null) {
5033                        // Stopping user, remove all objects for the user.
5034                        if (pir.key.userId != userId) {
5035                            // Not the same user, skip it.
5036                            continue;
5037                        }
5038                    } else {
5039                        if (UserHandle.getAppId(pir.uid) != appId) {
5040                            // Different app id, skip it.
5041                            continue;
5042                        }
5043                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5044                            // Different user, skip it.
5045                            continue;
5046                        }
5047                        if (!pir.key.packageName.equals(name)) {
5048                            // Different package, skip it.
5049                            continue;
5050                        }
5051                    }
5052                    if (!doit) {
5053                        return true;
5054                    }
5055                    didSomething = true;
5056                    it.remove();
5057                    pir.canceled = true;
5058                    if (pir.key.activity != null) {
5059                        pir.key.activity.pendingResults.remove(pir.ref);
5060                    }
5061                }
5062            }
5063        }
5064
5065        if (doit) {
5066            if (purgeCache && name != null) {
5067                AttributeCache ac = AttributeCache.instance();
5068                if (ac != null) {
5069                    ac.removePackage(name);
5070                }
5071            }
5072            if (mBooted) {
5073                mStackSupervisor.resumeTopActivitiesLocked();
5074                mStackSupervisor.scheduleIdleLocked();
5075            }
5076        }
5077
5078        return didSomething;
5079    }
5080
5081    private final boolean removeProcessLocked(ProcessRecord app,
5082            boolean callerWillRestart, boolean allowRestart, String reason) {
5083        final String name = app.processName;
5084        final int uid = app.uid;
5085        if (DEBUG_PROCESSES) Slog.d(
5086            TAG, "Force removing proc " + app.toShortString() + " (" + name
5087            + "/" + uid + ")");
5088
5089        mProcessNames.remove(name, uid);
5090        mIsolatedProcesses.remove(app.uid);
5091        if (mHeavyWeightProcess == app) {
5092            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5093                    mHeavyWeightProcess.userId, 0));
5094            mHeavyWeightProcess = null;
5095        }
5096        boolean needRestart = false;
5097        if (app.pid > 0 && app.pid != MY_PID) {
5098            int pid = app.pid;
5099            synchronized (mPidsSelfLocked) {
5100                mPidsSelfLocked.remove(pid);
5101                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5102            }
5103            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5104                    app.processName, app.info.uid);
5105            if (app.isolated) {
5106                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5107            }
5108            killUnneededProcessLocked(app, reason);
5109            handleAppDiedLocked(app, true, allowRestart);
5110            removeLruProcessLocked(app);
5111
5112            if (app.persistent && !app.isolated) {
5113                if (!callerWillRestart) {
5114                    addAppLocked(app.info, false, null /* ABI override */);
5115                } else {
5116                    needRestart = true;
5117                }
5118            }
5119        } else {
5120            mRemovedProcesses.add(app);
5121        }
5122
5123        return needRestart;
5124    }
5125
5126    private final void processStartTimedOutLocked(ProcessRecord app) {
5127        final int pid = app.pid;
5128        boolean gone = false;
5129        synchronized (mPidsSelfLocked) {
5130            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5131            if (knownApp != null && knownApp.thread == null) {
5132                mPidsSelfLocked.remove(pid);
5133                gone = true;
5134            }
5135        }
5136
5137        if (gone) {
5138            Slog.w(TAG, "Process " + app + " failed to attach");
5139            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5140                    pid, app.uid, app.processName);
5141            mProcessNames.remove(app.processName, app.uid);
5142            mIsolatedProcesses.remove(app.uid);
5143            if (mHeavyWeightProcess == app) {
5144                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5145                        mHeavyWeightProcess.userId, 0));
5146                mHeavyWeightProcess = null;
5147            }
5148            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5149                    app.processName, app.info.uid);
5150            if (app.isolated) {
5151                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5152            }
5153            // Take care of any launching providers waiting for this process.
5154            checkAppInLaunchingProvidersLocked(app, true);
5155            // Take care of any services that are waiting for the process.
5156            mServices.processStartTimedOutLocked(app);
5157            killUnneededProcessLocked(app, "start timeout");
5158            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5159                Slog.w(TAG, "Unattached app died before backup, skipping");
5160                try {
5161                    IBackupManager bm = IBackupManager.Stub.asInterface(
5162                            ServiceManager.getService(Context.BACKUP_SERVICE));
5163                    bm.agentDisconnected(app.info.packageName);
5164                } catch (RemoteException e) {
5165                    // Can't happen; the backup manager is local
5166                }
5167            }
5168            if (isPendingBroadcastProcessLocked(pid)) {
5169                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5170                skipPendingBroadcastLocked(pid);
5171            }
5172        } else {
5173            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5174        }
5175    }
5176
5177    private final boolean attachApplicationLocked(IApplicationThread thread,
5178            int pid) {
5179
5180        // Find the application record that is being attached...  either via
5181        // the pid if we are running in multiple processes, or just pull the
5182        // next app record if we are emulating process with anonymous threads.
5183        ProcessRecord app;
5184        if (pid != MY_PID && pid >= 0) {
5185            synchronized (mPidsSelfLocked) {
5186                app = mPidsSelfLocked.get(pid);
5187            }
5188        } else {
5189            app = null;
5190        }
5191
5192        if (app == null) {
5193            Slog.w(TAG, "No pending application record for pid " + pid
5194                    + " (IApplicationThread " + thread + "); dropping process");
5195            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5196            if (pid > 0 && pid != MY_PID) {
5197                Process.killProcessQuiet(pid);
5198            } else {
5199                try {
5200                    thread.scheduleExit();
5201                } catch (Exception e) {
5202                    // Ignore exceptions.
5203                }
5204            }
5205            return false;
5206        }
5207
5208        // If this application record is still attached to a previous
5209        // process, clean it up now.
5210        if (app.thread != null) {
5211            handleAppDiedLocked(app, true, true);
5212        }
5213
5214        // Tell the process all about itself.
5215
5216        if (localLOGV) Slog.v(
5217                TAG, "Binding process pid " + pid + " to record " + app);
5218
5219        final String processName = app.processName;
5220        try {
5221            AppDeathRecipient adr = new AppDeathRecipient(
5222                    app, pid, thread);
5223            thread.asBinder().linkToDeath(adr, 0);
5224            app.deathRecipient = adr;
5225        } catch (RemoteException e) {
5226            app.resetPackageList(mProcessStats);
5227            startProcessLocked(app, "link fail", processName, null /* ABI override */);
5228            return false;
5229        }
5230
5231        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5232
5233        app.makeActive(thread, mProcessStats);
5234        app.curAdj = app.setAdj = -100;
5235        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5236        app.forcingToForeground = null;
5237        updateProcessForegroundLocked(app, false, false);
5238        app.hasShownUi = false;
5239        app.debugging = false;
5240        app.cached = false;
5241
5242        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5243
5244        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5245        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5246
5247        if (!normalMode) {
5248            Slog.i(TAG, "Launching preboot mode app: " + app);
5249        }
5250
5251        if (localLOGV) Slog.v(
5252            TAG, "New app record " + app
5253            + " thread=" + thread.asBinder() + " pid=" + pid);
5254        try {
5255            int testMode = IApplicationThread.DEBUG_OFF;
5256            if (mDebugApp != null && mDebugApp.equals(processName)) {
5257                testMode = mWaitForDebugger
5258                    ? IApplicationThread.DEBUG_WAIT
5259                    : IApplicationThread.DEBUG_ON;
5260                app.debugging = true;
5261                if (mDebugTransient) {
5262                    mDebugApp = mOrigDebugApp;
5263                    mWaitForDebugger = mOrigWaitForDebugger;
5264                }
5265            }
5266            String profileFile = app.instrumentationProfileFile;
5267            ParcelFileDescriptor profileFd = null;
5268            boolean profileAutoStop = false;
5269            if (mProfileApp != null && mProfileApp.equals(processName)) {
5270                mProfileProc = app;
5271                profileFile = mProfileFile;
5272                profileFd = mProfileFd;
5273                profileAutoStop = mAutoStopProfiler;
5274            }
5275            boolean enableOpenGlTrace = false;
5276            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5277                enableOpenGlTrace = true;
5278                mOpenGlTraceApp = null;
5279            }
5280
5281            // If the app is being launched for restore or full backup, set it up specially
5282            boolean isRestrictedBackupMode = false;
5283            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5284                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5285                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5286                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5287            }
5288
5289            ensurePackageDexOpt(app.instrumentationInfo != null
5290                    ? app.instrumentationInfo.packageName
5291                    : app.info.packageName);
5292            if (app.instrumentationClass != null) {
5293                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5294            }
5295            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5296                    + processName + " with config " + mConfiguration);
5297            ApplicationInfo appInfo = app.instrumentationInfo != null
5298                    ? app.instrumentationInfo : app.info;
5299            app.compat = compatibilityInfoForPackageLocked(appInfo);
5300            if (profileFd != null) {
5301                profileFd = profileFd.dup();
5302            }
5303            thread.bindApplication(processName, appInfo, providers,
5304                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5305                    app.instrumentationArguments, app.instrumentationWatcher,
5306                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5307                    isRestrictedBackupMode || !normalMode, app.persistent,
5308                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5309                    mCoreSettingsObserver.getCoreSettingsLocked());
5310            updateLruProcessLocked(app, false, null);
5311            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5312        } catch (Exception e) {
5313            // todo: Yikes!  What should we do?  For now we will try to
5314            // start another process, but that could easily get us in
5315            // an infinite loop of restarting processes...
5316            Slog.w(TAG, "Exception thrown during bind!", e);
5317
5318            app.resetPackageList(mProcessStats);
5319            app.unlinkDeathRecipient();
5320            startProcessLocked(app, "bind fail", processName, null /* ABI override */);
5321            return false;
5322        }
5323
5324        // Remove this record from the list of starting applications.
5325        mPersistentStartingProcesses.remove(app);
5326        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5327                "Attach application locked removing on hold: " + app);
5328        mProcessesOnHold.remove(app);
5329
5330        boolean badApp = false;
5331        boolean didSomething = false;
5332
5333        // See if the top visible activity is waiting to run in this process...
5334        if (normalMode) {
5335            try {
5336                if (mStackSupervisor.attachApplicationLocked(app)) {
5337                    didSomething = true;
5338                }
5339            } catch (Exception e) {
5340                badApp = true;
5341            }
5342        }
5343
5344        // Find any services that should be running in this process...
5345        if (!badApp) {
5346            try {
5347                didSomething |= mServices.attachApplicationLocked(app, processName);
5348            } catch (Exception e) {
5349                badApp = true;
5350            }
5351        }
5352
5353        // Check if a next-broadcast receiver is in this process...
5354        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5355            try {
5356                didSomething |= sendPendingBroadcastsLocked(app);
5357            } catch (Exception e) {
5358                // If the app died trying to launch the receiver we declare it 'bad'
5359                badApp = true;
5360            }
5361        }
5362
5363        // Check whether the next backup agent is in this process...
5364        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5365            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5366            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5367            try {
5368                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5369                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5370                        mBackupTarget.backupMode);
5371            } catch (Exception e) {
5372                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5373                e.printStackTrace();
5374            }
5375        }
5376
5377        if (badApp) {
5378            // todo: Also need to kill application to deal with all
5379            // kinds of exceptions.
5380            handleAppDiedLocked(app, false, true);
5381            return false;
5382        }
5383
5384        if (!didSomething) {
5385            updateOomAdjLocked();
5386        }
5387
5388        return true;
5389    }
5390
5391    @Override
5392    public final void attachApplication(IApplicationThread thread) {
5393        synchronized (this) {
5394            int callingPid = Binder.getCallingPid();
5395            final long origId = Binder.clearCallingIdentity();
5396            attachApplicationLocked(thread, callingPid);
5397            Binder.restoreCallingIdentity(origId);
5398        }
5399    }
5400
5401    @Override
5402    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5403        final long origId = Binder.clearCallingIdentity();
5404        synchronized (this) {
5405            ActivityStack stack = ActivityRecord.getStackLocked(token);
5406            if (stack != null) {
5407                ActivityRecord r =
5408                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5409                if (stopProfiling) {
5410                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5411                        try {
5412                            mProfileFd.close();
5413                        } catch (IOException e) {
5414                        }
5415                        clearProfilerLocked();
5416                    }
5417                }
5418            }
5419        }
5420        Binder.restoreCallingIdentity(origId);
5421    }
5422
5423    void enableScreenAfterBoot() {
5424        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5425                SystemClock.uptimeMillis());
5426        mWindowManager.enableScreenAfterBoot();
5427
5428        synchronized (this) {
5429            updateEventDispatchingLocked();
5430        }
5431    }
5432
5433    @Override
5434    public void showBootMessage(final CharSequence msg, final boolean always) {
5435        enforceNotIsolatedCaller("showBootMessage");
5436        mWindowManager.showBootMessage(msg, always);
5437    }
5438
5439    @Override
5440    public void dismissKeyguardOnNextActivity() {
5441        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5442        final long token = Binder.clearCallingIdentity();
5443        try {
5444            synchronized (this) {
5445                if (DEBUG_LOCKSCREEN) logLockScreen("");
5446                if (mLockScreenShown) {
5447                    mLockScreenShown = false;
5448                    comeOutOfSleepIfNeededLocked();
5449                }
5450                mStackSupervisor.setDismissKeyguard(true);
5451            }
5452        } finally {
5453            Binder.restoreCallingIdentity(token);
5454        }
5455    }
5456
5457    final void finishBooting() {
5458        // Register receivers to handle package update events
5459        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5460
5461        synchronized (this) {
5462            // Ensure that any processes we had put on hold are now started
5463            // up.
5464            final int NP = mProcessesOnHold.size();
5465            if (NP > 0) {
5466                ArrayList<ProcessRecord> procs =
5467                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5468                for (int ip=0; ip<NP; ip++) {
5469                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5470                            + procs.get(ip));
5471                    startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */);
5472                }
5473            }
5474
5475            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5476                // Start looking for apps that are abusing wake locks.
5477                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5478                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5479                // Tell anyone interested that we are done booting!
5480                SystemProperties.set("sys.boot_completed", "1");
5481                SystemProperties.set("dev.bootcomplete", "1");
5482                for (int i=0; i<mStartedUsers.size(); i++) {
5483                    UserStartedState uss = mStartedUsers.valueAt(i);
5484                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5485                        uss.mState = UserStartedState.STATE_RUNNING;
5486                        final int userId = mStartedUsers.keyAt(i);
5487                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5488                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5489                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5490                        broadcastIntentLocked(null, null, intent, null,
5491                                new IIntentReceiver.Stub() {
5492                                    @Override
5493                                    public void performReceive(Intent intent, int resultCode,
5494                                            String data, Bundle extras, boolean ordered,
5495                                            boolean sticky, int sendingUser) {
5496                                        synchronized (ActivityManagerService.this) {
5497                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5498                                                    true, false);
5499                                        }
5500                                    }
5501                                },
5502                                0, null, null,
5503                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5504                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5505                                userId);
5506                    }
5507                }
5508                scheduleStartProfilesLocked();
5509            }
5510        }
5511    }
5512
5513    final void ensureBootCompleted() {
5514        boolean booting;
5515        boolean enableScreen;
5516        synchronized (this) {
5517            booting = mBooting;
5518            mBooting = false;
5519            enableScreen = !mBooted;
5520            mBooted = true;
5521        }
5522
5523        if (booting) {
5524            finishBooting();
5525        }
5526
5527        if (enableScreen) {
5528            enableScreenAfterBoot();
5529        }
5530    }
5531
5532    @Override
5533    public final void activityResumed(IBinder token) {
5534        final long origId = Binder.clearCallingIdentity();
5535        synchronized(this) {
5536            ActivityStack stack = ActivityRecord.getStackLocked(token);
5537            if (stack != null) {
5538                ActivityRecord.activityResumedLocked(token);
5539            }
5540        }
5541        Binder.restoreCallingIdentity(origId);
5542    }
5543
5544    @Override
5545    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5546        final long origId = Binder.clearCallingIdentity();
5547        synchronized(this) {
5548            ActivityStack stack = ActivityRecord.getStackLocked(token);
5549            if (stack != null) {
5550                stack.activityPausedLocked(token, false, persistentState);
5551            }
5552        }
5553        Binder.restoreCallingIdentity(origId);
5554    }
5555
5556    @Override
5557    public final void activityStopped(IBinder token, Bundle icicle,
5558            PersistableBundle persistentState, CharSequence description) {
5559        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5560
5561        // Refuse possible leaked file descriptors
5562        if (icicle != null && icicle.hasFileDescriptors()) {
5563            throw new IllegalArgumentException("File descriptors passed in Bundle");
5564        }
5565
5566        final long origId = Binder.clearCallingIdentity();
5567
5568        synchronized (this) {
5569            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5570            if (r != null) {
5571                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5572            }
5573        }
5574
5575        trimApplications();
5576
5577        Binder.restoreCallingIdentity(origId);
5578    }
5579
5580    @Override
5581    public final void activityDestroyed(IBinder token) {
5582        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5583        synchronized (this) {
5584            ActivityStack stack = ActivityRecord.getStackLocked(token);
5585            if (stack != null) {
5586                stack.activityDestroyedLocked(token);
5587            }
5588        }
5589    }
5590
5591    @Override
5592    public String getCallingPackage(IBinder token) {
5593        synchronized (this) {
5594            ActivityRecord r = getCallingRecordLocked(token);
5595            return r != null ? r.info.packageName : null;
5596        }
5597    }
5598
5599    @Override
5600    public ComponentName getCallingActivity(IBinder token) {
5601        synchronized (this) {
5602            ActivityRecord r = getCallingRecordLocked(token);
5603            return r != null ? r.intent.getComponent() : null;
5604        }
5605    }
5606
5607    private ActivityRecord getCallingRecordLocked(IBinder token) {
5608        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5609        if (r == null) {
5610            return null;
5611        }
5612        return r.resultTo;
5613    }
5614
5615    @Override
5616    public ComponentName getActivityClassForToken(IBinder token) {
5617        synchronized(this) {
5618            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5619            if (r == null) {
5620                return null;
5621            }
5622            return r.intent.getComponent();
5623        }
5624    }
5625
5626    @Override
5627    public String getPackageForToken(IBinder token) {
5628        synchronized(this) {
5629            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5630            if (r == null) {
5631                return null;
5632            }
5633            return r.packageName;
5634        }
5635    }
5636
5637    @Override
5638    public IIntentSender getIntentSender(int type,
5639            String packageName, IBinder token, String resultWho,
5640            int requestCode, Intent[] intents, String[] resolvedTypes,
5641            int flags, Bundle options, int userId) {
5642        enforceNotIsolatedCaller("getIntentSender");
5643        // Refuse possible leaked file descriptors
5644        if (intents != null) {
5645            if (intents.length < 1) {
5646                throw new IllegalArgumentException("Intents array length must be >= 1");
5647            }
5648            for (int i=0; i<intents.length; i++) {
5649                Intent intent = intents[i];
5650                if (intent != null) {
5651                    if (intent.hasFileDescriptors()) {
5652                        throw new IllegalArgumentException("File descriptors passed in Intent");
5653                    }
5654                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5655                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5656                        throw new IllegalArgumentException(
5657                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5658                    }
5659                    intents[i] = new Intent(intent);
5660                }
5661            }
5662            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5663                throw new IllegalArgumentException(
5664                        "Intent array length does not match resolvedTypes length");
5665            }
5666        }
5667        if (options != null) {
5668            if (options.hasFileDescriptors()) {
5669                throw new IllegalArgumentException("File descriptors passed in options");
5670            }
5671        }
5672
5673        synchronized(this) {
5674            int callingUid = Binder.getCallingUid();
5675            int origUserId = userId;
5676            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5677                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5678                    "getIntentSender", null);
5679            if (origUserId == UserHandle.USER_CURRENT) {
5680                // We don't want to evaluate this until the pending intent is
5681                // actually executed.  However, we do want to always do the
5682                // security checking for it above.
5683                userId = UserHandle.USER_CURRENT;
5684            }
5685            try {
5686                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5687                    int uid = AppGlobals.getPackageManager()
5688                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5689                    if (!UserHandle.isSameApp(callingUid, uid)) {
5690                        String msg = "Permission Denial: getIntentSender() from pid="
5691                            + Binder.getCallingPid()
5692                            + ", uid=" + Binder.getCallingUid()
5693                            + ", (need uid=" + uid + ")"
5694                            + " is not allowed to send as package " + packageName;
5695                        Slog.w(TAG, msg);
5696                        throw new SecurityException(msg);
5697                    }
5698                }
5699
5700                return getIntentSenderLocked(type, packageName, callingUid, userId,
5701                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5702
5703            } catch (RemoteException e) {
5704                throw new SecurityException(e);
5705            }
5706        }
5707    }
5708
5709    IIntentSender getIntentSenderLocked(int type, String packageName,
5710            int callingUid, int userId, IBinder token, String resultWho,
5711            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5712            Bundle options) {
5713        if (DEBUG_MU)
5714            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5715        ActivityRecord activity = null;
5716        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5717            activity = ActivityRecord.isInStackLocked(token);
5718            if (activity == null) {
5719                return null;
5720            }
5721            if (activity.finishing) {
5722                return null;
5723            }
5724        }
5725
5726        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5727        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5728        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5729        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5730                |PendingIntent.FLAG_UPDATE_CURRENT);
5731
5732        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5733                type, packageName, activity, resultWho,
5734                requestCode, intents, resolvedTypes, flags, options, userId);
5735        WeakReference<PendingIntentRecord> ref;
5736        ref = mIntentSenderRecords.get(key);
5737        PendingIntentRecord rec = ref != null ? ref.get() : null;
5738        if (rec != null) {
5739            if (!cancelCurrent) {
5740                if (updateCurrent) {
5741                    if (rec.key.requestIntent != null) {
5742                        rec.key.requestIntent.replaceExtras(intents != null ?
5743                                intents[intents.length - 1] : null);
5744                    }
5745                    if (intents != null) {
5746                        intents[intents.length-1] = rec.key.requestIntent;
5747                        rec.key.allIntents = intents;
5748                        rec.key.allResolvedTypes = resolvedTypes;
5749                    } else {
5750                        rec.key.allIntents = null;
5751                        rec.key.allResolvedTypes = null;
5752                    }
5753                }
5754                return rec;
5755            }
5756            rec.canceled = true;
5757            mIntentSenderRecords.remove(key);
5758        }
5759        if (noCreate) {
5760            return rec;
5761        }
5762        rec = new PendingIntentRecord(this, key, callingUid);
5763        mIntentSenderRecords.put(key, rec.ref);
5764        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5765            if (activity.pendingResults == null) {
5766                activity.pendingResults
5767                        = new HashSet<WeakReference<PendingIntentRecord>>();
5768            }
5769            activity.pendingResults.add(rec.ref);
5770        }
5771        return rec;
5772    }
5773
5774    @Override
5775    public void cancelIntentSender(IIntentSender sender) {
5776        if (!(sender instanceof PendingIntentRecord)) {
5777            return;
5778        }
5779        synchronized(this) {
5780            PendingIntentRecord rec = (PendingIntentRecord)sender;
5781            try {
5782                int uid = AppGlobals.getPackageManager()
5783                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5784                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5785                    String msg = "Permission Denial: cancelIntentSender() from pid="
5786                        + Binder.getCallingPid()
5787                        + ", uid=" + Binder.getCallingUid()
5788                        + " is not allowed to cancel packges "
5789                        + rec.key.packageName;
5790                    Slog.w(TAG, msg);
5791                    throw new SecurityException(msg);
5792                }
5793            } catch (RemoteException e) {
5794                throw new SecurityException(e);
5795            }
5796            cancelIntentSenderLocked(rec, true);
5797        }
5798    }
5799
5800    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5801        rec.canceled = true;
5802        mIntentSenderRecords.remove(rec.key);
5803        if (cleanActivity && rec.key.activity != null) {
5804            rec.key.activity.pendingResults.remove(rec.ref);
5805        }
5806    }
5807
5808    @Override
5809    public String getPackageForIntentSender(IIntentSender pendingResult) {
5810        if (!(pendingResult instanceof PendingIntentRecord)) {
5811            return null;
5812        }
5813        try {
5814            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5815            return res.key.packageName;
5816        } catch (ClassCastException e) {
5817        }
5818        return null;
5819    }
5820
5821    @Override
5822    public int getUidForIntentSender(IIntentSender sender) {
5823        if (sender instanceof PendingIntentRecord) {
5824            try {
5825                PendingIntentRecord res = (PendingIntentRecord)sender;
5826                return res.uid;
5827            } catch (ClassCastException e) {
5828            }
5829        }
5830        return -1;
5831    }
5832
5833    @Override
5834    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5835        if (!(pendingResult instanceof PendingIntentRecord)) {
5836            return false;
5837        }
5838        try {
5839            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5840            if (res.key.allIntents == null) {
5841                return false;
5842            }
5843            for (int i=0; i<res.key.allIntents.length; i++) {
5844                Intent intent = res.key.allIntents[i];
5845                if (intent.getPackage() != null && intent.getComponent() != null) {
5846                    return false;
5847                }
5848            }
5849            return true;
5850        } catch (ClassCastException e) {
5851        }
5852        return false;
5853    }
5854
5855    @Override
5856    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5857        if (!(pendingResult instanceof PendingIntentRecord)) {
5858            return false;
5859        }
5860        try {
5861            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5862            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5863                return true;
5864            }
5865            return false;
5866        } catch (ClassCastException e) {
5867        }
5868        return false;
5869    }
5870
5871    @Override
5872    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5873        if (!(pendingResult instanceof PendingIntentRecord)) {
5874            return null;
5875        }
5876        try {
5877            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5878            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5879        } catch (ClassCastException e) {
5880        }
5881        return null;
5882    }
5883
5884    @Override
5885    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5886        if (!(pendingResult instanceof PendingIntentRecord)) {
5887            return null;
5888        }
5889        try {
5890            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5891            Intent intent = res.key.requestIntent;
5892            if (intent != null) {
5893                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5894                        || res.lastTagPrefix.equals(prefix))) {
5895                    return res.lastTag;
5896                }
5897                res.lastTagPrefix = prefix;
5898                StringBuilder sb = new StringBuilder(128);
5899                if (prefix != null) {
5900                    sb.append(prefix);
5901                }
5902                if (intent.getAction() != null) {
5903                    sb.append(intent.getAction());
5904                } else if (intent.getComponent() != null) {
5905                    intent.getComponent().appendShortString(sb);
5906                } else {
5907                    sb.append("?");
5908                }
5909                return res.lastTag = sb.toString();
5910            }
5911        } catch (ClassCastException e) {
5912        }
5913        return null;
5914    }
5915
5916    @Override
5917    public void setProcessLimit(int max) {
5918        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5919                "setProcessLimit()");
5920        synchronized (this) {
5921            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5922            mProcessLimitOverride = max;
5923        }
5924        trimApplications();
5925    }
5926
5927    @Override
5928    public int getProcessLimit() {
5929        synchronized (this) {
5930            return mProcessLimitOverride;
5931        }
5932    }
5933
5934    void foregroundTokenDied(ForegroundToken token) {
5935        synchronized (ActivityManagerService.this) {
5936            synchronized (mPidsSelfLocked) {
5937                ForegroundToken cur
5938                    = mForegroundProcesses.get(token.pid);
5939                if (cur != token) {
5940                    return;
5941                }
5942                mForegroundProcesses.remove(token.pid);
5943                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5944                if (pr == null) {
5945                    return;
5946                }
5947                pr.forcingToForeground = null;
5948                updateProcessForegroundLocked(pr, false, false);
5949            }
5950            updateOomAdjLocked();
5951        }
5952    }
5953
5954    @Override
5955    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5956        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5957                "setProcessForeground()");
5958        synchronized(this) {
5959            boolean changed = false;
5960
5961            synchronized (mPidsSelfLocked) {
5962                ProcessRecord pr = mPidsSelfLocked.get(pid);
5963                if (pr == null && isForeground) {
5964                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5965                    return;
5966                }
5967                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5968                if (oldToken != null) {
5969                    oldToken.token.unlinkToDeath(oldToken, 0);
5970                    mForegroundProcesses.remove(pid);
5971                    if (pr != null) {
5972                        pr.forcingToForeground = null;
5973                    }
5974                    changed = true;
5975                }
5976                if (isForeground && token != null) {
5977                    ForegroundToken newToken = new ForegroundToken() {
5978                        @Override
5979                        public void binderDied() {
5980                            foregroundTokenDied(this);
5981                        }
5982                    };
5983                    newToken.pid = pid;
5984                    newToken.token = token;
5985                    try {
5986                        token.linkToDeath(newToken, 0);
5987                        mForegroundProcesses.put(pid, newToken);
5988                        pr.forcingToForeground = token;
5989                        changed = true;
5990                    } catch (RemoteException e) {
5991                        // If the process died while doing this, we will later
5992                        // do the cleanup with the process death link.
5993                    }
5994                }
5995            }
5996
5997            if (changed) {
5998                updateOomAdjLocked();
5999            }
6000        }
6001    }
6002
6003    // =========================================================
6004    // PERMISSIONS
6005    // =========================================================
6006
6007    static class PermissionController extends IPermissionController.Stub {
6008        ActivityManagerService mActivityManagerService;
6009        PermissionController(ActivityManagerService activityManagerService) {
6010            mActivityManagerService = activityManagerService;
6011        }
6012
6013        @Override
6014        public boolean checkPermission(String permission, int pid, int uid) {
6015            return mActivityManagerService.checkPermission(permission, pid,
6016                    uid) == PackageManager.PERMISSION_GRANTED;
6017        }
6018    }
6019
6020    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6021        @Override
6022        public int checkComponentPermission(String permission, int pid, int uid,
6023                int owningUid, boolean exported) {
6024            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6025                    owningUid, exported);
6026        }
6027
6028        @Override
6029        public Object getAMSLock() {
6030            return ActivityManagerService.this;
6031        }
6032    }
6033
6034    /**
6035     * This can be called with or without the global lock held.
6036     */
6037    int checkComponentPermission(String permission, int pid, int uid,
6038            int owningUid, boolean exported) {
6039        // We might be performing an operation on behalf of an indirect binder
6040        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6041        // client identity accordingly before proceeding.
6042        Identity tlsIdentity = sCallerIdentity.get();
6043        if (tlsIdentity != null) {
6044            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6045                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6046            uid = tlsIdentity.uid;
6047            pid = tlsIdentity.pid;
6048        }
6049
6050        if (pid == MY_PID) {
6051            return PackageManager.PERMISSION_GRANTED;
6052        }
6053
6054        return ActivityManager.checkComponentPermission(permission, uid,
6055                owningUid, exported);
6056    }
6057
6058    /**
6059     * As the only public entry point for permissions checking, this method
6060     * can enforce the semantic that requesting a check on a null global
6061     * permission is automatically denied.  (Internally a null permission
6062     * string is used when calling {@link #checkComponentPermission} in cases
6063     * when only uid-based security is needed.)
6064     *
6065     * This can be called with or without the global lock held.
6066     */
6067    @Override
6068    public int checkPermission(String permission, int pid, int uid) {
6069        if (permission == null) {
6070            return PackageManager.PERMISSION_DENIED;
6071        }
6072        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6073    }
6074
6075    /**
6076     * Binder IPC calls go through the public entry point.
6077     * This can be called with or without the global lock held.
6078     */
6079    int checkCallingPermission(String permission) {
6080        return checkPermission(permission,
6081                Binder.getCallingPid(),
6082                UserHandle.getAppId(Binder.getCallingUid()));
6083    }
6084
6085    /**
6086     * This can be called with or without the global lock held.
6087     */
6088    void enforceCallingPermission(String permission, String func) {
6089        if (checkCallingPermission(permission)
6090                == PackageManager.PERMISSION_GRANTED) {
6091            return;
6092        }
6093
6094        String msg = "Permission Denial: " + func + " from pid="
6095                + Binder.getCallingPid()
6096                + ", uid=" + Binder.getCallingUid()
6097                + " requires " + permission;
6098        Slog.w(TAG, msg);
6099        throw new SecurityException(msg);
6100    }
6101
6102    /**
6103     * Determine if UID is holding permissions required to access {@link Uri} in
6104     * the given {@link ProviderInfo}. Final permission checking is always done
6105     * in {@link ContentProvider}.
6106     */
6107    private final boolean checkHoldingPermissionsLocked(
6108            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6109        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6110                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6111        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6112            return false;
6113        }
6114        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6115    }
6116
6117    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6118            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6119        if (pi.applicationInfo.uid == uid) {
6120            return true;
6121        } else if (!pi.exported) {
6122            return false;
6123        }
6124
6125        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6126        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6127        try {
6128            // check if target holds top-level <provider> permissions
6129            if (!readMet && pi.readPermission != null && considerUidPermissions
6130                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6131                readMet = true;
6132            }
6133            if (!writeMet && pi.writePermission != null && considerUidPermissions
6134                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6135                writeMet = true;
6136            }
6137
6138            // track if unprotected read/write is allowed; any denied
6139            // <path-permission> below removes this ability
6140            boolean allowDefaultRead = pi.readPermission == null;
6141            boolean allowDefaultWrite = pi.writePermission == null;
6142
6143            // check if target holds any <path-permission> that match uri
6144            final PathPermission[] pps = pi.pathPermissions;
6145            if (pps != null) {
6146                final String path = grantUri.uri.getPath();
6147                int i = pps.length;
6148                while (i > 0 && (!readMet || !writeMet)) {
6149                    i--;
6150                    PathPermission pp = pps[i];
6151                    if (pp.match(path)) {
6152                        if (!readMet) {
6153                            final String pprperm = pp.getReadPermission();
6154                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6155                                    + pprperm + " for " + pp.getPath()
6156                                    + ": match=" + pp.match(path)
6157                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6158                            if (pprperm != null) {
6159                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6160                                        == PERMISSION_GRANTED) {
6161                                    readMet = true;
6162                                } else {
6163                                    allowDefaultRead = false;
6164                                }
6165                            }
6166                        }
6167                        if (!writeMet) {
6168                            final String ppwperm = pp.getWritePermission();
6169                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6170                                    + ppwperm + " for " + pp.getPath()
6171                                    + ": match=" + pp.match(path)
6172                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6173                            if (ppwperm != null) {
6174                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6175                                        == PERMISSION_GRANTED) {
6176                                    writeMet = true;
6177                                } else {
6178                                    allowDefaultWrite = false;
6179                                }
6180                            }
6181                        }
6182                    }
6183                }
6184            }
6185
6186            // grant unprotected <provider> read/write, if not blocked by
6187            // <path-permission> above
6188            if (allowDefaultRead) readMet = true;
6189            if (allowDefaultWrite) writeMet = true;
6190
6191        } catch (RemoteException e) {
6192            return false;
6193        }
6194
6195        return readMet && writeMet;
6196    }
6197
6198    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6199        ProviderInfo pi = null;
6200        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6201        if (cpr != null) {
6202            pi = cpr.info;
6203        } else {
6204            try {
6205                pi = AppGlobals.getPackageManager().resolveContentProvider(
6206                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6207            } catch (RemoteException ex) {
6208            }
6209        }
6210        return pi;
6211    }
6212
6213    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6214        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6215        if (targetUris != null) {
6216            return targetUris.get(grantUri);
6217        }
6218        return null;
6219    }
6220
6221    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6222            String targetPkg, int targetUid, GrantUri grantUri) {
6223        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6224        if (targetUris == null) {
6225            targetUris = Maps.newArrayMap();
6226            mGrantedUriPermissions.put(targetUid, targetUris);
6227        }
6228
6229        UriPermission perm = targetUris.get(grantUri);
6230        if (perm == null) {
6231            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6232            targetUris.put(grantUri, perm);
6233        }
6234
6235        return perm;
6236    }
6237
6238    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6239            final int modeFlags) {
6240        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6241        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6242                : UriPermission.STRENGTH_OWNED;
6243
6244        // Root gets to do everything.
6245        if (uid == 0) {
6246            return true;
6247        }
6248
6249        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6250        if (perms == null) return false;
6251
6252        // First look for exact match
6253        final UriPermission exactPerm = perms.get(grantUri);
6254        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6255            return true;
6256        }
6257
6258        // No exact match, look for prefixes
6259        final int N = perms.size();
6260        for (int i = 0; i < N; i++) {
6261            final UriPermission perm = perms.valueAt(i);
6262            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6263                    && perm.getStrength(modeFlags) >= minStrength) {
6264                return true;
6265            }
6266        }
6267
6268        return false;
6269    }
6270
6271    @Override
6272    public int checkUriPermission(Uri uri, int pid, int uid,
6273            final int modeFlags, int userId) {
6274        enforceNotIsolatedCaller("checkUriPermission");
6275
6276        // Another redirected-binder-call permissions check as in
6277        // {@link checkComponentPermission}.
6278        Identity tlsIdentity = sCallerIdentity.get();
6279        if (tlsIdentity != null) {
6280            uid = tlsIdentity.uid;
6281            pid = tlsIdentity.pid;
6282        }
6283
6284        // Our own process gets to do everything.
6285        if (pid == MY_PID) {
6286            return PackageManager.PERMISSION_GRANTED;
6287        }
6288        synchronized (this) {
6289            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6290                    ? PackageManager.PERMISSION_GRANTED
6291                    : PackageManager.PERMISSION_DENIED;
6292        }
6293    }
6294
6295    /**
6296     * Check if the targetPkg can be granted permission to access uri by
6297     * the callingUid using the given modeFlags.  Throws a security exception
6298     * if callingUid is not allowed to do this.  Returns the uid of the target
6299     * if the URI permission grant should be performed; returns -1 if it is not
6300     * needed (for example targetPkg already has permission to access the URI).
6301     * If you already know the uid of the target, you can supply it in
6302     * lastTargetUid else set that to -1.
6303     */
6304    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6305            final int modeFlags, int lastTargetUid) {
6306        if (!Intent.isAccessUriMode(modeFlags)) {
6307            return -1;
6308        }
6309
6310        if (targetPkg != null) {
6311            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6312                    "Checking grant " + targetPkg + " permission to " + grantUri);
6313        }
6314
6315        final IPackageManager pm = AppGlobals.getPackageManager();
6316
6317        // If this is not a content: uri, we can't do anything with it.
6318        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6319            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6320                    "Can't grant URI permission for non-content URI: " + grantUri);
6321            return -1;
6322        }
6323
6324        final String authority = grantUri.uri.getAuthority();
6325        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6326        if (pi == null) {
6327            Slog.w(TAG, "No content provider found for permission check: " +
6328                    grantUri.uri.toSafeString());
6329            return -1;
6330        }
6331
6332        int targetUid = lastTargetUid;
6333        if (targetUid < 0 && targetPkg != null) {
6334            try {
6335                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6336                if (targetUid < 0) {
6337                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6338                            "Can't grant URI permission no uid for: " + targetPkg);
6339                    return -1;
6340                }
6341            } catch (RemoteException ex) {
6342                return -1;
6343            }
6344        }
6345
6346        if (targetUid >= 0) {
6347            // First...  does the target actually need this permission?
6348            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6349                // No need to grant the target this permission.
6350                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6351                        "Target " + targetPkg + " already has full permission to " + grantUri);
6352                return -1;
6353            }
6354        } else {
6355            // First...  there is no target package, so can anyone access it?
6356            boolean allowed = pi.exported;
6357            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6358                if (pi.readPermission != null) {
6359                    allowed = false;
6360                }
6361            }
6362            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6363                if (pi.writePermission != null) {
6364                    allowed = false;
6365                }
6366            }
6367            if (allowed) {
6368                return -1;
6369            }
6370        }
6371
6372        /* There is a special cross user grant if:
6373         * - The target is on another user.
6374         * - Apps on the current user can access the uri without any uid permissions.
6375         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6376         * grant uri permissions.
6377         */
6378        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6379                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6380                modeFlags, false /*without considering the uid permissions*/);
6381
6382        // Second...  is the provider allowing granting of URI permissions?
6383        if (!specialCrossUserGrant) {
6384            if (!pi.grantUriPermissions) {
6385                throw new SecurityException("Provider " + pi.packageName
6386                        + "/" + pi.name
6387                        + " does not allow granting of Uri permissions (uri "
6388                        + grantUri + ")");
6389            }
6390            if (pi.uriPermissionPatterns != null) {
6391                final int N = pi.uriPermissionPatterns.length;
6392                boolean allowed = false;
6393                for (int i=0; i<N; i++) {
6394                    if (pi.uriPermissionPatterns[i] != null
6395                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6396                        allowed = true;
6397                        break;
6398                    }
6399                }
6400                if (!allowed) {
6401                    throw new SecurityException("Provider " + pi.packageName
6402                            + "/" + pi.name
6403                            + " does not allow granting of permission to path of Uri "
6404                            + grantUri);
6405                }
6406            }
6407        }
6408
6409        // Third...  does the caller itself have permission to access
6410        // this uri?
6411        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6412            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6413                // Require they hold a strong enough Uri permission
6414                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6415                    throw new SecurityException("Uid " + callingUid
6416                            + " does not have permission to uri " + grantUri);
6417                }
6418            }
6419        }
6420        return targetUid;
6421    }
6422
6423    @Override
6424    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6425            final int modeFlags, int userId) {
6426        enforceNotIsolatedCaller("checkGrantUriPermission");
6427        synchronized(this) {
6428            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6429                    new GrantUri(userId, uri, false), modeFlags, -1);
6430        }
6431    }
6432
6433    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6434            final int modeFlags, UriPermissionOwner owner) {
6435        if (!Intent.isAccessUriMode(modeFlags)) {
6436            return;
6437        }
6438
6439        // So here we are: the caller has the assumed permission
6440        // to the uri, and the target doesn't.  Let's now give this to
6441        // the target.
6442
6443        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6444                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6445
6446        final String authority = grantUri.uri.getAuthority();
6447        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6448        if (pi == null) {
6449            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6450            return;
6451        }
6452
6453        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6454            grantUri.prefix = true;
6455        }
6456        final UriPermission perm = findOrCreateUriPermissionLocked(
6457                pi.packageName, targetPkg, targetUid, grantUri);
6458        perm.grantModes(modeFlags, owner);
6459    }
6460
6461    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6462            final int modeFlags, UriPermissionOwner owner) {
6463        if (targetPkg == null) {
6464            throw new NullPointerException("targetPkg");
6465        }
6466
6467        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6468                -1);
6469        if (targetUid < 0) {
6470            return;
6471        }
6472
6473        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6474                owner);
6475    }
6476
6477    static class NeededUriGrants extends ArrayList<GrantUri> {
6478        final String targetPkg;
6479        final int targetUid;
6480        final int flags;
6481
6482        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6483            this.targetPkg = targetPkg;
6484            this.targetUid = targetUid;
6485            this.flags = flags;
6486        }
6487    }
6488
6489    /**
6490     * Like checkGrantUriPermissionLocked, but takes an Intent.
6491     */
6492    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6493            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6494        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6495                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6496                + " clip=" + (intent != null ? intent.getClipData() : null)
6497                + " from " + intent + "; flags=0x"
6498                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6499
6500        if (targetPkg == null) {
6501            throw new NullPointerException("targetPkg");
6502        }
6503
6504        if (intent == null) {
6505            return null;
6506        }
6507        Uri data = intent.getData();
6508        ClipData clip = intent.getClipData();
6509        if (data == null && clip == null) {
6510            return null;
6511        }
6512        final IPackageManager pm = AppGlobals.getPackageManager();
6513        int targetUid;
6514        if (needed != null) {
6515            targetUid = needed.targetUid;
6516        } else {
6517            try {
6518                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6519            } catch (RemoteException ex) {
6520                return null;
6521            }
6522            if (targetUid < 0) {
6523                if (DEBUG_URI_PERMISSION) {
6524                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6525                            + " on user " + targetUserId);
6526                }
6527                return null;
6528            }
6529        }
6530        if (data != null) {
6531            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6532            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6533                    targetUid);
6534            if (targetUid > 0) {
6535                if (needed == null) {
6536                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6537                }
6538                needed.add(grantUri);
6539            }
6540        }
6541        if (clip != null) {
6542            for (int i=0; i<clip.getItemCount(); i++) {
6543                Uri uri = clip.getItemAt(i).getUri();
6544                if (uri != null) {
6545                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6546                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6547                            targetUid);
6548                    if (targetUid > 0) {
6549                        if (needed == null) {
6550                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6551                        }
6552                        needed.add(grantUri);
6553                    }
6554                } else {
6555                    Intent clipIntent = clip.getItemAt(i).getIntent();
6556                    if (clipIntent != null) {
6557                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6558                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6559                        if (newNeeded != null) {
6560                            needed = newNeeded;
6561                        }
6562                    }
6563                }
6564            }
6565        }
6566
6567        return needed;
6568    }
6569
6570    /**
6571     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6572     */
6573    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6574            UriPermissionOwner owner) {
6575        if (needed != null) {
6576            for (int i=0; i<needed.size(); i++) {
6577                GrantUri grantUri = needed.get(i);
6578                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6579                        grantUri, needed.flags, owner);
6580            }
6581        }
6582    }
6583
6584    void grantUriPermissionFromIntentLocked(int callingUid,
6585            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6586        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6587                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6588        if (needed == null) {
6589            return;
6590        }
6591
6592        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6593    }
6594
6595    @Override
6596    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6597            final int modeFlags, int userId) {
6598        enforceNotIsolatedCaller("grantUriPermission");
6599        GrantUri grantUri = new GrantUri(userId, uri, false);
6600        synchronized(this) {
6601            final ProcessRecord r = getRecordForAppLocked(caller);
6602            if (r == null) {
6603                throw new SecurityException("Unable to find app for caller "
6604                        + caller
6605                        + " when granting permission to uri " + grantUri);
6606            }
6607            if (targetPkg == null) {
6608                throw new IllegalArgumentException("null target");
6609            }
6610            if (grantUri == null) {
6611                throw new IllegalArgumentException("null uri");
6612            }
6613
6614            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6615                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6616                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6617                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6618
6619            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null);
6620        }
6621    }
6622
6623    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6624        if (perm.modeFlags == 0) {
6625            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6626                    perm.targetUid);
6627            if (perms != null) {
6628                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6629                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6630
6631                perms.remove(perm.uri);
6632                if (perms.isEmpty()) {
6633                    mGrantedUriPermissions.remove(perm.targetUid);
6634                }
6635            }
6636        }
6637    }
6638
6639    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6640        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6641
6642        final IPackageManager pm = AppGlobals.getPackageManager();
6643        final String authority = grantUri.uri.getAuthority();
6644        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6645        if (pi == null) {
6646            Slog.w(TAG, "No content provider found for permission revoke: "
6647                    + grantUri.toSafeString());
6648            return;
6649        }
6650
6651        // Does the caller have this permission on the URI?
6652        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6653            // Right now, if you are not the original owner of the permission,
6654            // you are not allowed to revoke it.
6655            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6656                throw new SecurityException("Uid " + callingUid
6657                        + " does not have permission to uri " + grantUri);
6658            //}
6659        }
6660
6661        boolean persistChanged = false;
6662
6663        // Go through all of the permissions and remove any that match.
6664        int N = mGrantedUriPermissions.size();
6665        for (int i = 0; i < N; i++) {
6666            final int targetUid = mGrantedUriPermissions.keyAt(i);
6667            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6668
6669            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6670                final UriPermission perm = it.next();
6671                if (perm.uri.sourceUserId == grantUri.sourceUserId
6672                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6673                    if (DEBUG_URI_PERMISSION)
6674                        Slog.v(TAG,
6675                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6676                    persistChanged |= perm.revokeModes(
6677                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6678                    if (perm.modeFlags == 0) {
6679                        it.remove();
6680                    }
6681                }
6682            }
6683
6684            if (perms.isEmpty()) {
6685                mGrantedUriPermissions.remove(targetUid);
6686                N--;
6687                i--;
6688            }
6689        }
6690
6691        if (persistChanged) {
6692            schedulePersistUriGrants();
6693        }
6694    }
6695
6696    @Override
6697    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6698            int userId) {
6699        enforceNotIsolatedCaller("revokeUriPermission");
6700        synchronized(this) {
6701            final ProcessRecord r = getRecordForAppLocked(caller);
6702            if (r == null) {
6703                throw new SecurityException("Unable to find app for caller "
6704                        + caller
6705                        + " when revoking permission to uri " + uri);
6706            }
6707            if (uri == null) {
6708                Slog.w(TAG, "revokeUriPermission: null uri");
6709                return;
6710            }
6711
6712            if (!Intent.isAccessUriMode(modeFlags)) {
6713                return;
6714            }
6715
6716            final IPackageManager pm = AppGlobals.getPackageManager();
6717            final String authority = uri.getAuthority();
6718            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6719            if (pi == null) {
6720                Slog.w(TAG, "No content provider found for permission revoke: "
6721                        + uri.toSafeString());
6722                return;
6723            }
6724
6725            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6726        }
6727    }
6728
6729    /**
6730     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6731     * given package.
6732     *
6733     * @param packageName Package name to match, or {@code null} to apply to all
6734     *            packages.
6735     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6736     *            to all users.
6737     * @param persistable If persistable grants should be removed.
6738     */
6739    private void removeUriPermissionsForPackageLocked(
6740            String packageName, int userHandle, boolean persistable) {
6741        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6742            throw new IllegalArgumentException("Must narrow by either package or user");
6743        }
6744
6745        boolean persistChanged = false;
6746
6747        int N = mGrantedUriPermissions.size();
6748        for (int i = 0; i < N; i++) {
6749            final int targetUid = mGrantedUriPermissions.keyAt(i);
6750            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6751
6752            // Only inspect grants matching user
6753            if (userHandle == UserHandle.USER_ALL
6754                    || userHandle == UserHandle.getUserId(targetUid)) {
6755                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6756                    final UriPermission perm = it.next();
6757
6758                    // Only inspect grants matching package
6759                    if (packageName == null || perm.sourcePkg.equals(packageName)
6760                            || perm.targetPkg.equals(packageName)) {
6761                        persistChanged |= perm.revokeModes(
6762                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6763
6764                        // Only remove when no modes remain; any persisted grants
6765                        // will keep this alive.
6766                        if (perm.modeFlags == 0) {
6767                            it.remove();
6768                        }
6769                    }
6770                }
6771
6772                if (perms.isEmpty()) {
6773                    mGrantedUriPermissions.remove(targetUid);
6774                    N--;
6775                    i--;
6776                }
6777            }
6778        }
6779
6780        if (persistChanged) {
6781            schedulePersistUriGrants();
6782        }
6783    }
6784
6785    @Override
6786    public IBinder newUriPermissionOwner(String name) {
6787        enforceNotIsolatedCaller("newUriPermissionOwner");
6788        synchronized(this) {
6789            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6790            return owner.getExternalTokenLocked();
6791        }
6792    }
6793
6794    @Override
6795    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6796            final int modeFlags, int userId) {
6797        synchronized(this) {
6798            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6799            if (owner == null) {
6800                throw new IllegalArgumentException("Unknown owner: " + token);
6801            }
6802            if (fromUid != Binder.getCallingUid()) {
6803                if (Binder.getCallingUid() != Process.myUid()) {
6804                    // Only system code can grant URI permissions on behalf
6805                    // of other users.
6806                    throw new SecurityException("nice try");
6807                }
6808            }
6809            if (targetPkg == null) {
6810                throw new IllegalArgumentException("null target");
6811            }
6812            if (uri == null) {
6813                throw new IllegalArgumentException("null uri");
6814            }
6815
6816            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false),
6817                    modeFlags, owner);
6818        }
6819    }
6820
6821    @Override
6822    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6823        synchronized(this) {
6824            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6825            if (owner == null) {
6826                throw new IllegalArgumentException("Unknown owner: " + token);
6827            }
6828
6829            if (uri == null) {
6830                owner.removeUriPermissionsLocked(mode);
6831            } else {
6832                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6833            }
6834        }
6835    }
6836
6837    private void schedulePersistUriGrants() {
6838        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6839            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6840                    10 * DateUtils.SECOND_IN_MILLIS);
6841        }
6842    }
6843
6844    private void writeGrantedUriPermissions() {
6845        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6846
6847        // Snapshot permissions so we can persist without lock
6848        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6849        synchronized (this) {
6850            final int size = mGrantedUriPermissions.size();
6851            for (int i = 0; i < size; i++) {
6852                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6853                for (UriPermission perm : perms.values()) {
6854                    if (perm.persistedModeFlags != 0) {
6855                        persist.add(perm.snapshot());
6856                    }
6857                }
6858            }
6859        }
6860
6861        FileOutputStream fos = null;
6862        try {
6863            fos = mGrantFile.startWrite();
6864
6865            XmlSerializer out = new FastXmlSerializer();
6866            out.setOutput(fos, "utf-8");
6867            out.startDocument(null, true);
6868            out.startTag(null, TAG_URI_GRANTS);
6869            for (UriPermission.Snapshot perm : persist) {
6870                out.startTag(null, TAG_URI_GRANT);
6871                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6872                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6873                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6874                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6875                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6876                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6877                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6878                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6879                out.endTag(null, TAG_URI_GRANT);
6880            }
6881            out.endTag(null, TAG_URI_GRANTS);
6882            out.endDocument();
6883
6884            mGrantFile.finishWrite(fos);
6885        } catch (IOException e) {
6886            if (fos != null) {
6887                mGrantFile.failWrite(fos);
6888            }
6889        }
6890    }
6891
6892    private void readGrantedUriPermissionsLocked() {
6893        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6894
6895        final long now = System.currentTimeMillis();
6896
6897        FileInputStream fis = null;
6898        try {
6899            fis = mGrantFile.openRead();
6900            final XmlPullParser in = Xml.newPullParser();
6901            in.setInput(fis, null);
6902
6903            int type;
6904            while ((type = in.next()) != END_DOCUMENT) {
6905                final String tag = in.getName();
6906                if (type == START_TAG) {
6907                    if (TAG_URI_GRANT.equals(tag)) {
6908                        final int sourceUserId;
6909                        final int targetUserId;
6910                        final int userHandle = readIntAttribute(in,
6911                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
6912                        if (userHandle != UserHandle.USER_NULL) {
6913                            // For backwards compatibility.
6914                            sourceUserId = userHandle;
6915                            targetUserId = userHandle;
6916                        } else {
6917                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
6918                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
6919                        }
6920                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6921                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6922                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6923                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6924                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6925                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6926
6927                        // Sanity check that provider still belongs to source package
6928                        final ProviderInfo pi = getProviderInfoLocked(
6929                                uri.getAuthority(), sourceUserId);
6930                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6931                            int targetUid = -1;
6932                            try {
6933                                targetUid = AppGlobals.getPackageManager()
6934                                        .getPackageUid(targetPkg, targetUserId);
6935                            } catch (RemoteException e) {
6936                            }
6937                            if (targetUid != -1) {
6938                                final UriPermission perm = findOrCreateUriPermissionLocked(
6939                                        sourcePkg, targetPkg, targetUid,
6940                                        new GrantUri(sourceUserId, uri, prefix));
6941                                perm.initPersistedModes(modeFlags, createdTime);
6942                            }
6943                        } else {
6944                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6945                                    + " but instead found " + pi);
6946                        }
6947                    }
6948                }
6949            }
6950        } catch (FileNotFoundException e) {
6951            // Missing grants is okay
6952        } catch (IOException e) {
6953            Log.wtf(TAG, "Failed reading Uri grants", e);
6954        } catch (XmlPullParserException e) {
6955            Log.wtf(TAG, "Failed reading Uri grants", e);
6956        } finally {
6957            IoUtils.closeQuietly(fis);
6958        }
6959    }
6960
6961    @Override
6962    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6963        enforceNotIsolatedCaller("takePersistableUriPermission");
6964
6965        Preconditions.checkFlagsArgument(modeFlags,
6966                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6967
6968        synchronized (this) {
6969            final int callingUid = Binder.getCallingUid();
6970            boolean persistChanged = false;
6971            GrantUri grantUri = new GrantUri(userId, uri, false);
6972
6973            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6974                    new GrantUri(userId, uri, false));
6975            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6976                    new GrantUri(userId, uri, true));
6977
6978            final boolean exactValid = (exactPerm != null)
6979                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
6980            final boolean prefixValid = (prefixPerm != null)
6981                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
6982
6983            if (!(exactValid || prefixValid)) {
6984                throw new SecurityException("No persistable permission grants found for UID "
6985                        + callingUid + " and Uri " + grantUri.toSafeString());
6986            }
6987
6988            if (exactValid) {
6989                persistChanged |= exactPerm.takePersistableModes(modeFlags);
6990            }
6991            if (prefixValid) {
6992                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
6993            }
6994
6995            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6996
6997            if (persistChanged) {
6998                schedulePersistUriGrants();
6999            }
7000        }
7001    }
7002
7003    @Override
7004    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7005        enforceNotIsolatedCaller("releasePersistableUriPermission");
7006
7007        Preconditions.checkFlagsArgument(modeFlags,
7008                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7009
7010        synchronized (this) {
7011            final int callingUid = Binder.getCallingUid();
7012            boolean persistChanged = false;
7013
7014            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7015                    new GrantUri(userId, uri, false));
7016            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7017                    new GrantUri(userId, uri, true));
7018            if (exactPerm == null && prefixPerm == null) {
7019                throw new SecurityException("No permission grants found for UID " + callingUid
7020                        + " and Uri " + uri.toSafeString());
7021            }
7022
7023            if (exactPerm != null) {
7024                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7025                removeUriPermissionIfNeededLocked(exactPerm);
7026            }
7027            if (prefixPerm != null) {
7028                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7029                removeUriPermissionIfNeededLocked(prefixPerm);
7030            }
7031
7032            if (persistChanged) {
7033                schedulePersistUriGrants();
7034            }
7035        }
7036    }
7037
7038    /**
7039     * Prune any older {@link UriPermission} for the given UID until outstanding
7040     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7041     *
7042     * @return if any mutations occured that require persisting.
7043     */
7044    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7045        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7046        if (perms == null) return false;
7047        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7048
7049        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7050        for (UriPermission perm : perms.values()) {
7051            if (perm.persistedModeFlags != 0) {
7052                persisted.add(perm);
7053            }
7054        }
7055
7056        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7057        if (trimCount <= 0) return false;
7058
7059        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7060        for (int i = 0; i < trimCount; i++) {
7061            final UriPermission perm = persisted.get(i);
7062
7063            if (DEBUG_URI_PERMISSION) {
7064                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7065            }
7066
7067            perm.releasePersistableModes(~0);
7068            removeUriPermissionIfNeededLocked(perm);
7069        }
7070
7071        return true;
7072    }
7073
7074    @Override
7075    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7076            String packageName, boolean incoming) {
7077        enforceNotIsolatedCaller("getPersistedUriPermissions");
7078        Preconditions.checkNotNull(packageName, "packageName");
7079
7080        final int callingUid = Binder.getCallingUid();
7081        final IPackageManager pm = AppGlobals.getPackageManager();
7082        try {
7083            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7084            if (packageUid != callingUid) {
7085                throw new SecurityException(
7086                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7087            }
7088        } catch (RemoteException e) {
7089            throw new SecurityException("Failed to verify package name ownership");
7090        }
7091
7092        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7093        synchronized (this) {
7094            if (incoming) {
7095                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7096                        callingUid);
7097                if (perms == null) {
7098                    Slog.w(TAG, "No permission grants found for " + packageName);
7099                } else {
7100                    for (UriPermission perm : perms.values()) {
7101                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7102                            result.add(perm.buildPersistedPublicApiObject());
7103                        }
7104                    }
7105                }
7106            } else {
7107                final int size = mGrantedUriPermissions.size();
7108                for (int i = 0; i < size; i++) {
7109                    final ArrayMap<GrantUri, UriPermission> perms =
7110                            mGrantedUriPermissions.valueAt(i);
7111                    for (UriPermission perm : perms.values()) {
7112                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7113                            result.add(perm.buildPersistedPublicApiObject());
7114                        }
7115                    }
7116                }
7117            }
7118        }
7119        return new ParceledListSlice<android.content.UriPermission>(result);
7120    }
7121
7122    @Override
7123    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7124        synchronized (this) {
7125            ProcessRecord app =
7126                who != null ? getRecordForAppLocked(who) : null;
7127            if (app == null) return;
7128
7129            Message msg = Message.obtain();
7130            msg.what = WAIT_FOR_DEBUGGER_MSG;
7131            msg.obj = app;
7132            msg.arg1 = waiting ? 1 : 0;
7133            mHandler.sendMessage(msg);
7134        }
7135    }
7136
7137    @Override
7138    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7139        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7140        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7141        outInfo.availMem = Process.getFreeMemory();
7142        outInfo.totalMem = Process.getTotalMemory();
7143        outInfo.threshold = homeAppMem;
7144        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7145        outInfo.hiddenAppThreshold = cachedAppMem;
7146        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7147                ProcessList.SERVICE_ADJ);
7148        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7149                ProcessList.VISIBLE_APP_ADJ);
7150        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7151                ProcessList.FOREGROUND_APP_ADJ);
7152    }
7153
7154    // =========================================================
7155    // TASK MANAGEMENT
7156    // =========================================================
7157
7158    @Override
7159    public List<IAppTask> getAppTasks() {
7160        final PackageManager pm = mContext.getPackageManager();
7161        int callingUid = Binder.getCallingUid();
7162        long ident = Binder.clearCallingIdentity();
7163
7164        // Compose the list of packages for this id to test against
7165        HashSet<String> packages = new HashSet<String>();
7166        String[] uidPackages = pm.getPackagesForUid(callingUid);
7167        for (int i = 0; i < uidPackages.length; i++) {
7168            packages.add(uidPackages[i]);
7169        }
7170
7171        synchronized(this) {
7172            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7173            try {
7174                if (localLOGV) Slog.v(TAG, "getAppTasks");
7175
7176                final int N = mRecentTasks.size();
7177                for (int i = 0; i < N; i++) {
7178                    TaskRecord tr = mRecentTasks.get(i);
7179                    // Skip tasks that are not created by the caller
7180                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
7181                        ActivityManager.RecentTaskInfo taskInfo =
7182                                createRecentTaskInfoFromTaskRecord(tr);
7183                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7184                        list.add(taskImpl);
7185                    }
7186                }
7187            } finally {
7188                Binder.restoreCallingIdentity(ident);
7189            }
7190            return list;
7191        }
7192    }
7193
7194    @Override
7195    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7196        final int callingUid = Binder.getCallingUid();
7197        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7198
7199        synchronized(this) {
7200            if (localLOGV) Slog.v(
7201                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7202
7203            final boolean allowed = checkCallingPermission(
7204                    android.Manifest.permission.GET_TASKS)
7205                    == PackageManager.PERMISSION_GRANTED;
7206            if (!allowed) {
7207                Slog.w(TAG, "getTasks: caller " + callingUid
7208                        + " does not hold GET_TASKS; limiting output");
7209            }
7210
7211            // TODO: Improve with MRU list from all ActivityStacks.
7212            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7213        }
7214
7215        return list;
7216    }
7217
7218    TaskRecord getMostRecentTask() {
7219        return mRecentTasks.get(0);
7220    }
7221
7222    /**
7223     * Creates a new RecentTaskInfo from a TaskRecord.
7224     */
7225    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7226        // Update the task description to reflect any changes in the task stack
7227        tr.updateTaskDescription();
7228
7229        // Compose the recent task info
7230        ActivityManager.RecentTaskInfo rti
7231                = new ActivityManager.RecentTaskInfo();
7232        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7233        rti.persistentId = tr.taskId;
7234        rti.baseIntent = new Intent(tr.getBaseIntent());
7235        rti.origActivity = tr.origActivity;
7236        rti.description = tr.lastDescription;
7237        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7238        rti.userId = tr.userId;
7239        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7240        rti.lastActiveTime = tr.lastActiveTime;
7241        return rti;
7242    }
7243
7244    @Override
7245    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7246            int flags, int userId) {
7247        final int callingUid = Binder.getCallingUid();
7248        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7249                false, true, "getRecentTasks", null);
7250
7251        synchronized (this) {
7252            final boolean allowed = checkCallingPermission(
7253                    android.Manifest.permission.GET_TASKS)
7254                    == PackageManager.PERMISSION_GRANTED;
7255            if (!allowed) {
7256                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7257                        + " does not hold GET_TASKS; limiting output");
7258            }
7259            final boolean detailed = checkCallingPermission(
7260                    android.Manifest.permission.GET_DETAILED_TASKS)
7261                    == PackageManager.PERMISSION_GRANTED;
7262
7263            IPackageManager pm = AppGlobals.getPackageManager();
7264
7265            final int N = mRecentTasks.size();
7266            ArrayList<ActivityManager.RecentTaskInfo> res
7267                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7268                            maxNum < N ? maxNum : N);
7269
7270            final Set<Integer> includedUsers;
7271            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7272                includedUsers = getProfileIdsLocked(userId);
7273            } else {
7274                includedUsers = new HashSet<Integer>();
7275            }
7276            includedUsers.add(Integer.valueOf(userId));
7277            for (int i=0; i<N && maxNum > 0; i++) {
7278                TaskRecord tr = mRecentTasks.get(i);
7279                // Only add calling user or related users recent tasks
7280                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7281
7282                // Return the entry if desired by the caller.  We always return
7283                // the first entry, because callers always expect this to be the
7284                // foreground app.  We may filter others if the caller has
7285                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7286                // we should exclude the entry.
7287
7288                if (i == 0
7289                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7290                        || (tr.intent == null)
7291                        || ((tr.intent.getFlags()
7292                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7293                    if (!allowed) {
7294                        // If the caller doesn't have the GET_TASKS permission, then only
7295                        // allow them to see a small subset of tasks -- their own and home.
7296                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7297                            continue;
7298                        }
7299                    }
7300                    if (tr.intent != null &&
7301                            (tr.intent.getFlags() & Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS)
7302                            != 0 && tr.getTopActivity() == null) {
7303                        // Don't include auto remove tasks that are finished or finishing.
7304                        continue;
7305                    }
7306
7307                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7308                    if (!detailed) {
7309                        rti.baseIntent.replaceExtras((Bundle)null);
7310                    }
7311
7312                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7313                        // Check whether this activity is currently available.
7314                        try {
7315                            if (rti.origActivity != null) {
7316                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7317                                        == null) {
7318                                    continue;
7319                                }
7320                            } else if (rti.baseIntent != null) {
7321                                if (pm.queryIntentActivities(rti.baseIntent,
7322                                        null, 0, userId) == null) {
7323                                    continue;
7324                                }
7325                            }
7326                        } catch (RemoteException e) {
7327                            // Will never happen.
7328                        }
7329                    }
7330
7331                    res.add(rti);
7332                    maxNum--;
7333                }
7334            }
7335            return res;
7336        }
7337    }
7338
7339    private TaskRecord recentTaskForIdLocked(int id) {
7340        final int N = mRecentTasks.size();
7341            for (int i=0; i<N; i++) {
7342                TaskRecord tr = mRecentTasks.get(i);
7343                if (tr.taskId == id) {
7344                    return tr;
7345                }
7346            }
7347            return null;
7348    }
7349
7350    @Override
7351    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7352        synchronized (this) {
7353            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7354                    "getTaskThumbnails()");
7355            TaskRecord tr = recentTaskForIdLocked(id);
7356            if (tr != null) {
7357                return tr.getTaskThumbnailsLocked();
7358            }
7359        }
7360        return null;
7361    }
7362
7363    @Override
7364    public Bitmap getTaskTopThumbnail(int id) {
7365        synchronized (this) {
7366            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7367                    "getTaskTopThumbnail()");
7368            TaskRecord tr = recentTaskForIdLocked(id);
7369            if (tr != null) {
7370                return tr.getTaskTopThumbnailLocked();
7371            }
7372        }
7373        return null;
7374    }
7375
7376    @Override
7377    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7378        synchronized (this) {
7379            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7380            if (r != null) {
7381                r.taskDescription = td;
7382                r.task.updateTaskDescription();
7383            }
7384        }
7385    }
7386
7387    @Override
7388    public boolean removeSubTask(int taskId, int subTaskIndex) {
7389        synchronized (this) {
7390            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7391                    "removeSubTask()");
7392            long ident = Binder.clearCallingIdentity();
7393            try {
7394                TaskRecord tr = recentTaskForIdLocked(taskId);
7395                if (tr != null) {
7396                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7397                }
7398                return false;
7399            } finally {
7400                Binder.restoreCallingIdentity(ident);
7401            }
7402        }
7403    }
7404
7405    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7406        if (!pr.killedByAm) {
7407            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7408            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7409                    pr.processName, pr.setAdj, reason);
7410            pr.killedByAm = true;
7411            Process.killProcessQuiet(pr.pid);
7412        }
7413    }
7414
7415    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7416        tr.disposeThumbnail();
7417        mRecentTasks.remove(tr);
7418        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7419        Intent baseIntent = new Intent(
7420                tr.intent != null ? tr.intent : tr.affinityIntent);
7421        ComponentName component = baseIntent.getComponent();
7422        if (component == null) {
7423            Slog.w(TAG, "Now component for base intent of task: " + tr);
7424            return;
7425        }
7426
7427        // Find any running services associated with this app.
7428        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7429
7430        if (killProcesses) {
7431            // Find any running processes associated with this app.
7432            final String pkg = component.getPackageName();
7433            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7434            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7435            for (int i=0; i<pmap.size(); i++) {
7436                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7437                for (int j=0; j<uids.size(); j++) {
7438                    ProcessRecord proc = uids.valueAt(j);
7439                    if (proc.userId != tr.userId) {
7440                        continue;
7441                    }
7442                    if (!proc.pkgList.containsKey(pkg)) {
7443                        continue;
7444                    }
7445                    procs.add(proc);
7446                }
7447            }
7448
7449            // Kill the running processes.
7450            for (int i=0; i<procs.size(); i++) {
7451                ProcessRecord pr = procs.get(i);
7452                if (pr == mHomeProcess) {
7453                    // Don't kill the home process along with tasks from the same package.
7454                    continue;
7455                }
7456                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7457                    killUnneededProcessLocked(pr, "remove task");
7458                } else {
7459                    pr.waitingToKill = "remove task";
7460                }
7461            }
7462        }
7463    }
7464
7465    /**
7466     * Removes the task with the specified task id.
7467     *
7468     * @param taskId Identifier of the task to be removed.
7469     * @param flags Additional operational flags.  May be 0 or
7470     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7471     * @return Returns true if the given task was found and removed.
7472     */
7473    private boolean removeTaskByIdLocked(int taskId, int flags) {
7474        TaskRecord tr = recentTaskForIdLocked(taskId);
7475        if (tr != null) {
7476            tr.removeTaskActivitiesLocked(-1, false);
7477            cleanUpRemovedTaskLocked(tr, flags);
7478            if (tr.isPersistable) {
7479                notifyTaskPersisterLocked(tr, true);
7480            }
7481            return true;
7482        }
7483        return false;
7484    }
7485
7486    @Override
7487    public boolean removeTask(int taskId, int flags) {
7488        synchronized (this) {
7489            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7490                    "removeTask()");
7491            long ident = Binder.clearCallingIdentity();
7492            try {
7493                return removeTaskByIdLocked(taskId, flags);
7494            } finally {
7495                Binder.restoreCallingIdentity(ident);
7496            }
7497        }
7498    }
7499
7500    /**
7501     * TODO: Add mController hook
7502     */
7503    @Override
7504    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7505        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7506                "moveTaskToFront()");
7507
7508        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7509        synchronized(this) {
7510            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7511                    Binder.getCallingUid(), "Task to front")) {
7512                ActivityOptions.abort(options);
7513                return;
7514            }
7515            final long origId = Binder.clearCallingIdentity();
7516            try {
7517                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7518                if (task == null) {
7519                    return;
7520                }
7521                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7522                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7523                    return;
7524                }
7525                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7526                if (prev != null && prev.isRecentsActivity()) {
7527                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7528                }
7529                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7530            } finally {
7531                Binder.restoreCallingIdentity(origId);
7532            }
7533            ActivityOptions.abort(options);
7534        }
7535    }
7536
7537    @Override
7538    public void moveTaskToBack(int taskId) {
7539        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7540                "moveTaskToBack()");
7541
7542        synchronized(this) {
7543            TaskRecord tr = recentTaskForIdLocked(taskId);
7544            if (tr != null) {
7545                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7546                ActivityStack stack = tr.stack;
7547                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7548                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7549                            Binder.getCallingUid(), "Task to back")) {
7550                        return;
7551                    }
7552                }
7553                final long origId = Binder.clearCallingIdentity();
7554                try {
7555                    stack.moveTaskToBackLocked(taskId, null);
7556                } finally {
7557                    Binder.restoreCallingIdentity(origId);
7558                }
7559            }
7560        }
7561    }
7562
7563    /**
7564     * Moves an activity, and all of the other activities within the same task, to the bottom
7565     * of the history stack.  The activity's order within the task is unchanged.
7566     *
7567     * @param token A reference to the activity we wish to move
7568     * @param nonRoot If false then this only works if the activity is the root
7569     *                of a task; if true it will work for any activity in a task.
7570     * @return Returns true if the move completed, false if not.
7571     */
7572    @Override
7573    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7574        enforceNotIsolatedCaller("moveActivityTaskToBack");
7575        synchronized(this) {
7576            final long origId = Binder.clearCallingIdentity();
7577            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7578            if (taskId >= 0) {
7579                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7580            }
7581            Binder.restoreCallingIdentity(origId);
7582        }
7583        return false;
7584    }
7585
7586    @Override
7587    public void moveTaskBackwards(int task) {
7588        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7589                "moveTaskBackwards()");
7590
7591        synchronized(this) {
7592            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7593                    Binder.getCallingUid(), "Task backwards")) {
7594                return;
7595            }
7596            final long origId = Binder.clearCallingIdentity();
7597            moveTaskBackwardsLocked(task);
7598            Binder.restoreCallingIdentity(origId);
7599        }
7600    }
7601
7602    private final void moveTaskBackwardsLocked(int task) {
7603        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7604    }
7605
7606    @Override
7607    public IBinder getHomeActivityToken() throws RemoteException {
7608        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7609                "getHomeActivityToken()");
7610        synchronized (this) {
7611            return mStackSupervisor.getHomeActivityToken();
7612        }
7613    }
7614
7615    @Override
7616    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7617            IActivityContainerCallback callback) throws RemoteException {
7618        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7619                "createActivityContainer()");
7620        synchronized (this) {
7621            if (parentActivityToken == null) {
7622                throw new IllegalArgumentException("parent token must not be null");
7623            }
7624            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7625            if (r == null) {
7626                return null;
7627            }
7628            if (callback == null) {
7629                throw new IllegalArgumentException("callback must not be null");
7630            }
7631            return mStackSupervisor.createActivityContainer(r, callback);
7632        }
7633    }
7634
7635    @Override
7636    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7637        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7638                "deleteActivityContainer()");
7639        synchronized (this) {
7640            mStackSupervisor.deleteActivityContainer(container);
7641        }
7642    }
7643
7644    @Override
7645    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7646            throws RemoteException {
7647        synchronized (this) {
7648            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7649            if (stack != null) {
7650                return stack.mActivityContainer;
7651            }
7652            return null;
7653        }
7654    }
7655
7656    @Override
7657    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7658        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7659                "moveTaskToStack()");
7660        if (stackId == HOME_STACK_ID) {
7661            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7662                    new RuntimeException("here").fillInStackTrace());
7663        }
7664        synchronized (this) {
7665            long ident = Binder.clearCallingIdentity();
7666            try {
7667                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7668                        + stackId + " toTop=" + toTop);
7669                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7670            } finally {
7671                Binder.restoreCallingIdentity(ident);
7672            }
7673        }
7674    }
7675
7676    @Override
7677    public void resizeStack(int stackBoxId, Rect bounds) {
7678        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7679                "resizeStackBox()");
7680        long ident = Binder.clearCallingIdentity();
7681        try {
7682            mWindowManager.resizeStack(stackBoxId, bounds);
7683        } finally {
7684            Binder.restoreCallingIdentity(ident);
7685        }
7686    }
7687
7688    @Override
7689    public List<StackInfo> getAllStackInfos() {
7690        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7691                "getAllStackInfos()");
7692        long ident = Binder.clearCallingIdentity();
7693        try {
7694            synchronized (this) {
7695                return mStackSupervisor.getAllStackInfosLocked();
7696            }
7697        } finally {
7698            Binder.restoreCallingIdentity(ident);
7699        }
7700    }
7701
7702    @Override
7703    public StackInfo getStackInfo(int stackId) {
7704        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7705                "getStackInfo()");
7706        long ident = Binder.clearCallingIdentity();
7707        try {
7708            synchronized (this) {
7709                return mStackSupervisor.getStackInfoLocked(stackId);
7710            }
7711        } finally {
7712            Binder.restoreCallingIdentity(ident);
7713        }
7714    }
7715
7716    @Override
7717    public boolean isInHomeStack(int taskId) {
7718        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7719                "getStackInfo()");
7720        long ident = Binder.clearCallingIdentity();
7721        try {
7722            synchronized (this) {
7723                TaskRecord tr = recentTaskForIdLocked(taskId);
7724                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7725            }
7726        } finally {
7727            Binder.restoreCallingIdentity(ident);
7728        }
7729    }
7730
7731    @Override
7732    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7733        synchronized(this) {
7734            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7735        }
7736    }
7737
7738    private boolean isLockTaskAuthorized(String pkg) {
7739        final DevicePolicyManager dpm = (DevicePolicyManager)
7740                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7741        try {
7742            int uid = mContext.getPackageManager().getPackageUid(pkg,
7743                    Binder.getCallingUserHandle().getIdentifier());
7744            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7745        } catch (NameNotFoundException e) {
7746            return false;
7747        }
7748    }
7749
7750    void startLockTaskMode(TaskRecord task) {
7751        final String pkg;
7752        synchronized (this) {
7753            pkg = task.intent.getComponent().getPackageName();
7754        }
7755        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
7756        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
7757            final TaskRecord taskRecord = task;
7758            mHandler.post(new Runnable() {
7759                @Override
7760                public void run() {
7761                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
7762                }
7763            });
7764            return;
7765        }
7766        long ident = Binder.clearCallingIdentity();
7767        try {
7768            synchronized (this) {
7769                // Since we lost lock on task, make sure it is still there.
7770                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7771                if (task != null) {
7772                    if (!isSystemInitiated
7773                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
7774                        throw new IllegalArgumentException("Invalid task, not in foreground");
7775                    }
7776                    mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated);
7777                }
7778            }
7779        } finally {
7780            Binder.restoreCallingIdentity(ident);
7781        }
7782    }
7783
7784    @Override
7785    public void startLockTaskMode(int taskId) {
7786        final TaskRecord task;
7787        long ident = Binder.clearCallingIdentity();
7788        try {
7789            synchronized (this) {
7790                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7791            }
7792        } finally {
7793            Binder.restoreCallingIdentity(ident);
7794        }
7795        if (task != null) {
7796            startLockTaskMode(task);
7797        }
7798    }
7799
7800    @Override
7801    public void startLockTaskMode(IBinder token) {
7802        final TaskRecord task;
7803        long ident = Binder.clearCallingIdentity();
7804        try {
7805            synchronized (this) {
7806                final ActivityRecord r = ActivityRecord.forToken(token);
7807                if (r == null) {
7808                    return;
7809                }
7810                task = r.task;
7811            }
7812        } finally {
7813            Binder.restoreCallingIdentity(ident);
7814        }
7815        if (task != null) {
7816            startLockTaskMode(task);
7817        }
7818    }
7819
7820    @Override
7821    public void startLockTaskModeOnCurrent() throws RemoteException {
7822        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7823        ActivityRecord r = null;
7824        synchronized (this) {
7825            r = mStackSupervisor.topRunningActivityLocked();
7826        }
7827        startLockTaskMode(r.task);
7828    }
7829
7830    @Override
7831    public void stopLockTaskMode() {
7832        // Verify that the user matches the package of the intent for the TaskRecord
7833        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
7834        // and stopLockTaskMode.
7835        final int callingUid = Binder.getCallingUid();
7836        if (callingUid != Process.SYSTEM_UID) {
7837            try {
7838                String pkg =
7839                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
7840                int uid = mContext.getPackageManager().getPackageUid(pkg,
7841                        Binder.getCallingUserHandle().getIdentifier());
7842                if (uid != callingUid) {
7843                    throw new SecurityException("Invalid uid, expected " + uid);
7844                }
7845            } catch (NameNotFoundException e) {
7846                Log.d(TAG, "stopLockTaskMode " + e);
7847                return;
7848            }
7849        }
7850        long ident = Binder.clearCallingIdentity();
7851        try {
7852            Log.d(TAG, "stopLockTaskMode");
7853            // Stop lock task
7854            synchronized (this) {
7855                mStackSupervisor.setLockTaskModeLocked(null, false);
7856            }
7857        } finally {
7858            Binder.restoreCallingIdentity(ident);
7859        }
7860    }
7861
7862    @Override
7863    public void stopLockTaskModeOnCurrent() throws RemoteException {
7864        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7865        long ident = Binder.clearCallingIdentity();
7866        try {
7867            stopLockTaskMode();
7868        } finally {
7869            Binder.restoreCallingIdentity(ident);
7870        }
7871    }
7872
7873    @Override
7874    public boolean isInLockTaskMode() {
7875        synchronized (this) {
7876            return mStackSupervisor.isInLockTaskMode();
7877        }
7878    }
7879
7880    // =========================================================
7881    // CONTENT PROVIDERS
7882    // =========================================================
7883
7884    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7885        List<ProviderInfo> providers = null;
7886        try {
7887            providers = AppGlobals.getPackageManager().
7888                queryContentProviders(app.processName, app.uid,
7889                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7890        } catch (RemoteException ex) {
7891        }
7892        if (DEBUG_MU)
7893            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7894        int userId = app.userId;
7895        if (providers != null) {
7896            int N = providers.size();
7897            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7898            for (int i=0; i<N; i++) {
7899                ProviderInfo cpi =
7900                    (ProviderInfo)providers.get(i);
7901                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7902                        cpi.name, cpi.flags);
7903                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7904                    // This is a singleton provider, but a user besides the
7905                    // default user is asking to initialize a process it runs
7906                    // in...  well, no, it doesn't actually run in this process,
7907                    // it runs in the process of the default user.  Get rid of it.
7908                    providers.remove(i);
7909                    N--;
7910                    i--;
7911                    continue;
7912                }
7913
7914                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7915                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7916                if (cpr == null) {
7917                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7918                    mProviderMap.putProviderByClass(comp, cpr);
7919                }
7920                if (DEBUG_MU)
7921                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7922                app.pubProviders.put(cpi.name, cpr);
7923                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7924                    // Don't add this if it is a platform component that is marked
7925                    // to run in multiple processes, because this is actually
7926                    // part of the framework so doesn't make sense to track as a
7927                    // separate apk in the process.
7928                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
7929                            mProcessStats);
7930                }
7931                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7932            }
7933        }
7934        return providers;
7935    }
7936
7937    /**
7938     * Check if {@link ProcessRecord} has a possible chance at accessing the
7939     * given {@link ProviderInfo}. Final permission checking is always done
7940     * in {@link ContentProvider}.
7941     */
7942    private final String checkContentProviderPermissionLocked(
7943            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
7944        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7945        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7946        boolean checkedGrants = false;
7947        if (checkUser) {
7948            // Looking for cross-user grants before enforcing the typical cross-users permissions
7949            if (UserHandle.getUserId(callingUid) != userId) {
7950                if (checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
7951                    return null;
7952                }
7953                checkedGrants = true;
7954            }
7955            userId = handleIncomingUser(callingPid, callingUid, userId,
7956                    false, true, "checkContentProviderPermissionLocked " + cpi.authority, null);
7957        }
7958        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7959                cpi.applicationInfo.uid, cpi.exported)
7960                == PackageManager.PERMISSION_GRANTED) {
7961            return null;
7962        }
7963        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7964                cpi.applicationInfo.uid, cpi.exported)
7965                == PackageManager.PERMISSION_GRANTED) {
7966            return null;
7967        }
7968
7969        PathPermission[] pps = cpi.pathPermissions;
7970        if (pps != null) {
7971            int i = pps.length;
7972            while (i > 0) {
7973                i--;
7974                PathPermission pp = pps[i];
7975                String pprperm = pp.getReadPermission();
7976                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
7977                        cpi.applicationInfo.uid, cpi.exported)
7978                        == PackageManager.PERMISSION_GRANTED) {
7979                    return null;
7980                }
7981                String ppwperm = pp.getWritePermission();
7982                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
7983                        cpi.applicationInfo.uid, cpi.exported)
7984                        == PackageManager.PERMISSION_GRANTED) {
7985                    return null;
7986                }
7987            }
7988        }
7989        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
7990            return null;
7991        }
7992
7993        String msg;
7994        if (!cpi.exported) {
7995            msg = "Permission Denial: opening provider " + cpi.name
7996                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7997                    + ", uid=" + callingUid + ") that is not exported from uid "
7998                    + cpi.applicationInfo.uid;
7999        } else {
8000            msg = "Permission Denial: opening provider " + cpi.name
8001                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8002                    + ", uid=" + callingUid + ") requires "
8003                    + cpi.readPermission + " or " + cpi.writePermission;
8004        }
8005        Slog.w(TAG, msg);
8006        return msg;
8007    }
8008
8009    /**
8010     * Returns if the ContentProvider has granted a uri to callingUid
8011     */
8012    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8013        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8014        if (perms != null) {
8015            for (GrantUri grantUri : perms.keySet()) {
8016                if (grantUri.sourceUserId == userId || !checkUser) {
8017                    if (matchesProvider(grantUri.uri, cpi)) {
8018                        return true;
8019                    }
8020                }
8021            }
8022        }
8023        return false;
8024    }
8025
8026    /**
8027     * Returns true if the uri authority is one of the authorities specified in the provider.
8028     */
8029    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8030        String uriAuth = uri.getAuthority();
8031        String cpiAuth = cpi.authority;
8032        if (cpiAuth.indexOf(';') == -1) {
8033            return cpiAuth.equals(uriAuth);
8034        }
8035        String[] cpiAuths = cpiAuth.split(";");
8036        int length = cpiAuths.length;
8037        for (int i = 0; i < length; i++) {
8038            if (cpiAuths[i].equals(uriAuth)) return true;
8039        }
8040        return false;
8041    }
8042
8043    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8044            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8045        if (r != null) {
8046            for (int i=0; i<r.conProviders.size(); i++) {
8047                ContentProviderConnection conn = r.conProviders.get(i);
8048                if (conn.provider == cpr) {
8049                    if (DEBUG_PROVIDER) Slog.v(TAG,
8050                            "Adding provider requested by "
8051                            + r.processName + " from process "
8052                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8053                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8054                    if (stable) {
8055                        conn.stableCount++;
8056                        conn.numStableIncs++;
8057                    } else {
8058                        conn.unstableCount++;
8059                        conn.numUnstableIncs++;
8060                    }
8061                    return conn;
8062                }
8063            }
8064            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8065            if (stable) {
8066                conn.stableCount = 1;
8067                conn.numStableIncs = 1;
8068            } else {
8069                conn.unstableCount = 1;
8070                conn.numUnstableIncs = 1;
8071            }
8072            cpr.connections.add(conn);
8073            r.conProviders.add(conn);
8074            return conn;
8075        }
8076        cpr.addExternalProcessHandleLocked(externalProcessToken);
8077        return null;
8078    }
8079
8080    boolean decProviderCountLocked(ContentProviderConnection conn,
8081            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8082        if (conn != null) {
8083            cpr = conn.provider;
8084            if (DEBUG_PROVIDER) Slog.v(TAG,
8085                    "Removing provider requested by "
8086                    + conn.client.processName + " from process "
8087                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8088                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8089            if (stable) {
8090                conn.stableCount--;
8091            } else {
8092                conn.unstableCount--;
8093            }
8094            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8095                cpr.connections.remove(conn);
8096                conn.client.conProviders.remove(conn);
8097                return true;
8098            }
8099            return false;
8100        }
8101        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8102        return false;
8103    }
8104
8105    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8106            String name, IBinder token, boolean stable, int userId) {
8107        ContentProviderRecord cpr;
8108        ContentProviderConnection conn = null;
8109        ProviderInfo cpi = null;
8110
8111        synchronized(this) {
8112            ProcessRecord r = null;
8113            if (caller != null) {
8114                r = getRecordForAppLocked(caller);
8115                if (r == null) {
8116                    throw new SecurityException(
8117                            "Unable to find app for caller " + caller
8118                          + " (pid=" + Binder.getCallingPid()
8119                          + ") when getting content provider " + name);
8120                }
8121            }
8122
8123            boolean checkCrossUser = true;
8124
8125            // First check if this content provider has been published...
8126            cpr = mProviderMap.getProviderByName(name, userId);
8127            // If that didn't work, check if it exists for user 0 and then
8128            // verify that it's a singleton provider before using it.
8129            if (cpr == null && userId != UserHandle.USER_OWNER) {
8130                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8131                if (cpr != null) {
8132                    cpi = cpr.info;
8133                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8134                            cpi.name, cpi.flags)
8135                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8136                        userId = UserHandle.USER_OWNER;
8137                        checkCrossUser = false;
8138                    } else {
8139                        cpr = null;
8140                        cpi = null;
8141                    }
8142                }
8143            }
8144
8145            boolean providerRunning = cpr != null;
8146            if (providerRunning) {
8147                cpi = cpr.info;
8148                String msg;
8149                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8150                        != null) {
8151                    throw new SecurityException(msg);
8152                }
8153
8154                if (r != null && cpr.canRunHere(r)) {
8155                    // This provider has been published or is in the process
8156                    // of being published...  but it is also allowed to run
8157                    // in the caller's process, so don't make a connection
8158                    // and just let the caller instantiate its own instance.
8159                    ContentProviderHolder holder = cpr.newHolder(null);
8160                    // don't give caller the provider object, it needs
8161                    // to make its own.
8162                    holder.provider = null;
8163                    return holder;
8164                }
8165
8166                final long origId = Binder.clearCallingIdentity();
8167
8168                // In this case the provider instance already exists, so we can
8169                // return it right away.
8170                conn = incProviderCountLocked(r, cpr, token, stable);
8171                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8172                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8173                        // If this is a perceptible app accessing the provider,
8174                        // make sure to count it as being accessed and thus
8175                        // back up on the LRU list.  This is good because
8176                        // content providers are often expensive to start.
8177                        updateLruProcessLocked(cpr.proc, false, null);
8178                    }
8179                }
8180
8181                if (cpr.proc != null) {
8182                    if (false) {
8183                        if (cpr.name.flattenToShortString().equals(
8184                                "com.android.providers.calendar/.CalendarProvider2")) {
8185                            Slog.v(TAG, "****************** KILLING "
8186                                + cpr.name.flattenToShortString());
8187                            Process.killProcess(cpr.proc.pid);
8188                        }
8189                    }
8190                    boolean success = updateOomAdjLocked(cpr.proc);
8191                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8192                    // NOTE: there is still a race here where a signal could be
8193                    // pending on the process even though we managed to update its
8194                    // adj level.  Not sure what to do about this, but at least
8195                    // the race is now smaller.
8196                    if (!success) {
8197                        // Uh oh...  it looks like the provider's process
8198                        // has been killed on us.  We need to wait for a new
8199                        // process to be started, and make sure its death
8200                        // doesn't kill our process.
8201                        Slog.i(TAG,
8202                                "Existing provider " + cpr.name.flattenToShortString()
8203                                + " is crashing; detaching " + r);
8204                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8205                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8206                        if (!lastRef) {
8207                            // This wasn't the last ref our process had on
8208                            // the provider...  we have now been killed, bail.
8209                            return null;
8210                        }
8211                        providerRunning = false;
8212                        conn = null;
8213                    }
8214                }
8215
8216                Binder.restoreCallingIdentity(origId);
8217            }
8218
8219            boolean singleton;
8220            if (!providerRunning) {
8221                try {
8222                    cpi = AppGlobals.getPackageManager().
8223                        resolveContentProvider(name,
8224                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8225                } catch (RemoteException ex) {
8226                }
8227                if (cpi == null) {
8228                    return null;
8229                }
8230                // If the provider is a singleton AND
8231                // (it's a call within the same user || the provider is a
8232                // privileged app)
8233                // Then allow connecting to the singleton provider
8234                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8235                        cpi.name, cpi.flags)
8236                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8237                if (singleton) {
8238                    userId = UserHandle.USER_OWNER;
8239                }
8240                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8241
8242                String msg;
8243                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8244                        != null) {
8245                    throw new SecurityException(msg);
8246                }
8247
8248                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8249                        && !cpi.processName.equals("system")) {
8250                    // If this content provider does not run in the system
8251                    // process, and the system is not yet ready to run other
8252                    // processes, then fail fast instead of hanging.
8253                    throw new IllegalArgumentException(
8254                            "Attempt to launch content provider before system ready");
8255                }
8256
8257                // Make sure that the user who owns this provider is started.  If not,
8258                // we don't want to allow it to run.
8259                if (mStartedUsers.get(userId) == null) {
8260                    Slog.w(TAG, "Unable to launch app "
8261                            + cpi.applicationInfo.packageName + "/"
8262                            + cpi.applicationInfo.uid + " for provider "
8263                            + name + ": user " + userId + " is stopped");
8264                    return null;
8265                }
8266
8267                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8268                cpr = mProviderMap.getProviderByClass(comp, userId);
8269                final boolean firstClass = cpr == null;
8270                if (firstClass) {
8271                    try {
8272                        ApplicationInfo ai =
8273                            AppGlobals.getPackageManager().
8274                                getApplicationInfo(
8275                                        cpi.applicationInfo.packageName,
8276                                        STOCK_PM_FLAGS, userId);
8277                        if (ai == null) {
8278                            Slog.w(TAG, "No package info for content provider "
8279                                    + cpi.name);
8280                            return null;
8281                        }
8282                        ai = getAppInfoForUser(ai, userId);
8283                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8284                    } catch (RemoteException ex) {
8285                        // pm is in same process, this will never happen.
8286                    }
8287                }
8288
8289                if (r != null && cpr.canRunHere(r)) {
8290                    // If this is a multiprocess provider, then just return its
8291                    // info and allow the caller to instantiate it.  Only do
8292                    // this if the provider is the same user as the caller's
8293                    // process, or can run as root (so can be in any process).
8294                    return cpr.newHolder(null);
8295                }
8296
8297                if (DEBUG_PROVIDER) {
8298                    RuntimeException e = new RuntimeException("here");
8299                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8300                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8301                }
8302
8303                // This is single process, and our app is now connecting to it.
8304                // See if we are already in the process of launching this
8305                // provider.
8306                final int N = mLaunchingProviders.size();
8307                int i;
8308                for (i=0; i<N; i++) {
8309                    if (mLaunchingProviders.get(i) == cpr) {
8310                        break;
8311                    }
8312                }
8313
8314                // If the provider is not already being launched, then get it
8315                // started.
8316                if (i >= N) {
8317                    final long origId = Binder.clearCallingIdentity();
8318
8319                    try {
8320                        // Content provider is now in use, its package can't be stopped.
8321                        try {
8322                            AppGlobals.getPackageManager().setPackageStoppedState(
8323                                    cpr.appInfo.packageName, false, userId);
8324                        } catch (RemoteException e) {
8325                        } catch (IllegalArgumentException e) {
8326                            Slog.w(TAG, "Failed trying to unstop package "
8327                                    + cpr.appInfo.packageName + ": " + e);
8328                        }
8329
8330                        // Use existing process if already started
8331                        ProcessRecord proc = getProcessRecordLocked(
8332                                cpi.processName, cpr.appInfo.uid, false);
8333                        if (proc != null && proc.thread != null) {
8334                            if (DEBUG_PROVIDER) {
8335                                Slog.d(TAG, "Installing in existing process " + proc);
8336                            }
8337                            proc.pubProviders.put(cpi.name, cpr);
8338                            try {
8339                                proc.thread.scheduleInstallProvider(cpi);
8340                            } catch (RemoteException e) {
8341                            }
8342                        } else {
8343                            proc = startProcessLocked(cpi.processName,
8344                                    cpr.appInfo, false, 0, "content provider",
8345                                    new ComponentName(cpi.applicationInfo.packageName,
8346                                            cpi.name), false, false, false);
8347                            if (proc == null) {
8348                                Slog.w(TAG, "Unable to launch app "
8349                                        + cpi.applicationInfo.packageName + "/"
8350                                        + cpi.applicationInfo.uid + " for provider "
8351                                        + name + ": process is bad");
8352                                return null;
8353                            }
8354                        }
8355                        cpr.launchingApp = proc;
8356                        mLaunchingProviders.add(cpr);
8357                    } finally {
8358                        Binder.restoreCallingIdentity(origId);
8359                    }
8360                }
8361
8362                // Make sure the provider is published (the same provider class
8363                // may be published under multiple names).
8364                if (firstClass) {
8365                    mProviderMap.putProviderByClass(comp, cpr);
8366                }
8367
8368                mProviderMap.putProviderByName(name, cpr);
8369                conn = incProviderCountLocked(r, cpr, token, stable);
8370                if (conn != null) {
8371                    conn.waiting = true;
8372                }
8373            }
8374        }
8375
8376        // Wait for the provider to be published...
8377        synchronized (cpr) {
8378            while (cpr.provider == null) {
8379                if (cpr.launchingApp == null) {
8380                    Slog.w(TAG, "Unable to launch app "
8381                            + cpi.applicationInfo.packageName + "/"
8382                            + cpi.applicationInfo.uid + " for provider "
8383                            + name + ": launching app became null");
8384                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8385                            UserHandle.getUserId(cpi.applicationInfo.uid),
8386                            cpi.applicationInfo.packageName,
8387                            cpi.applicationInfo.uid, name);
8388                    return null;
8389                }
8390                try {
8391                    if (DEBUG_MU) {
8392                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8393                                + cpr.launchingApp);
8394                    }
8395                    if (conn != null) {
8396                        conn.waiting = true;
8397                    }
8398                    cpr.wait();
8399                } catch (InterruptedException ex) {
8400                } finally {
8401                    if (conn != null) {
8402                        conn.waiting = false;
8403                    }
8404                }
8405            }
8406        }
8407        return cpr != null ? cpr.newHolder(conn) : null;
8408    }
8409
8410    @Override
8411    public final ContentProviderHolder getContentProvider(
8412            IApplicationThread caller, String name, int userId, boolean stable) {
8413        enforceNotIsolatedCaller("getContentProvider");
8414        if (caller == null) {
8415            String msg = "null IApplicationThread when getting content provider "
8416                    + name;
8417            Slog.w(TAG, msg);
8418            throw new SecurityException(msg);
8419        }
8420        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8421        // with cross-user grant.
8422        return getContentProviderImpl(caller, name, null, stable, userId);
8423    }
8424
8425    public ContentProviderHolder getContentProviderExternal(
8426            String name, int userId, IBinder token) {
8427        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8428            "Do not have permission in call getContentProviderExternal()");
8429        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8430                false, true, "getContentProvider", null);
8431        return getContentProviderExternalUnchecked(name, token, userId);
8432    }
8433
8434    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8435            IBinder token, int userId) {
8436        return getContentProviderImpl(null, name, token, true, userId);
8437    }
8438
8439    /**
8440     * Drop a content provider from a ProcessRecord's bookkeeping
8441     */
8442    public void removeContentProvider(IBinder connection, boolean stable) {
8443        enforceNotIsolatedCaller("removeContentProvider");
8444        long ident = Binder.clearCallingIdentity();
8445        try {
8446            synchronized (this) {
8447                ContentProviderConnection conn;
8448                try {
8449                    conn = (ContentProviderConnection)connection;
8450                } catch (ClassCastException e) {
8451                    String msg ="removeContentProvider: " + connection
8452                            + " not a ContentProviderConnection";
8453                    Slog.w(TAG, msg);
8454                    throw new IllegalArgumentException(msg);
8455                }
8456                if (conn == null) {
8457                    throw new NullPointerException("connection is null");
8458                }
8459                if (decProviderCountLocked(conn, null, null, stable)) {
8460                    updateOomAdjLocked();
8461                }
8462            }
8463        } finally {
8464            Binder.restoreCallingIdentity(ident);
8465        }
8466    }
8467
8468    public void removeContentProviderExternal(String name, IBinder token) {
8469        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8470            "Do not have permission in call removeContentProviderExternal()");
8471        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8472    }
8473
8474    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8475        synchronized (this) {
8476            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8477            if(cpr == null) {
8478                //remove from mProvidersByClass
8479                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8480                return;
8481            }
8482
8483            //update content provider record entry info
8484            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8485            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8486            if (localCpr.hasExternalProcessHandles()) {
8487                if (localCpr.removeExternalProcessHandleLocked(token)) {
8488                    updateOomAdjLocked();
8489                } else {
8490                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8491                            + " with no external reference for token: "
8492                            + token + ".");
8493                }
8494            } else {
8495                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8496                        + " with no external references.");
8497            }
8498        }
8499    }
8500
8501    public final void publishContentProviders(IApplicationThread caller,
8502            List<ContentProviderHolder> providers) {
8503        if (providers == null) {
8504            return;
8505        }
8506
8507        enforceNotIsolatedCaller("publishContentProviders");
8508        synchronized (this) {
8509            final ProcessRecord r = getRecordForAppLocked(caller);
8510            if (DEBUG_MU)
8511                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8512            if (r == null) {
8513                throw new SecurityException(
8514                        "Unable to find app for caller " + caller
8515                      + " (pid=" + Binder.getCallingPid()
8516                      + ") when publishing content providers");
8517            }
8518
8519            final long origId = Binder.clearCallingIdentity();
8520
8521            final int N = providers.size();
8522            for (int i=0; i<N; i++) {
8523                ContentProviderHolder src = providers.get(i);
8524                if (src == null || src.info == null || src.provider == null) {
8525                    continue;
8526                }
8527                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8528                if (DEBUG_MU)
8529                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8530                if (dst != null) {
8531                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8532                    mProviderMap.putProviderByClass(comp, dst);
8533                    String names[] = dst.info.authority.split(";");
8534                    for (int j = 0; j < names.length; j++) {
8535                        mProviderMap.putProviderByName(names[j], dst);
8536                    }
8537
8538                    int NL = mLaunchingProviders.size();
8539                    int j;
8540                    for (j=0; j<NL; j++) {
8541                        if (mLaunchingProviders.get(j) == dst) {
8542                            mLaunchingProviders.remove(j);
8543                            j--;
8544                            NL--;
8545                        }
8546                    }
8547                    synchronized (dst) {
8548                        dst.provider = src.provider;
8549                        dst.proc = r;
8550                        dst.notifyAll();
8551                    }
8552                    updateOomAdjLocked(r);
8553                }
8554            }
8555
8556            Binder.restoreCallingIdentity(origId);
8557        }
8558    }
8559
8560    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8561        ContentProviderConnection conn;
8562        try {
8563            conn = (ContentProviderConnection)connection;
8564        } catch (ClassCastException e) {
8565            String msg ="refContentProvider: " + connection
8566                    + " not a ContentProviderConnection";
8567            Slog.w(TAG, msg);
8568            throw new IllegalArgumentException(msg);
8569        }
8570        if (conn == null) {
8571            throw new NullPointerException("connection is null");
8572        }
8573
8574        synchronized (this) {
8575            if (stable > 0) {
8576                conn.numStableIncs += stable;
8577            }
8578            stable = conn.stableCount + stable;
8579            if (stable < 0) {
8580                throw new IllegalStateException("stableCount < 0: " + stable);
8581            }
8582
8583            if (unstable > 0) {
8584                conn.numUnstableIncs += unstable;
8585            }
8586            unstable = conn.unstableCount + unstable;
8587            if (unstable < 0) {
8588                throw new IllegalStateException("unstableCount < 0: " + unstable);
8589            }
8590
8591            if ((stable+unstable) <= 0) {
8592                throw new IllegalStateException("ref counts can't go to zero here: stable="
8593                        + stable + " unstable=" + unstable);
8594            }
8595            conn.stableCount = stable;
8596            conn.unstableCount = unstable;
8597            return !conn.dead;
8598        }
8599    }
8600
8601    public void unstableProviderDied(IBinder connection) {
8602        ContentProviderConnection conn;
8603        try {
8604            conn = (ContentProviderConnection)connection;
8605        } catch (ClassCastException e) {
8606            String msg ="refContentProvider: " + connection
8607                    + " not a ContentProviderConnection";
8608            Slog.w(TAG, msg);
8609            throw new IllegalArgumentException(msg);
8610        }
8611        if (conn == null) {
8612            throw new NullPointerException("connection is null");
8613        }
8614
8615        // Safely retrieve the content provider associated with the connection.
8616        IContentProvider provider;
8617        synchronized (this) {
8618            provider = conn.provider.provider;
8619        }
8620
8621        if (provider == null) {
8622            // Um, yeah, we're way ahead of you.
8623            return;
8624        }
8625
8626        // Make sure the caller is being honest with us.
8627        if (provider.asBinder().pingBinder()) {
8628            // Er, no, still looks good to us.
8629            synchronized (this) {
8630                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8631                        + " says " + conn + " died, but we don't agree");
8632                return;
8633            }
8634        }
8635
8636        // Well look at that!  It's dead!
8637        synchronized (this) {
8638            if (conn.provider.provider != provider) {
8639                // But something changed...  good enough.
8640                return;
8641            }
8642
8643            ProcessRecord proc = conn.provider.proc;
8644            if (proc == null || proc.thread == null) {
8645                // Seems like the process is already cleaned up.
8646                return;
8647            }
8648
8649            // As far as we're concerned, this is just like receiving a
8650            // death notification...  just a bit prematurely.
8651            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8652                    + ") early provider death");
8653            final long ident = Binder.clearCallingIdentity();
8654            try {
8655                appDiedLocked(proc, proc.pid, proc.thread);
8656            } finally {
8657                Binder.restoreCallingIdentity(ident);
8658            }
8659        }
8660    }
8661
8662    @Override
8663    public void appNotRespondingViaProvider(IBinder connection) {
8664        enforceCallingPermission(
8665                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8666
8667        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8668        if (conn == null) {
8669            Slog.w(TAG, "ContentProviderConnection is null");
8670            return;
8671        }
8672
8673        final ProcessRecord host = conn.provider.proc;
8674        if (host == null) {
8675            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8676            return;
8677        }
8678
8679        final long token = Binder.clearCallingIdentity();
8680        try {
8681            appNotResponding(host, null, null, false, "ContentProvider not responding");
8682        } finally {
8683            Binder.restoreCallingIdentity(token);
8684        }
8685    }
8686
8687    public final void installSystemProviders() {
8688        List<ProviderInfo> providers;
8689        synchronized (this) {
8690            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8691            providers = generateApplicationProvidersLocked(app);
8692            if (providers != null) {
8693                for (int i=providers.size()-1; i>=0; i--) {
8694                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8695                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8696                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8697                                + ": not system .apk");
8698                        providers.remove(i);
8699                    }
8700                }
8701            }
8702        }
8703        if (providers != null) {
8704            mSystemThread.installSystemProviders(providers);
8705        }
8706
8707        mCoreSettingsObserver = new CoreSettingsObserver(this);
8708
8709        mUsageStatsService.monitorPackages();
8710    }
8711
8712    /**
8713     * Allows app to retrieve the MIME type of a URI without having permission
8714     * to access its content provider.
8715     *
8716     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8717     *
8718     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8719     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8720     */
8721    public String getProviderMimeType(Uri uri, int userId) {
8722        enforceNotIsolatedCaller("getProviderMimeType");
8723        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8724                userId, false, true, "getProviderMimeType", null);
8725        final String name = uri.getAuthority();
8726        final long ident = Binder.clearCallingIdentity();
8727        ContentProviderHolder holder = null;
8728
8729        try {
8730            holder = getContentProviderExternalUnchecked(name, null, userId);
8731            if (holder != null) {
8732                return holder.provider.getType(uri);
8733            }
8734        } catch (RemoteException e) {
8735            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8736            return null;
8737        } finally {
8738            if (holder != null) {
8739                removeContentProviderExternalUnchecked(name, null, userId);
8740            }
8741            Binder.restoreCallingIdentity(ident);
8742        }
8743
8744        return null;
8745    }
8746
8747    // =========================================================
8748    // GLOBAL MANAGEMENT
8749    // =========================================================
8750
8751    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8752            boolean isolated) {
8753        String proc = customProcess != null ? customProcess : info.processName;
8754        BatteryStatsImpl.Uid.Proc ps = null;
8755        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8756        int uid = info.uid;
8757        if (isolated) {
8758            int userId = UserHandle.getUserId(uid);
8759            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8760            while (true) {
8761                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8762                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8763                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8764                }
8765                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8766                mNextIsolatedProcessUid++;
8767                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8768                    // No process for this uid, use it.
8769                    break;
8770                }
8771                stepsLeft--;
8772                if (stepsLeft <= 0) {
8773                    return null;
8774                }
8775            }
8776        }
8777        return new ProcessRecord(stats, info, proc, uid);
8778    }
8779
8780    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8781            String abiOverride) {
8782        ProcessRecord app;
8783        if (!isolated) {
8784            app = getProcessRecordLocked(info.processName, info.uid, true);
8785        } else {
8786            app = null;
8787        }
8788
8789        if (app == null) {
8790            app = newProcessRecordLocked(info, null, isolated);
8791            mProcessNames.put(info.processName, app.uid, app);
8792            if (isolated) {
8793                mIsolatedProcesses.put(app.uid, app);
8794            }
8795            updateLruProcessLocked(app, false, null);
8796            updateOomAdjLocked();
8797        }
8798
8799        // This package really, really can not be stopped.
8800        try {
8801            AppGlobals.getPackageManager().setPackageStoppedState(
8802                    info.packageName, false, UserHandle.getUserId(app.uid));
8803        } catch (RemoteException e) {
8804        } catch (IllegalArgumentException e) {
8805            Slog.w(TAG, "Failed trying to unstop package "
8806                    + info.packageName + ": " + e);
8807        }
8808
8809        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8810                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8811            app.persistent = true;
8812            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8813        }
8814        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8815            mPersistentStartingProcesses.add(app);
8816            startProcessLocked(app, "added application", app.processName,
8817                    abiOverride);
8818        }
8819
8820        return app;
8821    }
8822
8823    public void unhandledBack() {
8824        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8825                "unhandledBack()");
8826
8827        synchronized(this) {
8828            final long origId = Binder.clearCallingIdentity();
8829            try {
8830                getFocusedStack().unhandledBackLocked();
8831            } finally {
8832                Binder.restoreCallingIdentity(origId);
8833            }
8834        }
8835    }
8836
8837    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8838        enforceNotIsolatedCaller("openContentUri");
8839        final int userId = UserHandle.getCallingUserId();
8840        String name = uri.getAuthority();
8841        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8842        ParcelFileDescriptor pfd = null;
8843        if (cph != null) {
8844            // We record the binder invoker's uid in thread-local storage before
8845            // going to the content provider to open the file.  Later, in the code
8846            // that handles all permissions checks, we look for this uid and use
8847            // that rather than the Activity Manager's own uid.  The effect is that
8848            // we do the check against the caller's permissions even though it looks
8849            // to the content provider like the Activity Manager itself is making
8850            // the request.
8851            sCallerIdentity.set(new Identity(
8852                    Binder.getCallingPid(), Binder.getCallingUid()));
8853            try {
8854                pfd = cph.provider.openFile(null, uri, "r", null);
8855            } catch (FileNotFoundException e) {
8856                // do nothing; pfd will be returned null
8857            } finally {
8858                // Ensure that whatever happens, we clean up the identity state
8859                sCallerIdentity.remove();
8860            }
8861
8862            // We've got the fd now, so we're done with the provider.
8863            removeContentProviderExternalUnchecked(name, null, userId);
8864        } else {
8865            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8866        }
8867        return pfd;
8868    }
8869
8870    // Actually is sleeping or shutting down or whatever else in the future
8871    // is an inactive state.
8872    public boolean isSleepingOrShuttingDown() {
8873        return mSleeping || mShuttingDown;
8874    }
8875
8876    public boolean isSleeping() {
8877        return mSleeping;
8878    }
8879
8880    void goingToSleep() {
8881        synchronized(this) {
8882            mWentToSleep = true;
8883            updateEventDispatchingLocked();
8884            goToSleepIfNeededLocked();
8885        }
8886    }
8887
8888    void finishRunningVoiceLocked() {
8889        if (mRunningVoice) {
8890            mRunningVoice = false;
8891            goToSleepIfNeededLocked();
8892        }
8893    }
8894
8895    void goToSleepIfNeededLocked() {
8896        if (mWentToSleep && !mRunningVoice) {
8897            if (!mSleeping) {
8898                mSleeping = true;
8899                mStackSupervisor.goingToSleepLocked();
8900
8901                // Initialize the wake times of all processes.
8902                checkExcessivePowerUsageLocked(false);
8903                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8904                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8905                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8906            }
8907        }
8908    }
8909
8910    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
8911        mTaskPersister.notify(task, flush);
8912    }
8913
8914    @Override
8915    public boolean shutdown(int timeout) {
8916        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8917                != PackageManager.PERMISSION_GRANTED) {
8918            throw new SecurityException("Requires permission "
8919                    + android.Manifest.permission.SHUTDOWN);
8920        }
8921
8922        boolean timedout = false;
8923
8924        synchronized(this) {
8925            mShuttingDown = true;
8926            updateEventDispatchingLocked();
8927            timedout = mStackSupervisor.shutdownLocked(timeout);
8928        }
8929
8930        mAppOpsService.shutdown();
8931        mUsageStatsService.shutdown();
8932        mBatteryStatsService.shutdown();
8933        synchronized (this) {
8934            mProcessStats.shutdownLocked();
8935        }
8936        notifyTaskPersisterLocked(null, true);
8937
8938        return timedout;
8939    }
8940
8941    public final void activitySlept(IBinder token) {
8942        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8943
8944        final long origId = Binder.clearCallingIdentity();
8945
8946        synchronized (this) {
8947            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8948            if (r != null) {
8949                mStackSupervisor.activitySleptLocked(r);
8950            }
8951        }
8952
8953        Binder.restoreCallingIdentity(origId);
8954    }
8955
8956    void logLockScreen(String msg) {
8957        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8958                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8959                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8960                mStackSupervisor.mDismissKeyguardOnNextActivity);
8961    }
8962
8963    private void comeOutOfSleepIfNeededLocked() {
8964        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8965            if (mSleeping) {
8966                mSleeping = false;
8967                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8968            }
8969        }
8970    }
8971
8972    void wakingUp() {
8973        synchronized(this) {
8974            mWentToSleep = false;
8975            updateEventDispatchingLocked();
8976            comeOutOfSleepIfNeededLocked();
8977        }
8978    }
8979
8980    void startRunningVoiceLocked() {
8981        if (!mRunningVoice) {
8982            mRunningVoice = true;
8983            comeOutOfSleepIfNeededLocked();
8984        }
8985    }
8986
8987    private void updateEventDispatchingLocked() {
8988        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8989    }
8990
8991    public void setLockScreenShown(boolean shown) {
8992        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8993                != PackageManager.PERMISSION_GRANTED) {
8994            throw new SecurityException("Requires permission "
8995                    + android.Manifest.permission.DEVICE_POWER);
8996        }
8997
8998        synchronized(this) {
8999            long ident = Binder.clearCallingIdentity();
9000            try {
9001                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9002                mLockScreenShown = shown;
9003                comeOutOfSleepIfNeededLocked();
9004            } finally {
9005                Binder.restoreCallingIdentity(ident);
9006            }
9007        }
9008    }
9009
9010    public void stopAppSwitches() {
9011        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9012                != PackageManager.PERMISSION_GRANTED) {
9013            throw new SecurityException("Requires permission "
9014                    + android.Manifest.permission.STOP_APP_SWITCHES);
9015        }
9016
9017        synchronized(this) {
9018            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9019                    + APP_SWITCH_DELAY_TIME;
9020            mDidAppSwitch = false;
9021            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9022            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9023            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9024        }
9025    }
9026
9027    public void resumeAppSwitches() {
9028        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9029                != PackageManager.PERMISSION_GRANTED) {
9030            throw new SecurityException("Requires permission "
9031                    + android.Manifest.permission.STOP_APP_SWITCHES);
9032        }
9033
9034        synchronized(this) {
9035            // Note that we don't execute any pending app switches... we will
9036            // let those wait until either the timeout, or the next start
9037            // activity request.
9038            mAppSwitchesAllowedTime = 0;
9039        }
9040    }
9041
9042    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9043            String name) {
9044        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9045            return true;
9046        }
9047
9048        final int perm = checkComponentPermission(
9049                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9050                callingUid, -1, true);
9051        if (perm == PackageManager.PERMISSION_GRANTED) {
9052            return true;
9053        }
9054
9055        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9056        return false;
9057    }
9058
9059    public void setDebugApp(String packageName, boolean waitForDebugger,
9060            boolean persistent) {
9061        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9062                "setDebugApp()");
9063
9064        long ident = Binder.clearCallingIdentity();
9065        try {
9066            // Note that this is not really thread safe if there are multiple
9067            // callers into it at the same time, but that's not a situation we
9068            // care about.
9069            if (persistent) {
9070                final ContentResolver resolver = mContext.getContentResolver();
9071                Settings.Global.putString(
9072                    resolver, Settings.Global.DEBUG_APP,
9073                    packageName);
9074                Settings.Global.putInt(
9075                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9076                    waitForDebugger ? 1 : 0);
9077            }
9078
9079            synchronized (this) {
9080                if (!persistent) {
9081                    mOrigDebugApp = mDebugApp;
9082                    mOrigWaitForDebugger = mWaitForDebugger;
9083                }
9084                mDebugApp = packageName;
9085                mWaitForDebugger = waitForDebugger;
9086                mDebugTransient = !persistent;
9087                if (packageName != null) {
9088                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9089                            false, UserHandle.USER_ALL, "set debug app");
9090                }
9091            }
9092        } finally {
9093            Binder.restoreCallingIdentity(ident);
9094        }
9095    }
9096
9097    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9098        synchronized (this) {
9099            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9100            if (!isDebuggable) {
9101                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9102                    throw new SecurityException("Process not debuggable: " + app.packageName);
9103                }
9104            }
9105
9106            mOpenGlTraceApp = processName;
9107        }
9108    }
9109
9110    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9111            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9112        synchronized (this) {
9113            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9114            if (!isDebuggable) {
9115                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9116                    throw new SecurityException("Process not debuggable: " + app.packageName);
9117                }
9118            }
9119            mProfileApp = processName;
9120            mProfileFile = profileFile;
9121            if (mProfileFd != null) {
9122                try {
9123                    mProfileFd.close();
9124                } catch (IOException e) {
9125                }
9126                mProfileFd = null;
9127            }
9128            mProfileFd = profileFd;
9129            mProfileType = 0;
9130            mAutoStopProfiler = autoStopProfiler;
9131        }
9132    }
9133
9134    @Override
9135    public void setAlwaysFinish(boolean enabled) {
9136        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9137                "setAlwaysFinish()");
9138
9139        Settings.Global.putInt(
9140                mContext.getContentResolver(),
9141                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9142
9143        synchronized (this) {
9144            mAlwaysFinishActivities = enabled;
9145        }
9146    }
9147
9148    @Override
9149    public void setActivityController(IActivityController controller) {
9150        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9151                "setActivityController()");
9152        synchronized (this) {
9153            mController = controller;
9154            Watchdog.getInstance().setActivityController(controller);
9155        }
9156    }
9157
9158    @Override
9159    public void setUserIsMonkey(boolean userIsMonkey) {
9160        synchronized (this) {
9161            synchronized (mPidsSelfLocked) {
9162                final int callingPid = Binder.getCallingPid();
9163                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9164                if (precessRecord == null) {
9165                    throw new SecurityException("Unknown process: " + callingPid);
9166                }
9167                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9168                    throw new SecurityException("Only an instrumentation process "
9169                            + "with a UiAutomation can call setUserIsMonkey");
9170                }
9171            }
9172            mUserIsMonkey = userIsMonkey;
9173        }
9174    }
9175
9176    @Override
9177    public boolean isUserAMonkey() {
9178        synchronized (this) {
9179            // If there is a controller also implies the user is a monkey.
9180            return (mUserIsMonkey || mController != null);
9181        }
9182    }
9183
9184    public void requestBugReport() {
9185        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9186        SystemProperties.set("ctl.start", "bugreport");
9187    }
9188
9189    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9190        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9191    }
9192
9193    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9194        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9195            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9196        }
9197        return KEY_DISPATCHING_TIMEOUT;
9198    }
9199
9200    @Override
9201    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9202        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9203                != PackageManager.PERMISSION_GRANTED) {
9204            throw new SecurityException("Requires permission "
9205                    + android.Manifest.permission.FILTER_EVENTS);
9206        }
9207        ProcessRecord proc;
9208        long timeout;
9209        synchronized (this) {
9210            synchronized (mPidsSelfLocked) {
9211                proc = mPidsSelfLocked.get(pid);
9212            }
9213            timeout = getInputDispatchingTimeoutLocked(proc);
9214        }
9215
9216        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9217            return -1;
9218        }
9219
9220        return timeout;
9221    }
9222
9223    /**
9224     * Handle input dispatching timeouts.
9225     * Returns whether input dispatching should be aborted or not.
9226     */
9227    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9228            final ActivityRecord activity, final ActivityRecord parent,
9229            final boolean aboveSystem, String reason) {
9230        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9231                != PackageManager.PERMISSION_GRANTED) {
9232            throw new SecurityException("Requires permission "
9233                    + android.Manifest.permission.FILTER_EVENTS);
9234        }
9235
9236        final String annotation;
9237        if (reason == null) {
9238            annotation = "Input dispatching timed out";
9239        } else {
9240            annotation = "Input dispatching timed out (" + reason + ")";
9241        }
9242
9243        if (proc != null) {
9244            synchronized (this) {
9245                if (proc.debugging) {
9246                    return false;
9247                }
9248
9249                if (mDidDexOpt) {
9250                    // Give more time since we were dexopting.
9251                    mDidDexOpt = false;
9252                    return false;
9253                }
9254
9255                if (proc.instrumentationClass != null) {
9256                    Bundle info = new Bundle();
9257                    info.putString("shortMsg", "keyDispatchingTimedOut");
9258                    info.putString("longMsg", annotation);
9259                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9260                    return true;
9261                }
9262            }
9263            mHandler.post(new Runnable() {
9264                @Override
9265                public void run() {
9266                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9267                }
9268            });
9269        }
9270
9271        return true;
9272    }
9273
9274    public Bundle getAssistContextExtras(int requestType) {
9275        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9276                "getAssistContextExtras()");
9277        PendingAssistExtras pae;
9278        Bundle extras = new Bundle();
9279        synchronized (this) {
9280            ActivityRecord activity = getFocusedStack().mResumedActivity;
9281            if (activity == null) {
9282                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9283                return null;
9284            }
9285            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9286            if (activity.app == null || activity.app.thread == null) {
9287                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9288                return extras;
9289            }
9290            if (activity.app.pid == Binder.getCallingPid()) {
9291                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9292                return extras;
9293            }
9294            pae = new PendingAssistExtras(activity);
9295            try {
9296                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9297                        requestType);
9298                mPendingAssistExtras.add(pae);
9299                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9300            } catch (RemoteException e) {
9301                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9302                return extras;
9303            }
9304        }
9305        synchronized (pae) {
9306            while (!pae.haveResult) {
9307                try {
9308                    pae.wait();
9309                } catch (InterruptedException e) {
9310                }
9311            }
9312            if (pae.result != null) {
9313                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9314            }
9315        }
9316        synchronized (this) {
9317            mPendingAssistExtras.remove(pae);
9318            mHandler.removeCallbacks(pae);
9319        }
9320        return extras;
9321    }
9322
9323    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9324        PendingAssistExtras pae = (PendingAssistExtras)token;
9325        synchronized (pae) {
9326            pae.result = extras;
9327            pae.haveResult = true;
9328            pae.notifyAll();
9329        }
9330    }
9331
9332    public void registerProcessObserver(IProcessObserver observer) {
9333        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9334                "registerProcessObserver()");
9335        synchronized (this) {
9336            mProcessObservers.register(observer);
9337        }
9338    }
9339
9340    @Override
9341    public void unregisterProcessObserver(IProcessObserver observer) {
9342        synchronized (this) {
9343            mProcessObservers.unregister(observer);
9344        }
9345    }
9346
9347    @Override
9348    public boolean convertFromTranslucent(IBinder token) {
9349        final long origId = Binder.clearCallingIdentity();
9350        try {
9351            synchronized (this) {
9352                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9353                if (r == null) {
9354                    return false;
9355                }
9356                if (r.changeWindowTranslucency(true)) {
9357                    mWindowManager.setAppFullscreen(token, true);
9358                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9359                    return true;
9360                }
9361                return false;
9362            }
9363        } finally {
9364            Binder.restoreCallingIdentity(origId);
9365        }
9366    }
9367
9368    @Override
9369    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9370        final long origId = Binder.clearCallingIdentity();
9371        try {
9372            synchronized (this) {
9373                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9374                if (r == null) {
9375                    return false;
9376                }
9377                if (r.changeWindowTranslucency(false)) {
9378                    r.task.stack.convertToTranslucent(r, options);
9379                    mWindowManager.setAppFullscreen(token, false);
9380                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9381                    return true;
9382                }
9383                return false;
9384            }
9385        } finally {
9386            Binder.restoreCallingIdentity(origId);
9387        }
9388    }
9389
9390    @Override
9391    public ActivityOptions getActivityOptions(IBinder token) {
9392        final long origId = Binder.clearCallingIdentity();
9393        try {
9394            synchronized (this) {
9395                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9396                if (r != null) {
9397                    final ActivityOptions activityOptions = r.pendingOptions;
9398                    r.pendingOptions = null;
9399                    return activityOptions;
9400                }
9401                return null;
9402            }
9403        } finally {
9404            Binder.restoreCallingIdentity(origId);
9405        }
9406    }
9407
9408    @Override
9409    public void setImmersive(IBinder token, boolean immersive) {
9410        synchronized(this) {
9411            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9412            if (r == null) {
9413                throw new IllegalArgumentException();
9414            }
9415            r.immersive = immersive;
9416
9417            // update associated state if we're frontmost
9418            if (r == mFocusedActivity) {
9419                if (DEBUG_IMMERSIVE) {
9420                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9421                }
9422                applyUpdateLockStateLocked(r);
9423            }
9424        }
9425    }
9426
9427    @Override
9428    public boolean isImmersive(IBinder token) {
9429        synchronized (this) {
9430            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9431            if (r == null) {
9432                throw new IllegalArgumentException();
9433            }
9434            return r.immersive;
9435        }
9436    }
9437
9438    public boolean isTopActivityImmersive() {
9439        enforceNotIsolatedCaller("startActivity");
9440        synchronized (this) {
9441            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9442            return (r != null) ? r.immersive : false;
9443        }
9444    }
9445
9446    public final void enterSafeMode() {
9447        synchronized(this) {
9448            // It only makes sense to do this before the system is ready
9449            // and started launching other packages.
9450            if (!mSystemReady) {
9451                try {
9452                    AppGlobals.getPackageManager().enterSafeMode();
9453                } catch (RemoteException e) {
9454                }
9455            }
9456
9457            mSafeMode = true;
9458        }
9459    }
9460
9461    public final void showSafeModeOverlay() {
9462        View v = LayoutInflater.from(mContext).inflate(
9463                com.android.internal.R.layout.safe_mode, null);
9464        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9465        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9466        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9467        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9468        lp.gravity = Gravity.BOTTOM | Gravity.START;
9469        lp.format = v.getBackground().getOpacity();
9470        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9471                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9472        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9473        ((WindowManager)mContext.getSystemService(
9474                Context.WINDOW_SERVICE)).addView(v, lp);
9475    }
9476
9477    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9478        if (!(sender instanceof PendingIntentRecord)) {
9479            return;
9480        }
9481        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9482        synchronized (stats) {
9483            if (mBatteryStatsService.isOnBattery()) {
9484                mBatteryStatsService.enforceCallingPermission();
9485                PendingIntentRecord rec = (PendingIntentRecord)sender;
9486                int MY_UID = Binder.getCallingUid();
9487                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9488                BatteryStatsImpl.Uid.Pkg pkg =
9489                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9490                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9491                pkg.incWakeupsLocked();
9492            }
9493        }
9494    }
9495
9496    public boolean killPids(int[] pids, String pReason, boolean secure) {
9497        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9498            throw new SecurityException("killPids only available to the system");
9499        }
9500        String reason = (pReason == null) ? "Unknown" : pReason;
9501        // XXX Note: don't acquire main activity lock here, because the window
9502        // manager calls in with its locks held.
9503
9504        boolean killed = false;
9505        synchronized (mPidsSelfLocked) {
9506            int[] types = new int[pids.length];
9507            int worstType = 0;
9508            for (int i=0; i<pids.length; i++) {
9509                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9510                if (proc != null) {
9511                    int type = proc.setAdj;
9512                    types[i] = type;
9513                    if (type > worstType) {
9514                        worstType = type;
9515                    }
9516                }
9517            }
9518
9519            // If the worst oom_adj is somewhere in the cached proc LRU range,
9520            // then constrain it so we will kill all cached procs.
9521            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9522                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9523                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9524            }
9525
9526            // If this is not a secure call, don't let it kill processes that
9527            // are important.
9528            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9529                worstType = ProcessList.SERVICE_ADJ;
9530            }
9531
9532            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9533            for (int i=0; i<pids.length; i++) {
9534                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9535                if (proc == null) {
9536                    continue;
9537                }
9538                int adj = proc.setAdj;
9539                if (adj >= worstType && !proc.killedByAm) {
9540                    killUnneededProcessLocked(proc, reason);
9541                    killed = true;
9542                }
9543            }
9544        }
9545        return killed;
9546    }
9547
9548    @Override
9549    public void killUid(int uid, String reason) {
9550        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9551            throw new SecurityException("killUid only available to the system");
9552        }
9553        synchronized (this) {
9554            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9555                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9556                    reason != null ? reason : "kill uid");
9557        }
9558    }
9559
9560    @Override
9561    public boolean killProcessesBelowForeground(String reason) {
9562        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9563            throw new SecurityException("killProcessesBelowForeground() only available to system");
9564        }
9565
9566        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9567    }
9568
9569    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9570        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9571            throw new SecurityException("killProcessesBelowAdj() only available to system");
9572        }
9573
9574        boolean killed = false;
9575        synchronized (mPidsSelfLocked) {
9576            final int size = mPidsSelfLocked.size();
9577            for (int i = 0; i < size; i++) {
9578                final int pid = mPidsSelfLocked.keyAt(i);
9579                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9580                if (proc == null) continue;
9581
9582                final int adj = proc.setAdj;
9583                if (adj > belowAdj && !proc.killedByAm) {
9584                    killUnneededProcessLocked(proc, reason);
9585                    killed = true;
9586                }
9587            }
9588        }
9589        return killed;
9590    }
9591
9592    @Override
9593    public void hang(final IBinder who, boolean allowRestart) {
9594        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9595                != PackageManager.PERMISSION_GRANTED) {
9596            throw new SecurityException("Requires permission "
9597                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9598        }
9599
9600        final IBinder.DeathRecipient death = new DeathRecipient() {
9601            @Override
9602            public void binderDied() {
9603                synchronized (this) {
9604                    notifyAll();
9605                }
9606            }
9607        };
9608
9609        try {
9610            who.linkToDeath(death, 0);
9611        } catch (RemoteException e) {
9612            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9613            return;
9614        }
9615
9616        synchronized (this) {
9617            Watchdog.getInstance().setAllowRestart(allowRestart);
9618            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9619            synchronized (death) {
9620                while (who.isBinderAlive()) {
9621                    try {
9622                        death.wait();
9623                    } catch (InterruptedException e) {
9624                    }
9625                }
9626            }
9627            Watchdog.getInstance().setAllowRestart(true);
9628        }
9629    }
9630
9631    @Override
9632    public void restart() {
9633        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9634                != PackageManager.PERMISSION_GRANTED) {
9635            throw new SecurityException("Requires permission "
9636                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9637        }
9638
9639        Log.i(TAG, "Sending shutdown broadcast...");
9640
9641        BroadcastReceiver br = new BroadcastReceiver() {
9642            @Override public void onReceive(Context context, Intent intent) {
9643                // Now the broadcast is done, finish up the low-level shutdown.
9644                Log.i(TAG, "Shutting down activity manager...");
9645                shutdown(10000);
9646                Log.i(TAG, "Shutdown complete, restarting!");
9647                Process.killProcess(Process.myPid());
9648                System.exit(10);
9649            }
9650        };
9651
9652        // First send the high-level shut down broadcast.
9653        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9654        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9655        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9656        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9657        mContext.sendOrderedBroadcastAsUser(intent,
9658                UserHandle.ALL, null, br, mHandler, 0, null, null);
9659        */
9660        br.onReceive(mContext, intent);
9661    }
9662
9663    private long getLowRamTimeSinceIdle(long now) {
9664        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9665    }
9666
9667    @Override
9668    public void performIdleMaintenance() {
9669        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9670                != PackageManager.PERMISSION_GRANTED) {
9671            throw new SecurityException("Requires permission "
9672                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9673        }
9674
9675        synchronized (this) {
9676            final long now = SystemClock.uptimeMillis();
9677            final long timeSinceLastIdle = now - mLastIdleTime;
9678            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9679            mLastIdleTime = now;
9680            mLowRamTimeSinceLastIdle = 0;
9681            if (mLowRamStartTime != 0) {
9682                mLowRamStartTime = now;
9683            }
9684
9685            StringBuilder sb = new StringBuilder(128);
9686            sb.append("Idle maintenance over ");
9687            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9688            sb.append(" low RAM for ");
9689            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9690            Slog.i(TAG, sb.toString());
9691
9692            // If at least 1/3 of our time since the last idle period has been spent
9693            // with RAM low, then we want to kill processes.
9694            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9695
9696            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9697                ProcessRecord proc = mLruProcesses.get(i);
9698                if (proc.notCachedSinceIdle) {
9699                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9700                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9701                        if (doKilling && proc.initialIdlePss != 0
9702                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9703                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9704                                    + " from " + proc.initialIdlePss + ")");
9705                        }
9706                    }
9707                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9708                    proc.notCachedSinceIdle = true;
9709                    proc.initialIdlePss = 0;
9710                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9711                            isSleeping(), now);
9712                }
9713            }
9714
9715            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9716            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9717        }
9718    }
9719
9720    private void retrieveSettings() {
9721        final ContentResolver resolver = mContext.getContentResolver();
9722        String debugApp = Settings.Global.getString(
9723            resolver, Settings.Global.DEBUG_APP);
9724        boolean waitForDebugger = Settings.Global.getInt(
9725            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9726        boolean alwaysFinishActivities = Settings.Global.getInt(
9727            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9728        boolean forceRtl = Settings.Global.getInt(
9729                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9730        // Transfer any global setting for forcing RTL layout, into a System Property
9731        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9732
9733        Configuration configuration = new Configuration();
9734        Settings.System.getConfiguration(resolver, configuration);
9735        if (forceRtl) {
9736            // This will take care of setting the correct layout direction flags
9737            configuration.setLayoutDirection(configuration.locale);
9738        }
9739
9740        synchronized (this) {
9741            mDebugApp = mOrigDebugApp = debugApp;
9742            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9743            mAlwaysFinishActivities = alwaysFinishActivities;
9744            // This happens before any activities are started, so we can
9745            // change mConfiguration in-place.
9746            updateConfigurationLocked(configuration, null, false, true);
9747            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9748        }
9749    }
9750
9751    public boolean testIsSystemReady() {
9752        // no need to synchronize(this) just to read & return the value
9753        return mSystemReady;
9754    }
9755
9756    private static File getCalledPreBootReceiversFile() {
9757        File dataDir = Environment.getDataDirectory();
9758        File systemDir = new File(dataDir, "system");
9759        File fname = new File(systemDir, "called_pre_boots.dat");
9760        return fname;
9761    }
9762
9763    static final int LAST_DONE_VERSION = 10000;
9764
9765    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9766        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9767        File file = getCalledPreBootReceiversFile();
9768        FileInputStream fis = null;
9769        try {
9770            fis = new FileInputStream(file);
9771            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9772            int fvers = dis.readInt();
9773            if (fvers == LAST_DONE_VERSION) {
9774                String vers = dis.readUTF();
9775                String codename = dis.readUTF();
9776                String build = dis.readUTF();
9777                if (android.os.Build.VERSION.RELEASE.equals(vers)
9778                        && android.os.Build.VERSION.CODENAME.equals(codename)
9779                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9780                    int num = dis.readInt();
9781                    while (num > 0) {
9782                        num--;
9783                        String pkg = dis.readUTF();
9784                        String cls = dis.readUTF();
9785                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9786                    }
9787                }
9788            }
9789        } catch (FileNotFoundException e) {
9790        } catch (IOException e) {
9791            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9792        } finally {
9793            if (fis != null) {
9794                try {
9795                    fis.close();
9796                } catch (IOException e) {
9797                }
9798            }
9799        }
9800        return lastDoneReceivers;
9801    }
9802
9803    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9804        File file = getCalledPreBootReceiversFile();
9805        FileOutputStream fos = null;
9806        DataOutputStream dos = null;
9807        try {
9808            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9809            fos = new FileOutputStream(file);
9810            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9811            dos.writeInt(LAST_DONE_VERSION);
9812            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9813            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9814            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9815            dos.writeInt(list.size());
9816            for (int i=0; i<list.size(); i++) {
9817                dos.writeUTF(list.get(i).getPackageName());
9818                dos.writeUTF(list.get(i).getClassName());
9819            }
9820        } catch (IOException e) {
9821            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9822            file.delete();
9823        } finally {
9824            FileUtils.sync(fos);
9825            if (dos != null) {
9826                try {
9827                    dos.close();
9828                } catch (IOException e) {
9829                    // TODO Auto-generated catch block
9830                    e.printStackTrace();
9831                }
9832            }
9833        }
9834    }
9835
9836    public void systemReady(final Runnable goingCallback) {
9837        synchronized(this) {
9838            if (mSystemReady) {
9839                if (goingCallback != null) goingCallback.run();
9840                return;
9841            }
9842
9843            if (mRecentTasks == null) {
9844                mRecentTasks = mTaskPersister.restoreTasksLocked();
9845                if (!mRecentTasks.isEmpty()) {
9846                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
9847                }
9848                mTaskPersister.startPersisting();
9849            }
9850
9851            // Check to see if there are any update receivers to run.
9852            if (!mDidUpdate) {
9853                if (mWaitingUpdate) {
9854                    return;
9855                }
9856                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9857                List<ResolveInfo> ris = null;
9858                try {
9859                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9860                            intent, null, 0, 0);
9861                } catch (RemoteException e) {
9862                }
9863                if (ris != null) {
9864                    for (int i=ris.size()-1; i>=0; i--) {
9865                        if ((ris.get(i).activityInfo.applicationInfo.flags
9866                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9867                            ris.remove(i);
9868                        }
9869                    }
9870                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9871
9872                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9873
9874                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9875                    for (int i=0; i<ris.size(); i++) {
9876                        ActivityInfo ai = ris.get(i).activityInfo;
9877                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9878                        if (lastDoneReceivers.contains(comp)) {
9879                            // We already did the pre boot receiver for this app with the current
9880                            // platform version, so don't do it again...
9881                            ris.remove(i);
9882                            i--;
9883                            // ...however, do keep it as one that has been done, so we don't
9884                            // forget about it when rewriting the file of last done receivers.
9885                            doneReceivers.add(comp);
9886                        }
9887                    }
9888
9889                    final int[] users = getUsersLocked();
9890                    for (int i=0; i<ris.size(); i++) {
9891                        ActivityInfo ai = ris.get(i).activityInfo;
9892                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9893                        doneReceivers.add(comp);
9894                        intent.setComponent(comp);
9895                        for (int j=0; j<users.length; j++) {
9896                            IIntentReceiver finisher = null;
9897                            if (i == ris.size()-1 && j == users.length-1) {
9898                                finisher = new IIntentReceiver.Stub() {
9899                                    public void performReceive(Intent intent, int resultCode,
9900                                            String data, Bundle extras, boolean ordered,
9901                                            boolean sticky, int sendingUser) {
9902                                        // The raw IIntentReceiver interface is called
9903                                        // with the AM lock held, so redispatch to
9904                                        // execute our code without the lock.
9905                                        mHandler.post(new Runnable() {
9906                                            public void run() {
9907                                                synchronized (ActivityManagerService.this) {
9908                                                    mDidUpdate = true;
9909                                                }
9910                                                writeLastDonePreBootReceivers(doneReceivers);
9911                                                showBootMessage(mContext.getText(
9912                                                        R.string.android_upgrading_complete),
9913                                                        false);
9914                                                systemReady(goingCallback);
9915                                            }
9916                                        });
9917                                    }
9918                                };
9919                            }
9920                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9921                                    + " for user " + users[j]);
9922                            broadcastIntentLocked(null, null, intent, null, finisher,
9923                                    0, null, null, null, AppOpsManager.OP_NONE,
9924                                    true, false, MY_PID, Process.SYSTEM_UID,
9925                                    users[j]);
9926                            if (finisher != null) {
9927                                mWaitingUpdate = true;
9928                            }
9929                        }
9930                    }
9931                }
9932                if (mWaitingUpdate) {
9933                    return;
9934                }
9935                mDidUpdate = true;
9936            }
9937
9938            mAppOpsService.systemReady();
9939            mUsageStatsService.systemReady();
9940            mSystemReady = true;
9941        }
9942
9943        ArrayList<ProcessRecord> procsToKill = null;
9944        synchronized(mPidsSelfLocked) {
9945            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9946                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9947                if (!isAllowedWhileBooting(proc.info)){
9948                    if (procsToKill == null) {
9949                        procsToKill = new ArrayList<ProcessRecord>();
9950                    }
9951                    procsToKill.add(proc);
9952                }
9953            }
9954        }
9955
9956        synchronized(this) {
9957            if (procsToKill != null) {
9958                for (int i=procsToKill.size()-1; i>=0; i--) {
9959                    ProcessRecord proc = procsToKill.get(i);
9960                    Slog.i(TAG, "Removing system update proc: " + proc);
9961                    removeProcessLocked(proc, true, false, "system update done");
9962                }
9963            }
9964
9965            // Now that we have cleaned up any update processes, we
9966            // are ready to start launching real processes and know that
9967            // we won't trample on them any more.
9968            mProcessesReady = true;
9969        }
9970
9971        Slog.i(TAG, "System now ready");
9972        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9973            SystemClock.uptimeMillis());
9974
9975        synchronized(this) {
9976            // Make sure we have no pre-ready processes sitting around.
9977
9978            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9979                ResolveInfo ri = mContext.getPackageManager()
9980                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9981                                STOCK_PM_FLAGS);
9982                CharSequence errorMsg = null;
9983                if (ri != null) {
9984                    ActivityInfo ai = ri.activityInfo;
9985                    ApplicationInfo app = ai.applicationInfo;
9986                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9987                        mTopAction = Intent.ACTION_FACTORY_TEST;
9988                        mTopData = null;
9989                        mTopComponent = new ComponentName(app.packageName,
9990                                ai.name);
9991                    } else {
9992                        errorMsg = mContext.getResources().getText(
9993                                com.android.internal.R.string.factorytest_not_system);
9994                    }
9995                } else {
9996                    errorMsg = mContext.getResources().getText(
9997                            com.android.internal.R.string.factorytest_no_action);
9998                }
9999                if (errorMsg != null) {
10000                    mTopAction = null;
10001                    mTopData = null;
10002                    mTopComponent = null;
10003                    Message msg = Message.obtain();
10004                    msg.what = SHOW_FACTORY_ERROR_MSG;
10005                    msg.getData().putCharSequence("msg", errorMsg);
10006                    mHandler.sendMessage(msg);
10007                }
10008            }
10009        }
10010
10011        retrieveSettings();
10012
10013        synchronized (this) {
10014            readGrantedUriPermissionsLocked();
10015        }
10016
10017        if (goingCallback != null) goingCallback.run();
10018
10019        mSystemServiceManager.startUser(mCurrentUserId);
10020
10021        synchronized (this) {
10022            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10023                try {
10024                    List apps = AppGlobals.getPackageManager().
10025                        getPersistentApplications(STOCK_PM_FLAGS);
10026                    if (apps != null) {
10027                        int N = apps.size();
10028                        int i;
10029                        for (i=0; i<N; i++) {
10030                            ApplicationInfo info
10031                                = (ApplicationInfo)apps.get(i);
10032                            if (info != null &&
10033                                    !info.packageName.equals("android")) {
10034                                addAppLocked(info, false, null /* ABI override */);
10035                            }
10036                        }
10037                    }
10038                } catch (RemoteException ex) {
10039                    // pm is in same process, this will never happen.
10040                }
10041            }
10042
10043            // Start up initial activity.
10044            mBooting = true;
10045
10046            try {
10047                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10048                    Message msg = Message.obtain();
10049                    msg.what = SHOW_UID_ERROR_MSG;
10050                    mHandler.sendMessage(msg);
10051                }
10052            } catch (RemoteException e) {
10053            }
10054
10055            long ident = Binder.clearCallingIdentity();
10056            try {
10057                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10058                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10059                        | Intent.FLAG_RECEIVER_FOREGROUND);
10060                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10061                broadcastIntentLocked(null, null, intent,
10062                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10063                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10064                intent = new Intent(Intent.ACTION_USER_STARTING);
10065                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10066                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10067                broadcastIntentLocked(null, null, intent,
10068                        null, new IIntentReceiver.Stub() {
10069                            @Override
10070                            public void performReceive(Intent intent, int resultCode, String data,
10071                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10072                                    throws RemoteException {
10073                            }
10074                        }, 0, null, null,
10075                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10076                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10077            } catch (Throwable t) {
10078                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10079            } finally {
10080                Binder.restoreCallingIdentity(ident);
10081            }
10082            mStackSupervisor.resumeTopActivitiesLocked();
10083            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10084        }
10085    }
10086
10087    private boolean makeAppCrashingLocked(ProcessRecord app,
10088            String shortMsg, String longMsg, String stackTrace) {
10089        app.crashing = true;
10090        app.crashingReport = generateProcessError(app,
10091                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10092        startAppProblemLocked(app);
10093        app.stopFreezingAllLocked();
10094        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10095    }
10096
10097    private void makeAppNotRespondingLocked(ProcessRecord app,
10098            String activity, String shortMsg, String longMsg) {
10099        app.notResponding = true;
10100        app.notRespondingReport = generateProcessError(app,
10101                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10102                activity, shortMsg, longMsg, null);
10103        startAppProblemLocked(app);
10104        app.stopFreezingAllLocked();
10105    }
10106
10107    /**
10108     * Generate a process error record, suitable for attachment to a ProcessRecord.
10109     *
10110     * @param app The ProcessRecord in which the error occurred.
10111     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10112     *                      ActivityManager.AppErrorStateInfo
10113     * @param activity The activity associated with the crash, if known.
10114     * @param shortMsg Short message describing the crash.
10115     * @param longMsg Long message describing the crash.
10116     * @param stackTrace Full crash stack trace, may be null.
10117     *
10118     * @return Returns a fully-formed AppErrorStateInfo record.
10119     */
10120    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10121            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10122        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10123
10124        report.condition = condition;
10125        report.processName = app.processName;
10126        report.pid = app.pid;
10127        report.uid = app.info.uid;
10128        report.tag = activity;
10129        report.shortMsg = shortMsg;
10130        report.longMsg = longMsg;
10131        report.stackTrace = stackTrace;
10132
10133        return report;
10134    }
10135
10136    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10137        synchronized (this) {
10138            app.crashing = false;
10139            app.crashingReport = null;
10140            app.notResponding = false;
10141            app.notRespondingReport = null;
10142            if (app.anrDialog == fromDialog) {
10143                app.anrDialog = null;
10144            }
10145            if (app.waitDialog == fromDialog) {
10146                app.waitDialog = null;
10147            }
10148            if (app.pid > 0 && app.pid != MY_PID) {
10149                handleAppCrashLocked(app, null, null, null);
10150                killUnneededProcessLocked(app, "user request after error");
10151            }
10152        }
10153    }
10154
10155    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10156            String stackTrace) {
10157        long now = SystemClock.uptimeMillis();
10158
10159        Long crashTime;
10160        if (!app.isolated) {
10161            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10162        } else {
10163            crashTime = null;
10164        }
10165        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10166            // This process loses!
10167            Slog.w(TAG, "Process " + app.info.processName
10168                    + " has crashed too many times: killing!");
10169            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10170                    app.userId, app.info.processName, app.uid);
10171            mStackSupervisor.handleAppCrashLocked(app);
10172            if (!app.persistent) {
10173                // We don't want to start this process again until the user
10174                // explicitly does so...  but for persistent process, we really
10175                // need to keep it running.  If a persistent process is actually
10176                // repeatedly crashing, then badness for everyone.
10177                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10178                        app.info.processName);
10179                if (!app.isolated) {
10180                    // XXX We don't have a way to mark isolated processes
10181                    // as bad, since they don't have a peristent identity.
10182                    mBadProcesses.put(app.info.processName, app.uid,
10183                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10184                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10185                }
10186                app.bad = true;
10187                app.removed = true;
10188                // Don't let services in this process be restarted and potentially
10189                // annoy the user repeatedly.  Unless it is persistent, since those
10190                // processes run critical code.
10191                removeProcessLocked(app, false, false, "crash");
10192                mStackSupervisor.resumeTopActivitiesLocked();
10193                return false;
10194            }
10195            mStackSupervisor.resumeTopActivitiesLocked();
10196        } else {
10197            mStackSupervisor.finishTopRunningActivityLocked(app);
10198        }
10199
10200        // Bump up the crash count of any services currently running in the proc.
10201        for (int i=app.services.size()-1; i>=0; i--) {
10202            // Any services running in the application need to be placed
10203            // back in the pending list.
10204            ServiceRecord sr = app.services.valueAt(i);
10205            sr.crashCount++;
10206        }
10207
10208        // If the crashing process is what we consider to be the "home process" and it has been
10209        // replaced by a third-party app, clear the package preferred activities from packages
10210        // with a home activity running in the process to prevent a repeatedly crashing app
10211        // from blocking the user to manually clear the list.
10212        final ArrayList<ActivityRecord> activities = app.activities;
10213        if (app == mHomeProcess && activities.size() > 0
10214                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10215            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10216                final ActivityRecord r = activities.get(activityNdx);
10217                if (r.isHomeActivity()) {
10218                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10219                    try {
10220                        ActivityThread.getPackageManager()
10221                                .clearPackagePreferredActivities(r.packageName);
10222                    } catch (RemoteException c) {
10223                        // pm is in same process, this will never happen.
10224                    }
10225                }
10226            }
10227        }
10228
10229        if (!app.isolated) {
10230            // XXX Can't keep track of crash times for isolated processes,
10231            // because they don't have a perisistent identity.
10232            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10233        }
10234
10235        return true;
10236    }
10237
10238    void startAppProblemLocked(ProcessRecord app) {
10239        if (app.userId == mCurrentUserId) {
10240            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10241                    mContext, app.info.packageName, app.info.flags);
10242        } else {
10243            // If this app is not running under the current user, then we
10244            // can't give it a report button because that would require
10245            // launching the report UI under a different user.
10246            app.errorReportReceiver = null;
10247        }
10248        skipCurrentReceiverLocked(app);
10249    }
10250
10251    void skipCurrentReceiverLocked(ProcessRecord app) {
10252        for (BroadcastQueue queue : mBroadcastQueues) {
10253            queue.skipCurrentReceiverLocked(app);
10254        }
10255    }
10256
10257    /**
10258     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10259     * The application process will exit immediately after this call returns.
10260     * @param app object of the crashing app, null for the system server
10261     * @param crashInfo describing the exception
10262     */
10263    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10264        ProcessRecord r = findAppProcess(app, "Crash");
10265        final String processName = app == null ? "system_server"
10266                : (r == null ? "unknown" : r.processName);
10267
10268        handleApplicationCrashInner("crash", r, processName, crashInfo);
10269    }
10270
10271    /* Native crash reporting uses this inner version because it needs to be somewhat
10272     * decoupled from the AM-managed cleanup lifecycle
10273     */
10274    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10275            ApplicationErrorReport.CrashInfo crashInfo) {
10276        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10277                UserHandle.getUserId(Binder.getCallingUid()), processName,
10278                r == null ? -1 : r.info.flags,
10279                crashInfo.exceptionClassName,
10280                crashInfo.exceptionMessage,
10281                crashInfo.throwFileName,
10282                crashInfo.throwLineNumber);
10283
10284        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10285
10286        crashApplication(r, crashInfo);
10287    }
10288
10289    public void handleApplicationStrictModeViolation(
10290            IBinder app,
10291            int violationMask,
10292            StrictMode.ViolationInfo info) {
10293        ProcessRecord r = findAppProcess(app, "StrictMode");
10294        if (r == null) {
10295            return;
10296        }
10297
10298        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10299            Integer stackFingerprint = info.hashCode();
10300            boolean logIt = true;
10301            synchronized (mAlreadyLoggedViolatedStacks) {
10302                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10303                    logIt = false;
10304                    // TODO: sub-sample into EventLog for these, with
10305                    // the info.durationMillis?  Then we'd get
10306                    // the relative pain numbers, without logging all
10307                    // the stack traces repeatedly.  We'd want to do
10308                    // likewise in the client code, which also does
10309                    // dup suppression, before the Binder call.
10310                } else {
10311                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10312                        mAlreadyLoggedViolatedStacks.clear();
10313                    }
10314                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10315                }
10316            }
10317            if (logIt) {
10318                logStrictModeViolationToDropBox(r, info);
10319            }
10320        }
10321
10322        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10323            AppErrorResult result = new AppErrorResult();
10324            synchronized (this) {
10325                final long origId = Binder.clearCallingIdentity();
10326
10327                Message msg = Message.obtain();
10328                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10329                HashMap<String, Object> data = new HashMap<String, Object>();
10330                data.put("result", result);
10331                data.put("app", r);
10332                data.put("violationMask", violationMask);
10333                data.put("info", info);
10334                msg.obj = data;
10335                mHandler.sendMessage(msg);
10336
10337                Binder.restoreCallingIdentity(origId);
10338            }
10339            int res = result.get();
10340            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10341        }
10342    }
10343
10344    // Depending on the policy in effect, there could be a bunch of
10345    // these in quick succession so we try to batch these together to
10346    // minimize disk writes, number of dropbox entries, and maximize
10347    // compression, by having more fewer, larger records.
10348    private void logStrictModeViolationToDropBox(
10349            ProcessRecord process,
10350            StrictMode.ViolationInfo info) {
10351        if (info == null) {
10352            return;
10353        }
10354        final boolean isSystemApp = process == null ||
10355                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10356                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10357        final String processName = process == null ? "unknown" : process.processName;
10358        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10359        final DropBoxManager dbox = (DropBoxManager)
10360                mContext.getSystemService(Context.DROPBOX_SERVICE);
10361
10362        // Exit early if the dropbox isn't configured to accept this report type.
10363        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10364
10365        boolean bufferWasEmpty;
10366        boolean needsFlush;
10367        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10368        synchronized (sb) {
10369            bufferWasEmpty = sb.length() == 0;
10370            appendDropBoxProcessHeaders(process, processName, sb);
10371            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10372            sb.append("System-App: ").append(isSystemApp).append("\n");
10373            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10374            if (info.violationNumThisLoop != 0) {
10375                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10376            }
10377            if (info.numAnimationsRunning != 0) {
10378                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10379            }
10380            if (info.broadcastIntentAction != null) {
10381                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10382            }
10383            if (info.durationMillis != -1) {
10384                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10385            }
10386            if (info.numInstances != -1) {
10387                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10388            }
10389            if (info.tags != null) {
10390                for (String tag : info.tags) {
10391                    sb.append("Span-Tag: ").append(tag).append("\n");
10392                }
10393            }
10394            sb.append("\n");
10395            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10396                sb.append(info.crashInfo.stackTrace);
10397            }
10398            sb.append("\n");
10399
10400            // Only buffer up to ~64k.  Various logging bits truncate
10401            // things at 128k.
10402            needsFlush = (sb.length() > 64 * 1024);
10403        }
10404
10405        // Flush immediately if the buffer's grown too large, or this
10406        // is a non-system app.  Non-system apps are isolated with a
10407        // different tag & policy and not batched.
10408        //
10409        // Batching is useful during internal testing with
10410        // StrictMode settings turned up high.  Without batching,
10411        // thousands of separate files could be created on boot.
10412        if (!isSystemApp || needsFlush) {
10413            new Thread("Error dump: " + dropboxTag) {
10414                @Override
10415                public void run() {
10416                    String report;
10417                    synchronized (sb) {
10418                        report = sb.toString();
10419                        sb.delete(0, sb.length());
10420                        sb.trimToSize();
10421                    }
10422                    if (report.length() != 0) {
10423                        dbox.addText(dropboxTag, report);
10424                    }
10425                }
10426            }.start();
10427            return;
10428        }
10429
10430        // System app batching:
10431        if (!bufferWasEmpty) {
10432            // An existing dropbox-writing thread is outstanding, so
10433            // we don't need to start it up.  The existing thread will
10434            // catch the buffer appends we just did.
10435            return;
10436        }
10437
10438        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10439        // (After this point, we shouldn't access AMS internal data structures.)
10440        new Thread("Error dump: " + dropboxTag) {
10441            @Override
10442            public void run() {
10443                // 5 second sleep to let stacks arrive and be batched together
10444                try {
10445                    Thread.sleep(5000);  // 5 seconds
10446                } catch (InterruptedException e) {}
10447
10448                String errorReport;
10449                synchronized (mStrictModeBuffer) {
10450                    errorReport = mStrictModeBuffer.toString();
10451                    if (errorReport.length() == 0) {
10452                        return;
10453                    }
10454                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10455                    mStrictModeBuffer.trimToSize();
10456                }
10457                dbox.addText(dropboxTag, errorReport);
10458            }
10459        }.start();
10460    }
10461
10462    /**
10463     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10464     * @param app object of the crashing app, null for the system server
10465     * @param tag reported by the caller
10466     * @param crashInfo describing the context of the error
10467     * @return true if the process should exit immediately (WTF is fatal)
10468     */
10469    public boolean handleApplicationWtf(IBinder app, String tag,
10470            ApplicationErrorReport.CrashInfo crashInfo) {
10471        ProcessRecord r = findAppProcess(app, "WTF");
10472        final String processName = app == null ? "system_server"
10473                : (r == null ? "unknown" : r.processName);
10474
10475        EventLog.writeEvent(EventLogTags.AM_WTF,
10476                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10477                processName,
10478                r == null ? -1 : r.info.flags,
10479                tag, crashInfo.exceptionMessage);
10480
10481        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10482
10483        if (r != null && r.pid != Process.myPid() &&
10484                Settings.Global.getInt(mContext.getContentResolver(),
10485                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10486            crashApplication(r, crashInfo);
10487            return true;
10488        } else {
10489            return false;
10490        }
10491    }
10492
10493    /**
10494     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10495     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10496     */
10497    private ProcessRecord findAppProcess(IBinder app, String reason) {
10498        if (app == null) {
10499            return null;
10500        }
10501
10502        synchronized (this) {
10503            final int NP = mProcessNames.getMap().size();
10504            for (int ip=0; ip<NP; ip++) {
10505                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10506                final int NA = apps.size();
10507                for (int ia=0; ia<NA; ia++) {
10508                    ProcessRecord p = apps.valueAt(ia);
10509                    if (p.thread != null && p.thread.asBinder() == app) {
10510                        return p;
10511                    }
10512                }
10513            }
10514
10515            Slog.w(TAG, "Can't find mystery application for " + reason
10516                    + " from pid=" + Binder.getCallingPid()
10517                    + " uid=" + Binder.getCallingUid() + ": " + app);
10518            return null;
10519        }
10520    }
10521
10522    /**
10523     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10524     * to append various headers to the dropbox log text.
10525     */
10526    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10527            StringBuilder sb) {
10528        // Watchdog thread ends up invoking this function (with
10529        // a null ProcessRecord) to add the stack file to dropbox.
10530        // Do not acquire a lock on this (am) in such cases, as it
10531        // could cause a potential deadlock, if and when watchdog
10532        // is invoked due to unavailability of lock on am and it
10533        // would prevent watchdog from killing system_server.
10534        if (process == null) {
10535            sb.append("Process: ").append(processName).append("\n");
10536            return;
10537        }
10538        // Note: ProcessRecord 'process' is guarded by the service
10539        // instance.  (notably process.pkgList, which could otherwise change
10540        // concurrently during execution of this method)
10541        synchronized (this) {
10542            sb.append("Process: ").append(processName).append("\n");
10543            int flags = process.info.flags;
10544            IPackageManager pm = AppGlobals.getPackageManager();
10545            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10546            for (int ip=0; ip<process.pkgList.size(); ip++) {
10547                String pkg = process.pkgList.keyAt(ip);
10548                sb.append("Package: ").append(pkg);
10549                try {
10550                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10551                    if (pi != null) {
10552                        sb.append(" v").append(pi.versionCode);
10553                        if (pi.versionName != null) {
10554                            sb.append(" (").append(pi.versionName).append(")");
10555                        }
10556                    }
10557                } catch (RemoteException e) {
10558                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10559                }
10560                sb.append("\n");
10561            }
10562        }
10563    }
10564
10565    private static String processClass(ProcessRecord process) {
10566        if (process == null || process.pid == MY_PID) {
10567            return "system_server";
10568        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10569            return "system_app";
10570        } else {
10571            return "data_app";
10572        }
10573    }
10574
10575    /**
10576     * Write a description of an error (crash, WTF, ANR) to the drop box.
10577     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10578     * @param process which caused the error, null means the system server
10579     * @param activity which triggered the error, null if unknown
10580     * @param parent activity related to the error, null if unknown
10581     * @param subject line related to the error, null if absent
10582     * @param report in long form describing the error, null if absent
10583     * @param logFile to include in the report, null if none
10584     * @param crashInfo giving an application stack trace, null if absent
10585     */
10586    public void addErrorToDropBox(String eventType,
10587            ProcessRecord process, String processName, ActivityRecord activity,
10588            ActivityRecord parent, String subject,
10589            final String report, final File logFile,
10590            final ApplicationErrorReport.CrashInfo crashInfo) {
10591        // NOTE -- this must never acquire the ActivityManagerService lock,
10592        // otherwise the watchdog may be prevented from resetting the system.
10593
10594        final String dropboxTag = processClass(process) + "_" + eventType;
10595        final DropBoxManager dbox = (DropBoxManager)
10596                mContext.getSystemService(Context.DROPBOX_SERVICE);
10597
10598        // Exit early if the dropbox isn't configured to accept this report type.
10599        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10600
10601        final StringBuilder sb = new StringBuilder(1024);
10602        appendDropBoxProcessHeaders(process, processName, sb);
10603        if (activity != null) {
10604            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10605        }
10606        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10607            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10608        }
10609        if (parent != null && parent != activity) {
10610            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10611        }
10612        if (subject != null) {
10613            sb.append("Subject: ").append(subject).append("\n");
10614        }
10615        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10616        if (Debug.isDebuggerConnected()) {
10617            sb.append("Debugger: Connected\n");
10618        }
10619        sb.append("\n");
10620
10621        // Do the rest in a worker thread to avoid blocking the caller on I/O
10622        // (After this point, we shouldn't access AMS internal data structures.)
10623        Thread worker = new Thread("Error dump: " + dropboxTag) {
10624            @Override
10625            public void run() {
10626                if (report != null) {
10627                    sb.append(report);
10628                }
10629                if (logFile != null) {
10630                    try {
10631                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10632                                    "\n\n[[TRUNCATED]]"));
10633                    } catch (IOException e) {
10634                        Slog.e(TAG, "Error reading " + logFile, e);
10635                    }
10636                }
10637                if (crashInfo != null && crashInfo.stackTrace != null) {
10638                    sb.append(crashInfo.stackTrace);
10639                }
10640
10641                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10642                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10643                if (lines > 0) {
10644                    sb.append("\n");
10645
10646                    // Merge several logcat streams, and take the last N lines
10647                    InputStreamReader input = null;
10648                    try {
10649                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10650                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10651                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10652
10653                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10654                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10655                        input = new InputStreamReader(logcat.getInputStream());
10656
10657                        int num;
10658                        char[] buf = new char[8192];
10659                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10660                    } catch (IOException e) {
10661                        Slog.e(TAG, "Error running logcat", e);
10662                    } finally {
10663                        if (input != null) try { input.close(); } catch (IOException e) {}
10664                    }
10665                }
10666
10667                dbox.addText(dropboxTag, sb.toString());
10668            }
10669        };
10670
10671        if (process == null) {
10672            // If process is null, we are being called from some internal code
10673            // and may be about to die -- run this synchronously.
10674            worker.run();
10675        } else {
10676            worker.start();
10677        }
10678    }
10679
10680    /**
10681     * Bring up the "unexpected error" dialog box for a crashing app.
10682     * Deal with edge cases (intercepts from instrumented applications,
10683     * ActivityController, error intent receivers, that sort of thing).
10684     * @param r the application crashing
10685     * @param crashInfo describing the failure
10686     */
10687    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10688        long timeMillis = System.currentTimeMillis();
10689        String shortMsg = crashInfo.exceptionClassName;
10690        String longMsg = crashInfo.exceptionMessage;
10691        String stackTrace = crashInfo.stackTrace;
10692        if (shortMsg != null && longMsg != null) {
10693            longMsg = shortMsg + ": " + longMsg;
10694        } else if (shortMsg != null) {
10695            longMsg = shortMsg;
10696        }
10697
10698        AppErrorResult result = new AppErrorResult();
10699        synchronized (this) {
10700            if (mController != null) {
10701                try {
10702                    String name = r != null ? r.processName : null;
10703                    int pid = r != null ? r.pid : Binder.getCallingPid();
10704                    if (!mController.appCrashed(name, pid,
10705                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10706                        Slog.w(TAG, "Force-killing crashed app " + name
10707                                + " at watcher's request");
10708                        Process.killProcess(pid);
10709                        return;
10710                    }
10711                } catch (RemoteException e) {
10712                    mController = null;
10713                    Watchdog.getInstance().setActivityController(null);
10714                }
10715            }
10716
10717            final long origId = Binder.clearCallingIdentity();
10718
10719            // If this process is running instrumentation, finish it.
10720            if (r != null && r.instrumentationClass != null) {
10721                Slog.w(TAG, "Error in app " + r.processName
10722                      + " running instrumentation " + r.instrumentationClass + ":");
10723                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10724                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10725                Bundle info = new Bundle();
10726                info.putString("shortMsg", shortMsg);
10727                info.putString("longMsg", longMsg);
10728                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10729                Binder.restoreCallingIdentity(origId);
10730                return;
10731            }
10732
10733            // If we can't identify the process or it's already exceeded its crash quota,
10734            // quit right away without showing a crash dialog.
10735            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10736                Binder.restoreCallingIdentity(origId);
10737                return;
10738            }
10739
10740            Message msg = Message.obtain();
10741            msg.what = SHOW_ERROR_MSG;
10742            HashMap data = new HashMap();
10743            data.put("result", result);
10744            data.put("app", r);
10745            msg.obj = data;
10746            mHandler.sendMessage(msg);
10747
10748            Binder.restoreCallingIdentity(origId);
10749        }
10750
10751        int res = result.get();
10752
10753        Intent appErrorIntent = null;
10754        synchronized (this) {
10755            if (r != null && !r.isolated) {
10756                // XXX Can't keep track of crash time for isolated processes,
10757                // since they don't have a persistent identity.
10758                mProcessCrashTimes.put(r.info.processName, r.uid,
10759                        SystemClock.uptimeMillis());
10760            }
10761            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10762                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10763            }
10764        }
10765
10766        if (appErrorIntent != null) {
10767            try {
10768                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10769            } catch (ActivityNotFoundException e) {
10770                Slog.w(TAG, "bug report receiver dissappeared", e);
10771            }
10772        }
10773    }
10774
10775    Intent createAppErrorIntentLocked(ProcessRecord r,
10776            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10777        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10778        if (report == null) {
10779            return null;
10780        }
10781        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10782        result.setComponent(r.errorReportReceiver);
10783        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10784        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10785        return result;
10786    }
10787
10788    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10789            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10790        if (r.errorReportReceiver == null) {
10791            return null;
10792        }
10793
10794        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10795            return null;
10796        }
10797
10798        ApplicationErrorReport report = new ApplicationErrorReport();
10799        report.packageName = r.info.packageName;
10800        report.installerPackageName = r.errorReportReceiver.getPackageName();
10801        report.processName = r.processName;
10802        report.time = timeMillis;
10803        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10804
10805        if (r.crashing || r.forceCrashReport) {
10806            report.type = ApplicationErrorReport.TYPE_CRASH;
10807            report.crashInfo = crashInfo;
10808        } else if (r.notResponding) {
10809            report.type = ApplicationErrorReport.TYPE_ANR;
10810            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10811
10812            report.anrInfo.activity = r.notRespondingReport.tag;
10813            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10814            report.anrInfo.info = r.notRespondingReport.longMsg;
10815        }
10816
10817        return report;
10818    }
10819
10820    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10821        enforceNotIsolatedCaller("getProcessesInErrorState");
10822        // assume our apps are happy - lazy create the list
10823        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10824
10825        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10826                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10827        int userId = UserHandle.getUserId(Binder.getCallingUid());
10828
10829        synchronized (this) {
10830
10831            // iterate across all processes
10832            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10833                ProcessRecord app = mLruProcesses.get(i);
10834                if (!allUsers && app.userId != userId) {
10835                    continue;
10836                }
10837                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10838                    // This one's in trouble, so we'll generate a report for it
10839                    // crashes are higher priority (in case there's a crash *and* an anr)
10840                    ActivityManager.ProcessErrorStateInfo report = null;
10841                    if (app.crashing) {
10842                        report = app.crashingReport;
10843                    } else if (app.notResponding) {
10844                        report = app.notRespondingReport;
10845                    }
10846
10847                    if (report != null) {
10848                        if (errList == null) {
10849                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10850                        }
10851                        errList.add(report);
10852                    } else {
10853                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10854                                " crashing = " + app.crashing +
10855                                " notResponding = " + app.notResponding);
10856                    }
10857                }
10858            }
10859        }
10860
10861        return errList;
10862    }
10863
10864    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10865        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10866            if (currApp != null) {
10867                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10868            }
10869            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10870        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10871            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10872        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10873            if (currApp != null) {
10874                currApp.lru = 0;
10875            }
10876            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10877        } else if (adj >= ProcessList.SERVICE_ADJ) {
10878            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10879        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10880            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10881        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10882            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10883        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10884            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10885        } else {
10886            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10887        }
10888    }
10889
10890    private void fillInProcMemInfo(ProcessRecord app,
10891            ActivityManager.RunningAppProcessInfo outInfo) {
10892        outInfo.pid = app.pid;
10893        outInfo.uid = app.info.uid;
10894        if (mHeavyWeightProcess == app) {
10895            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10896        }
10897        if (app.persistent) {
10898            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10899        }
10900        if (app.activities.size() > 0) {
10901            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10902        }
10903        outInfo.lastTrimLevel = app.trimMemoryLevel;
10904        int adj = app.curAdj;
10905        outInfo.importance = oomAdjToImportance(adj, outInfo);
10906        outInfo.importanceReasonCode = app.adjTypeCode;
10907        outInfo.processState = app.curProcState;
10908    }
10909
10910    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10911        enforceNotIsolatedCaller("getRunningAppProcesses");
10912        // Lazy instantiation of list
10913        List<ActivityManager.RunningAppProcessInfo> runList = null;
10914        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10915                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10916        int userId = UserHandle.getUserId(Binder.getCallingUid());
10917        synchronized (this) {
10918            // Iterate across all processes
10919            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10920                ProcessRecord app = mLruProcesses.get(i);
10921                if (!allUsers && app.userId != userId) {
10922                    continue;
10923                }
10924                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10925                    // Generate process state info for running application
10926                    ActivityManager.RunningAppProcessInfo currApp =
10927                        new ActivityManager.RunningAppProcessInfo(app.processName,
10928                                app.pid, app.getPackageList());
10929                    fillInProcMemInfo(app, currApp);
10930                    if (app.adjSource instanceof ProcessRecord) {
10931                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10932                        currApp.importanceReasonImportance = oomAdjToImportance(
10933                                app.adjSourceOom, null);
10934                    } else if (app.adjSource instanceof ActivityRecord) {
10935                        ActivityRecord r = (ActivityRecord)app.adjSource;
10936                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10937                    }
10938                    if (app.adjTarget instanceof ComponentName) {
10939                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10940                    }
10941                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10942                    //        + " lru=" + currApp.lru);
10943                    if (runList == null) {
10944                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10945                    }
10946                    runList.add(currApp);
10947                }
10948            }
10949        }
10950        return runList;
10951    }
10952
10953    public List<ApplicationInfo> getRunningExternalApplications() {
10954        enforceNotIsolatedCaller("getRunningExternalApplications");
10955        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10956        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10957        if (runningApps != null && runningApps.size() > 0) {
10958            Set<String> extList = new HashSet<String>();
10959            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10960                if (app.pkgList != null) {
10961                    for (String pkg : app.pkgList) {
10962                        extList.add(pkg);
10963                    }
10964                }
10965            }
10966            IPackageManager pm = AppGlobals.getPackageManager();
10967            for (String pkg : extList) {
10968                try {
10969                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10970                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10971                        retList.add(info);
10972                    }
10973                } catch (RemoteException e) {
10974                }
10975            }
10976        }
10977        return retList;
10978    }
10979
10980    @Override
10981    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10982        enforceNotIsolatedCaller("getMyMemoryState");
10983        synchronized (this) {
10984            ProcessRecord proc;
10985            synchronized (mPidsSelfLocked) {
10986                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10987            }
10988            fillInProcMemInfo(proc, outInfo);
10989        }
10990    }
10991
10992    @Override
10993    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10994        if (checkCallingPermission(android.Manifest.permission.DUMP)
10995                != PackageManager.PERMISSION_GRANTED) {
10996            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10997                    + Binder.getCallingPid()
10998                    + ", uid=" + Binder.getCallingUid()
10999                    + " without permission "
11000                    + android.Manifest.permission.DUMP);
11001            return;
11002        }
11003
11004        boolean dumpAll = false;
11005        boolean dumpClient = false;
11006        String dumpPackage = null;
11007
11008        int opti = 0;
11009        while (opti < args.length) {
11010            String opt = args[opti];
11011            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11012                break;
11013            }
11014            opti++;
11015            if ("-a".equals(opt)) {
11016                dumpAll = true;
11017            } else if ("-c".equals(opt)) {
11018                dumpClient = true;
11019            } else if ("-h".equals(opt)) {
11020                pw.println("Activity manager dump options:");
11021                pw.println("  [-a] [-c] [-h] [cmd] ...");
11022                pw.println("  cmd may be one of:");
11023                pw.println("    a[ctivities]: activity stack state");
11024                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11025                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11026                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11027                pw.println("    o[om]: out of memory management");
11028                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11029                pw.println("    provider [COMP_SPEC]: provider client-side state");
11030                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11031                pw.println("    service [COMP_SPEC]: service client-side state");
11032                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11033                pw.println("    all: dump all activities");
11034                pw.println("    top: dump the top activity");
11035                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11036                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11037                pw.println("    a partial substring in a component name, a");
11038                pw.println("    hex object identifier.");
11039                pw.println("  -a: include all available server state.");
11040                pw.println("  -c: include client state.");
11041                return;
11042            } else {
11043                pw.println("Unknown argument: " + opt + "; use -h for help");
11044            }
11045        }
11046
11047        long origId = Binder.clearCallingIdentity();
11048        boolean more = false;
11049        // Is the caller requesting to dump a particular piece of data?
11050        if (opti < args.length) {
11051            String cmd = args[opti];
11052            opti++;
11053            if ("activities".equals(cmd) || "a".equals(cmd)) {
11054                synchronized (this) {
11055                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11056                }
11057            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11058                String[] newArgs;
11059                String name;
11060                if (opti >= args.length) {
11061                    name = null;
11062                    newArgs = EMPTY_STRING_ARRAY;
11063                } else {
11064                    name = args[opti];
11065                    opti++;
11066                    newArgs = new String[args.length - opti];
11067                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11068                            args.length - opti);
11069                }
11070                synchronized (this) {
11071                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11072                }
11073            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11074                String[] newArgs;
11075                String name;
11076                if (opti >= args.length) {
11077                    name = null;
11078                    newArgs = EMPTY_STRING_ARRAY;
11079                } else {
11080                    name = args[opti];
11081                    opti++;
11082                    newArgs = new String[args.length - opti];
11083                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11084                            args.length - opti);
11085                }
11086                synchronized (this) {
11087                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11088                }
11089            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11090                String[] newArgs;
11091                String name;
11092                if (opti >= args.length) {
11093                    name = null;
11094                    newArgs = EMPTY_STRING_ARRAY;
11095                } else {
11096                    name = args[opti];
11097                    opti++;
11098                    newArgs = new String[args.length - opti];
11099                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11100                            args.length - opti);
11101                }
11102                synchronized (this) {
11103                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11104                }
11105            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11106                synchronized (this) {
11107                    dumpOomLocked(fd, pw, args, opti, true);
11108                }
11109            } else if ("provider".equals(cmd)) {
11110                String[] newArgs;
11111                String name;
11112                if (opti >= args.length) {
11113                    name = null;
11114                    newArgs = EMPTY_STRING_ARRAY;
11115                } else {
11116                    name = args[opti];
11117                    opti++;
11118                    newArgs = new String[args.length - opti];
11119                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11120                }
11121                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11122                    pw.println("No providers match: " + name);
11123                    pw.println("Use -h for help.");
11124                }
11125            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11126                synchronized (this) {
11127                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11128                }
11129            } else if ("service".equals(cmd)) {
11130                String[] newArgs;
11131                String name;
11132                if (opti >= args.length) {
11133                    name = null;
11134                    newArgs = EMPTY_STRING_ARRAY;
11135                } else {
11136                    name = args[opti];
11137                    opti++;
11138                    newArgs = new String[args.length - opti];
11139                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11140                            args.length - opti);
11141                }
11142                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11143                    pw.println("No services match: " + name);
11144                    pw.println("Use -h for help.");
11145                }
11146            } else if ("package".equals(cmd)) {
11147                String[] newArgs;
11148                if (opti >= args.length) {
11149                    pw.println("package: no package name specified");
11150                    pw.println("Use -h for help.");
11151                } else {
11152                    dumpPackage = args[opti];
11153                    opti++;
11154                    newArgs = new String[args.length - opti];
11155                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11156                            args.length - opti);
11157                    args = newArgs;
11158                    opti = 0;
11159                    more = true;
11160                }
11161            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11162                synchronized (this) {
11163                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11164                }
11165            } else {
11166                // Dumping a single activity?
11167                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11168                    pw.println("Bad activity command, or no activities match: " + cmd);
11169                    pw.println("Use -h for help.");
11170                }
11171            }
11172            if (!more) {
11173                Binder.restoreCallingIdentity(origId);
11174                return;
11175            }
11176        }
11177
11178        // No piece of data specified, dump everything.
11179        synchronized (this) {
11180            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11181            pw.println();
11182            if (dumpAll) {
11183                pw.println("-------------------------------------------------------------------------------");
11184            }
11185            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11186            pw.println();
11187            if (dumpAll) {
11188                pw.println("-------------------------------------------------------------------------------");
11189            }
11190            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11191            pw.println();
11192            if (dumpAll) {
11193                pw.println("-------------------------------------------------------------------------------");
11194            }
11195            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11196            pw.println();
11197            if (dumpAll) {
11198                pw.println("-------------------------------------------------------------------------------");
11199            }
11200            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11201            pw.println();
11202            if (dumpAll) {
11203                pw.println("-------------------------------------------------------------------------------");
11204            }
11205            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11206        }
11207        Binder.restoreCallingIdentity(origId);
11208    }
11209
11210    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11211            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11212        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11213
11214        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11215                dumpPackage);
11216        boolean needSep = printedAnything;
11217
11218        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11219                dumpPackage, needSep, "  mFocusedActivity: ");
11220        if (printed) {
11221            printedAnything = true;
11222            needSep = false;
11223        }
11224
11225        if (dumpPackage == null) {
11226            if (needSep) {
11227                pw.println();
11228            }
11229            needSep = true;
11230            printedAnything = true;
11231            mStackSupervisor.dump(pw, "  ");
11232        }
11233
11234        if (mRecentTasks.size() > 0) {
11235            boolean printedHeader = false;
11236
11237            final int N = mRecentTasks.size();
11238            for (int i=0; i<N; i++) {
11239                TaskRecord tr = mRecentTasks.get(i);
11240                if (dumpPackage != null) {
11241                    if (tr.realActivity == null ||
11242                            !dumpPackage.equals(tr.realActivity)) {
11243                        continue;
11244                    }
11245                }
11246                if (!printedHeader) {
11247                    if (needSep) {
11248                        pw.println();
11249                    }
11250                    pw.println("  Recent tasks:");
11251                    printedHeader = true;
11252                    printedAnything = true;
11253                }
11254                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11255                        pw.println(tr);
11256                if (dumpAll) {
11257                    mRecentTasks.get(i).dump(pw, "    ");
11258                }
11259            }
11260        }
11261
11262        if (!printedAnything) {
11263            pw.println("  (nothing)");
11264        }
11265    }
11266
11267    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11268            int opti, boolean dumpAll, String dumpPackage) {
11269        boolean needSep = false;
11270        boolean printedAnything = false;
11271        int numPers = 0;
11272
11273        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11274
11275        if (dumpAll) {
11276            final int NP = mProcessNames.getMap().size();
11277            for (int ip=0; ip<NP; ip++) {
11278                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11279                final int NA = procs.size();
11280                for (int ia=0; ia<NA; ia++) {
11281                    ProcessRecord r = procs.valueAt(ia);
11282                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11283                        continue;
11284                    }
11285                    if (!needSep) {
11286                        pw.println("  All known processes:");
11287                        needSep = true;
11288                        printedAnything = true;
11289                    }
11290                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11291                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11292                        pw.print(" "); pw.println(r);
11293                    r.dump(pw, "    ");
11294                    if (r.persistent) {
11295                        numPers++;
11296                    }
11297                }
11298            }
11299        }
11300
11301        if (mIsolatedProcesses.size() > 0) {
11302            boolean printed = false;
11303            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11304                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11305                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11306                    continue;
11307                }
11308                if (!printed) {
11309                    if (needSep) {
11310                        pw.println();
11311                    }
11312                    pw.println("  Isolated process list (sorted by uid):");
11313                    printedAnything = true;
11314                    printed = true;
11315                    needSep = true;
11316                }
11317                pw.println(String.format("%sIsolated #%2d: %s",
11318                        "    ", i, r.toString()));
11319            }
11320        }
11321
11322        if (mLruProcesses.size() > 0) {
11323            if (needSep) {
11324                pw.println();
11325            }
11326            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11327                    pw.print(" total, non-act at ");
11328                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11329                    pw.print(", non-svc at ");
11330                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11331                    pw.println("):");
11332            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11333            needSep = true;
11334            printedAnything = true;
11335        }
11336
11337        if (dumpAll || dumpPackage != null) {
11338            synchronized (mPidsSelfLocked) {
11339                boolean printed = false;
11340                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11341                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11342                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11343                        continue;
11344                    }
11345                    if (!printed) {
11346                        if (needSep) pw.println();
11347                        needSep = true;
11348                        pw.println("  PID mappings:");
11349                        printed = true;
11350                        printedAnything = true;
11351                    }
11352                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11353                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11354                }
11355            }
11356        }
11357
11358        if (mForegroundProcesses.size() > 0) {
11359            synchronized (mPidsSelfLocked) {
11360                boolean printed = false;
11361                for (int i=0; i<mForegroundProcesses.size(); i++) {
11362                    ProcessRecord r = mPidsSelfLocked.get(
11363                            mForegroundProcesses.valueAt(i).pid);
11364                    if (dumpPackage != null && (r == null
11365                            || !r.pkgList.containsKey(dumpPackage))) {
11366                        continue;
11367                    }
11368                    if (!printed) {
11369                        if (needSep) pw.println();
11370                        needSep = true;
11371                        pw.println("  Foreground Processes:");
11372                        printed = true;
11373                        printedAnything = true;
11374                    }
11375                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11376                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11377                }
11378            }
11379        }
11380
11381        if (mPersistentStartingProcesses.size() > 0) {
11382            if (needSep) pw.println();
11383            needSep = true;
11384            printedAnything = true;
11385            pw.println("  Persisent processes that are starting:");
11386            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11387                    "Starting Norm", "Restarting PERS", dumpPackage);
11388        }
11389
11390        if (mRemovedProcesses.size() > 0) {
11391            if (needSep) pw.println();
11392            needSep = true;
11393            printedAnything = true;
11394            pw.println("  Processes that are being removed:");
11395            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11396                    "Removed Norm", "Removed PERS", dumpPackage);
11397        }
11398
11399        if (mProcessesOnHold.size() > 0) {
11400            if (needSep) pw.println();
11401            needSep = true;
11402            printedAnything = true;
11403            pw.println("  Processes that are on old until the system is ready:");
11404            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11405                    "OnHold Norm", "OnHold PERS", dumpPackage);
11406        }
11407
11408        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11409
11410        if (mProcessCrashTimes.getMap().size() > 0) {
11411            boolean printed = false;
11412            long now = SystemClock.uptimeMillis();
11413            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11414            final int NP = pmap.size();
11415            for (int ip=0; ip<NP; ip++) {
11416                String pname = pmap.keyAt(ip);
11417                SparseArray<Long> uids = pmap.valueAt(ip);
11418                final int N = uids.size();
11419                for (int i=0; i<N; i++) {
11420                    int puid = uids.keyAt(i);
11421                    ProcessRecord r = mProcessNames.get(pname, puid);
11422                    if (dumpPackage != null && (r == null
11423                            || !r.pkgList.containsKey(dumpPackage))) {
11424                        continue;
11425                    }
11426                    if (!printed) {
11427                        if (needSep) pw.println();
11428                        needSep = true;
11429                        pw.println("  Time since processes crashed:");
11430                        printed = true;
11431                        printedAnything = true;
11432                    }
11433                    pw.print("    Process "); pw.print(pname);
11434                            pw.print(" uid "); pw.print(puid);
11435                            pw.print(": last crashed ");
11436                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11437                            pw.println(" ago");
11438                }
11439            }
11440        }
11441
11442        if (mBadProcesses.getMap().size() > 0) {
11443            boolean printed = false;
11444            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11445            final int NP = pmap.size();
11446            for (int ip=0; ip<NP; ip++) {
11447                String pname = pmap.keyAt(ip);
11448                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11449                final int N = uids.size();
11450                for (int i=0; i<N; i++) {
11451                    int puid = uids.keyAt(i);
11452                    ProcessRecord r = mProcessNames.get(pname, puid);
11453                    if (dumpPackage != null && (r == null
11454                            || !r.pkgList.containsKey(dumpPackage))) {
11455                        continue;
11456                    }
11457                    if (!printed) {
11458                        if (needSep) pw.println();
11459                        needSep = true;
11460                        pw.println("  Bad processes:");
11461                        printedAnything = true;
11462                    }
11463                    BadProcessInfo info = uids.valueAt(i);
11464                    pw.print("    Bad process "); pw.print(pname);
11465                            pw.print(" uid "); pw.print(puid);
11466                            pw.print(": crashed at time "); pw.println(info.time);
11467                    if (info.shortMsg != null) {
11468                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11469                    }
11470                    if (info.longMsg != null) {
11471                        pw.print("      Long msg: "); pw.println(info.longMsg);
11472                    }
11473                    if (info.stack != null) {
11474                        pw.println("      Stack:");
11475                        int lastPos = 0;
11476                        for (int pos=0; pos<info.stack.length(); pos++) {
11477                            if (info.stack.charAt(pos) == '\n') {
11478                                pw.print("        ");
11479                                pw.write(info.stack, lastPos, pos-lastPos);
11480                                pw.println();
11481                                lastPos = pos+1;
11482                            }
11483                        }
11484                        if (lastPos < info.stack.length()) {
11485                            pw.print("        ");
11486                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11487                            pw.println();
11488                        }
11489                    }
11490                }
11491            }
11492        }
11493
11494        if (dumpPackage == null) {
11495            pw.println();
11496            needSep = false;
11497            pw.println("  mStartedUsers:");
11498            for (int i=0; i<mStartedUsers.size(); i++) {
11499                UserStartedState uss = mStartedUsers.valueAt(i);
11500                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11501                        pw.print(": "); uss.dump("", pw);
11502            }
11503            pw.print("  mStartedUserArray: [");
11504            for (int i=0; i<mStartedUserArray.length; i++) {
11505                if (i > 0) pw.print(", ");
11506                pw.print(mStartedUserArray[i]);
11507            }
11508            pw.println("]");
11509            pw.print("  mUserLru: [");
11510            for (int i=0; i<mUserLru.size(); i++) {
11511                if (i > 0) pw.print(", ");
11512                pw.print(mUserLru.get(i));
11513            }
11514            pw.println("]");
11515            if (dumpAll) {
11516                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11517            }
11518        }
11519        if (mHomeProcess != null && (dumpPackage == null
11520                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11521            if (needSep) {
11522                pw.println();
11523                needSep = false;
11524            }
11525            pw.println("  mHomeProcess: " + mHomeProcess);
11526        }
11527        if (mPreviousProcess != null && (dumpPackage == null
11528                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11529            if (needSep) {
11530                pw.println();
11531                needSep = false;
11532            }
11533            pw.println("  mPreviousProcess: " + mPreviousProcess);
11534        }
11535        if (dumpAll) {
11536            StringBuilder sb = new StringBuilder(128);
11537            sb.append("  mPreviousProcessVisibleTime: ");
11538            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11539            pw.println(sb);
11540        }
11541        if (mHeavyWeightProcess != null && (dumpPackage == null
11542                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11543            if (needSep) {
11544                pw.println();
11545                needSep = false;
11546            }
11547            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11548        }
11549        if (dumpPackage == null) {
11550            pw.println("  mConfiguration: " + mConfiguration);
11551        }
11552        if (dumpAll) {
11553            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11554            if (mCompatModePackages.getPackages().size() > 0) {
11555                boolean printed = false;
11556                for (Map.Entry<String, Integer> entry
11557                        : mCompatModePackages.getPackages().entrySet()) {
11558                    String pkg = entry.getKey();
11559                    int mode = entry.getValue();
11560                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11561                        continue;
11562                    }
11563                    if (!printed) {
11564                        pw.println("  mScreenCompatPackages:");
11565                        printed = true;
11566                    }
11567                    pw.print("    "); pw.print(pkg); pw.print(": ");
11568                            pw.print(mode); pw.println();
11569                }
11570            }
11571        }
11572        if (dumpPackage == null) {
11573            if (mSleeping || mWentToSleep || mLockScreenShown) {
11574                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11575                        + " mLockScreenShown " + mLockScreenShown);
11576            }
11577            if (mShuttingDown || mRunningVoice) {
11578                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11579            }
11580        }
11581        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11582                || mOrigWaitForDebugger) {
11583            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11584                    || dumpPackage.equals(mOrigDebugApp)) {
11585                if (needSep) {
11586                    pw.println();
11587                    needSep = false;
11588                }
11589                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11590                        + " mDebugTransient=" + mDebugTransient
11591                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11592            }
11593        }
11594        if (mOpenGlTraceApp != null) {
11595            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11596                if (needSep) {
11597                    pw.println();
11598                    needSep = false;
11599                }
11600                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11601            }
11602        }
11603        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11604                || mProfileFd != null) {
11605            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11606                if (needSep) {
11607                    pw.println();
11608                    needSep = false;
11609                }
11610                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11611                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11612                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11613                        + mAutoStopProfiler);
11614            }
11615        }
11616        if (dumpPackage == null) {
11617            if (mAlwaysFinishActivities || mController != null) {
11618                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11619                        + " mController=" + mController);
11620            }
11621            if (dumpAll) {
11622                pw.println("  Total persistent processes: " + numPers);
11623                pw.println("  mProcessesReady=" + mProcessesReady
11624                        + " mSystemReady=" + mSystemReady);
11625                pw.println("  mBooting=" + mBooting
11626                        + " mBooted=" + mBooted
11627                        + " mFactoryTest=" + mFactoryTest);
11628                pw.print("  mLastPowerCheckRealtime=");
11629                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11630                        pw.println("");
11631                pw.print("  mLastPowerCheckUptime=");
11632                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11633                        pw.println("");
11634                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11635                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11636                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11637                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11638                        + " (" + mLruProcesses.size() + " total)"
11639                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11640                        + " mNumServiceProcs=" + mNumServiceProcs
11641                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11642                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11643                        + " mLastMemoryLevel" + mLastMemoryLevel
11644                        + " mLastNumProcesses" + mLastNumProcesses);
11645                long now = SystemClock.uptimeMillis();
11646                pw.print("  mLastIdleTime=");
11647                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11648                        pw.print(" mLowRamSinceLastIdle=");
11649                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11650                        pw.println();
11651            }
11652        }
11653
11654        if (!printedAnything) {
11655            pw.println("  (nothing)");
11656        }
11657    }
11658
11659    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11660            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11661        if (mProcessesToGc.size() > 0) {
11662            boolean printed = false;
11663            long now = SystemClock.uptimeMillis();
11664            for (int i=0; i<mProcessesToGc.size(); i++) {
11665                ProcessRecord proc = mProcessesToGc.get(i);
11666                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11667                    continue;
11668                }
11669                if (!printed) {
11670                    if (needSep) pw.println();
11671                    needSep = true;
11672                    pw.println("  Processes that are waiting to GC:");
11673                    printed = true;
11674                }
11675                pw.print("    Process "); pw.println(proc);
11676                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11677                        pw.print(", last gced=");
11678                        pw.print(now-proc.lastRequestedGc);
11679                        pw.print(" ms ago, last lowMem=");
11680                        pw.print(now-proc.lastLowMemory);
11681                        pw.println(" ms ago");
11682
11683            }
11684        }
11685        return needSep;
11686    }
11687
11688    void printOomLevel(PrintWriter pw, String name, int adj) {
11689        pw.print("    ");
11690        if (adj >= 0) {
11691            pw.print(' ');
11692            if (adj < 10) pw.print(' ');
11693        } else {
11694            if (adj > -10) pw.print(' ');
11695        }
11696        pw.print(adj);
11697        pw.print(": ");
11698        pw.print(name);
11699        pw.print(" (");
11700        pw.print(mProcessList.getMemLevel(adj)/1024);
11701        pw.println(" kB)");
11702    }
11703
11704    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11705            int opti, boolean dumpAll) {
11706        boolean needSep = false;
11707
11708        if (mLruProcesses.size() > 0) {
11709            if (needSep) pw.println();
11710            needSep = true;
11711            pw.println("  OOM levels:");
11712            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11713            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11714            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11715            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11716            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11717            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11718            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11719            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11720            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11721            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11722            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11723            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11724            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11725
11726            if (needSep) pw.println();
11727            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11728                    pw.print(" total, non-act at ");
11729                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11730                    pw.print(", non-svc at ");
11731                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11732                    pw.println("):");
11733            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11734            needSep = true;
11735        }
11736
11737        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11738
11739        pw.println();
11740        pw.println("  mHomeProcess: " + mHomeProcess);
11741        pw.println("  mPreviousProcess: " + mPreviousProcess);
11742        if (mHeavyWeightProcess != null) {
11743            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11744        }
11745
11746        return true;
11747    }
11748
11749    /**
11750     * There are three ways to call this:
11751     *  - no provider specified: dump all the providers
11752     *  - a flattened component name that matched an existing provider was specified as the
11753     *    first arg: dump that one provider
11754     *  - the first arg isn't the flattened component name of an existing provider:
11755     *    dump all providers whose component contains the first arg as a substring
11756     */
11757    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11758            int opti, boolean dumpAll) {
11759        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11760    }
11761
11762    static class ItemMatcher {
11763        ArrayList<ComponentName> components;
11764        ArrayList<String> strings;
11765        ArrayList<Integer> objects;
11766        boolean all;
11767
11768        ItemMatcher() {
11769            all = true;
11770        }
11771
11772        void build(String name) {
11773            ComponentName componentName = ComponentName.unflattenFromString(name);
11774            if (componentName != null) {
11775                if (components == null) {
11776                    components = new ArrayList<ComponentName>();
11777                }
11778                components.add(componentName);
11779                all = false;
11780            } else {
11781                int objectId = 0;
11782                // Not a '/' separated full component name; maybe an object ID?
11783                try {
11784                    objectId = Integer.parseInt(name, 16);
11785                    if (objects == null) {
11786                        objects = new ArrayList<Integer>();
11787                    }
11788                    objects.add(objectId);
11789                    all = false;
11790                } catch (RuntimeException e) {
11791                    // Not an integer; just do string match.
11792                    if (strings == null) {
11793                        strings = new ArrayList<String>();
11794                    }
11795                    strings.add(name);
11796                    all = false;
11797                }
11798            }
11799        }
11800
11801        int build(String[] args, int opti) {
11802            for (; opti<args.length; opti++) {
11803                String name = args[opti];
11804                if ("--".equals(name)) {
11805                    return opti+1;
11806                }
11807                build(name);
11808            }
11809            return opti;
11810        }
11811
11812        boolean match(Object object, ComponentName comp) {
11813            if (all) {
11814                return true;
11815            }
11816            if (components != null) {
11817                for (int i=0; i<components.size(); i++) {
11818                    if (components.get(i).equals(comp)) {
11819                        return true;
11820                    }
11821                }
11822            }
11823            if (objects != null) {
11824                for (int i=0; i<objects.size(); i++) {
11825                    if (System.identityHashCode(object) == objects.get(i)) {
11826                        return true;
11827                    }
11828                }
11829            }
11830            if (strings != null) {
11831                String flat = comp.flattenToString();
11832                for (int i=0; i<strings.size(); i++) {
11833                    if (flat.contains(strings.get(i))) {
11834                        return true;
11835                    }
11836                }
11837            }
11838            return false;
11839        }
11840    }
11841
11842    /**
11843     * There are three things that cmd can be:
11844     *  - a flattened component name that matches an existing activity
11845     *  - the cmd arg isn't the flattened component name of an existing activity:
11846     *    dump all activity whose component contains the cmd as a substring
11847     *  - A hex number of the ActivityRecord object instance.
11848     */
11849    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11850            int opti, boolean dumpAll) {
11851        ArrayList<ActivityRecord> activities;
11852
11853        synchronized (this) {
11854            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11855        }
11856
11857        if (activities.size() <= 0) {
11858            return false;
11859        }
11860
11861        String[] newArgs = new String[args.length - opti];
11862        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11863
11864        TaskRecord lastTask = null;
11865        boolean needSep = false;
11866        for (int i=activities.size()-1; i>=0; i--) {
11867            ActivityRecord r = activities.get(i);
11868            if (needSep) {
11869                pw.println();
11870            }
11871            needSep = true;
11872            synchronized (this) {
11873                if (lastTask != r.task) {
11874                    lastTask = r.task;
11875                    pw.print("TASK "); pw.print(lastTask.affinity);
11876                            pw.print(" id="); pw.println(lastTask.taskId);
11877                    if (dumpAll) {
11878                        lastTask.dump(pw, "  ");
11879                    }
11880                }
11881            }
11882            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11883        }
11884        return true;
11885    }
11886
11887    /**
11888     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11889     * there is a thread associated with the activity.
11890     */
11891    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11892            final ActivityRecord r, String[] args, boolean dumpAll) {
11893        String innerPrefix = prefix + "  ";
11894        synchronized (this) {
11895            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11896                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11897                    pw.print(" pid=");
11898                    if (r.app != null) pw.println(r.app.pid);
11899                    else pw.println("(not running)");
11900            if (dumpAll) {
11901                r.dump(pw, innerPrefix);
11902            }
11903        }
11904        if (r.app != null && r.app.thread != null) {
11905            // flush anything that is already in the PrintWriter since the thread is going
11906            // to write to the file descriptor directly
11907            pw.flush();
11908            try {
11909                TransferPipe tp = new TransferPipe();
11910                try {
11911                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11912                            r.appToken, innerPrefix, args);
11913                    tp.go(fd);
11914                } finally {
11915                    tp.kill();
11916                }
11917            } catch (IOException e) {
11918                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11919            } catch (RemoteException e) {
11920                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11921            }
11922        }
11923    }
11924
11925    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11926            int opti, boolean dumpAll, String dumpPackage) {
11927        boolean needSep = false;
11928        boolean onlyHistory = false;
11929        boolean printedAnything = false;
11930
11931        if ("history".equals(dumpPackage)) {
11932            if (opti < args.length && "-s".equals(args[opti])) {
11933                dumpAll = false;
11934            }
11935            onlyHistory = true;
11936            dumpPackage = null;
11937        }
11938
11939        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11940        if (!onlyHistory && dumpAll) {
11941            if (mRegisteredReceivers.size() > 0) {
11942                boolean printed = false;
11943                Iterator it = mRegisteredReceivers.values().iterator();
11944                while (it.hasNext()) {
11945                    ReceiverList r = (ReceiverList)it.next();
11946                    if (dumpPackage != null && (r.app == null ||
11947                            !dumpPackage.equals(r.app.info.packageName))) {
11948                        continue;
11949                    }
11950                    if (!printed) {
11951                        pw.println("  Registered Receivers:");
11952                        needSep = true;
11953                        printed = true;
11954                        printedAnything = true;
11955                    }
11956                    pw.print("  * "); pw.println(r);
11957                    r.dump(pw, "    ");
11958                }
11959            }
11960
11961            if (mReceiverResolver.dump(pw, needSep ?
11962                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11963                    "    ", dumpPackage, false)) {
11964                needSep = true;
11965                printedAnything = true;
11966            }
11967        }
11968
11969        for (BroadcastQueue q : mBroadcastQueues) {
11970            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11971            printedAnything |= needSep;
11972        }
11973
11974        needSep = true;
11975
11976        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11977            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11978                if (needSep) {
11979                    pw.println();
11980                }
11981                needSep = true;
11982                printedAnything = true;
11983                pw.print("  Sticky broadcasts for user ");
11984                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11985                StringBuilder sb = new StringBuilder(128);
11986                for (Map.Entry<String, ArrayList<Intent>> ent
11987                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11988                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11989                    if (dumpAll) {
11990                        pw.println(":");
11991                        ArrayList<Intent> intents = ent.getValue();
11992                        final int N = intents.size();
11993                        for (int i=0; i<N; i++) {
11994                            sb.setLength(0);
11995                            sb.append("    Intent: ");
11996                            intents.get(i).toShortString(sb, false, true, false, false);
11997                            pw.println(sb.toString());
11998                            Bundle bundle = intents.get(i).getExtras();
11999                            if (bundle != null) {
12000                                pw.print("      ");
12001                                pw.println(bundle.toString());
12002                            }
12003                        }
12004                    } else {
12005                        pw.println("");
12006                    }
12007                }
12008            }
12009        }
12010
12011        if (!onlyHistory && dumpAll) {
12012            pw.println();
12013            for (BroadcastQueue queue : mBroadcastQueues) {
12014                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12015                        + queue.mBroadcastsScheduled);
12016            }
12017            pw.println("  mHandler:");
12018            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12019            needSep = true;
12020            printedAnything = true;
12021        }
12022
12023        if (!printedAnything) {
12024            pw.println("  (nothing)");
12025        }
12026    }
12027
12028    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12029            int opti, boolean dumpAll, String dumpPackage) {
12030        boolean needSep;
12031        boolean printedAnything = false;
12032
12033        ItemMatcher matcher = new ItemMatcher();
12034        matcher.build(args, opti);
12035
12036        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12037
12038        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12039        printedAnything |= needSep;
12040
12041        if (mLaunchingProviders.size() > 0) {
12042            boolean printed = false;
12043            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12044                ContentProviderRecord r = mLaunchingProviders.get(i);
12045                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12046                    continue;
12047                }
12048                if (!printed) {
12049                    if (needSep) pw.println();
12050                    needSep = true;
12051                    pw.println("  Launching content providers:");
12052                    printed = true;
12053                    printedAnything = true;
12054                }
12055                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12056                        pw.println(r);
12057            }
12058        }
12059
12060        if (mGrantedUriPermissions.size() > 0) {
12061            boolean printed = false;
12062            int dumpUid = -2;
12063            if (dumpPackage != null) {
12064                try {
12065                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12066                } catch (NameNotFoundException e) {
12067                    dumpUid = -1;
12068                }
12069            }
12070            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12071                int uid = mGrantedUriPermissions.keyAt(i);
12072                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12073                    continue;
12074                }
12075                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12076                if (!printed) {
12077                    if (needSep) pw.println();
12078                    needSep = true;
12079                    pw.println("  Granted Uri Permissions:");
12080                    printed = true;
12081                    printedAnything = true;
12082                }
12083                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12084                for (UriPermission perm : perms.values()) {
12085                    pw.print("    "); pw.println(perm);
12086                    if (dumpAll) {
12087                        perm.dump(pw, "      ");
12088                    }
12089                }
12090            }
12091        }
12092
12093        if (!printedAnything) {
12094            pw.println("  (nothing)");
12095        }
12096    }
12097
12098    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12099            int opti, boolean dumpAll, String dumpPackage) {
12100        boolean printed = false;
12101
12102        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12103
12104        if (mIntentSenderRecords.size() > 0) {
12105            Iterator<WeakReference<PendingIntentRecord>> it
12106                    = mIntentSenderRecords.values().iterator();
12107            while (it.hasNext()) {
12108                WeakReference<PendingIntentRecord> ref = it.next();
12109                PendingIntentRecord rec = ref != null ? ref.get(): null;
12110                if (dumpPackage != null && (rec == null
12111                        || !dumpPackage.equals(rec.key.packageName))) {
12112                    continue;
12113                }
12114                printed = true;
12115                if (rec != null) {
12116                    pw.print("  * "); pw.println(rec);
12117                    if (dumpAll) {
12118                        rec.dump(pw, "    ");
12119                    }
12120                } else {
12121                    pw.print("  * "); pw.println(ref);
12122                }
12123            }
12124        }
12125
12126        if (!printed) {
12127            pw.println("  (nothing)");
12128        }
12129    }
12130
12131    private static final int dumpProcessList(PrintWriter pw,
12132            ActivityManagerService service, List list,
12133            String prefix, String normalLabel, String persistentLabel,
12134            String dumpPackage) {
12135        int numPers = 0;
12136        final int N = list.size()-1;
12137        for (int i=N; i>=0; i--) {
12138            ProcessRecord r = (ProcessRecord)list.get(i);
12139            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12140                continue;
12141            }
12142            pw.println(String.format("%s%s #%2d: %s",
12143                    prefix, (r.persistent ? persistentLabel : normalLabel),
12144                    i, r.toString()));
12145            if (r.persistent) {
12146                numPers++;
12147            }
12148        }
12149        return numPers;
12150    }
12151
12152    private static final boolean dumpProcessOomList(PrintWriter pw,
12153            ActivityManagerService service, List<ProcessRecord> origList,
12154            String prefix, String normalLabel, String persistentLabel,
12155            boolean inclDetails, String dumpPackage) {
12156
12157        ArrayList<Pair<ProcessRecord, Integer>> list
12158                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12159        for (int i=0; i<origList.size(); i++) {
12160            ProcessRecord r = origList.get(i);
12161            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12162                continue;
12163            }
12164            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12165        }
12166
12167        if (list.size() <= 0) {
12168            return false;
12169        }
12170
12171        Comparator<Pair<ProcessRecord, Integer>> comparator
12172                = new Comparator<Pair<ProcessRecord, Integer>>() {
12173            @Override
12174            public int compare(Pair<ProcessRecord, Integer> object1,
12175                    Pair<ProcessRecord, Integer> object2) {
12176                if (object1.first.setAdj != object2.first.setAdj) {
12177                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12178                }
12179                if (object1.second.intValue() != object2.second.intValue()) {
12180                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12181                }
12182                return 0;
12183            }
12184        };
12185
12186        Collections.sort(list, comparator);
12187
12188        final long curRealtime = SystemClock.elapsedRealtime();
12189        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12190        final long curUptime = SystemClock.uptimeMillis();
12191        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12192
12193        for (int i=list.size()-1; i>=0; i--) {
12194            ProcessRecord r = list.get(i).first;
12195            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12196            char schedGroup;
12197            switch (r.setSchedGroup) {
12198                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12199                    schedGroup = 'B';
12200                    break;
12201                case Process.THREAD_GROUP_DEFAULT:
12202                    schedGroup = 'F';
12203                    break;
12204                default:
12205                    schedGroup = '?';
12206                    break;
12207            }
12208            char foreground;
12209            if (r.foregroundActivities) {
12210                foreground = 'A';
12211            } else if (r.foregroundServices) {
12212                foreground = 'S';
12213            } else {
12214                foreground = ' ';
12215            }
12216            String procState = ProcessList.makeProcStateString(r.curProcState);
12217            pw.print(prefix);
12218            pw.print(r.persistent ? persistentLabel : normalLabel);
12219            pw.print(" #");
12220            int num = (origList.size()-1)-list.get(i).second;
12221            if (num < 10) pw.print(' ');
12222            pw.print(num);
12223            pw.print(": ");
12224            pw.print(oomAdj);
12225            pw.print(' ');
12226            pw.print(schedGroup);
12227            pw.print('/');
12228            pw.print(foreground);
12229            pw.print('/');
12230            pw.print(procState);
12231            pw.print(" trm:");
12232            if (r.trimMemoryLevel < 10) pw.print(' ');
12233            pw.print(r.trimMemoryLevel);
12234            pw.print(' ');
12235            pw.print(r.toShortString());
12236            pw.print(" (");
12237            pw.print(r.adjType);
12238            pw.println(')');
12239            if (r.adjSource != null || r.adjTarget != null) {
12240                pw.print(prefix);
12241                pw.print("    ");
12242                if (r.adjTarget instanceof ComponentName) {
12243                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12244                } else if (r.adjTarget != null) {
12245                    pw.print(r.adjTarget.toString());
12246                } else {
12247                    pw.print("{null}");
12248                }
12249                pw.print("<=");
12250                if (r.adjSource instanceof ProcessRecord) {
12251                    pw.print("Proc{");
12252                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12253                    pw.println("}");
12254                } else if (r.adjSource != null) {
12255                    pw.println(r.adjSource.toString());
12256                } else {
12257                    pw.println("{null}");
12258                }
12259            }
12260            if (inclDetails) {
12261                pw.print(prefix);
12262                pw.print("    ");
12263                pw.print("oom: max="); pw.print(r.maxAdj);
12264                pw.print(" curRaw="); pw.print(r.curRawAdj);
12265                pw.print(" setRaw="); pw.print(r.setRawAdj);
12266                pw.print(" cur="); pw.print(r.curAdj);
12267                pw.print(" set="); pw.println(r.setAdj);
12268                pw.print(prefix);
12269                pw.print("    ");
12270                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12271                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12272                pw.print(" lastPss="); pw.print(r.lastPss);
12273                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12274                pw.print(prefix);
12275                pw.print("    ");
12276                pw.print("keeping="); pw.print(r.keeping);
12277                pw.print(" cached="); pw.print(r.cached);
12278                pw.print(" empty="); pw.print(r.empty);
12279                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12280
12281                if (!r.keeping) {
12282                    if (r.lastWakeTime != 0) {
12283                        long wtime;
12284                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12285                        synchronized (stats) {
12286                            wtime = stats.getProcessWakeTime(r.info.uid,
12287                                    r.pid, curRealtime);
12288                        }
12289                        long timeUsed = wtime - r.lastWakeTime;
12290                        pw.print(prefix);
12291                        pw.print("    ");
12292                        pw.print("keep awake over ");
12293                        TimeUtils.formatDuration(realtimeSince, pw);
12294                        pw.print(" used ");
12295                        TimeUtils.formatDuration(timeUsed, pw);
12296                        pw.print(" (");
12297                        pw.print((timeUsed*100)/realtimeSince);
12298                        pw.println("%)");
12299                    }
12300                    if (r.lastCpuTime != 0) {
12301                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12302                        pw.print(prefix);
12303                        pw.print("    ");
12304                        pw.print("run cpu over ");
12305                        TimeUtils.formatDuration(uptimeSince, pw);
12306                        pw.print(" used ");
12307                        TimeUtils.formatDuration(timeUsed, pw);
12308                        pw.print(" (");
12309                        pw.print((timeUsed*100)/uptimeSince);
12310                        pw.println("%)");
12311                    }
12312                }
12313            }
12314        }
12315        return true;
12316    }
12317
12318    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12319        ArrayList<ProcessRecord> procs;
12320        synchronized (this) {
12321            if (args != null && args.length > start
12322                    && args[start].charAt(0) != '-') {
12323                procs = new ArrayList<ProcessRecord>();
12324                int pid = -1;
12325                try {
12326                    pid = Integer.parseInt(args[start]);
12327                } catch (NumberFormatException e) {
12328                }
12329                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12330                    ProcessRecord proc = mLruProcesses.get(i);
12331                    if (proc.pid == pid) {
12332                        procs.add(proc);
12333                    } else if (proc.processName.equals(args[start])) {
12334                        procs.add(proc);
12335                    }
12336                }
12337                if (procs.size() <= 0) {
12338                    return null;
12339                }
12340            } else {
12341                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12342            }
12343        }
12344        return procs;
12345    }
12346
12347    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12348            PrintWriter pw, String[] args) {
12349        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12350        if (procs == null) {
12351            pw.println("No process found for: " + args[0]);
12352            return;
12353        }
12354
12355        long uptime = SystemClock.uptimeMillis();
12356        long realtime = SystemClock.elapsedRealtime();
12357        pw.println("Applications Graphics Acceleration Info:");
12358        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12359
12360        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12361            ProcessRecord r = procs.get(i);
12362            if (r.thread != null) {
12363                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12364                pw.flush();
12365                try {
12366                    TransferPipe tp = new TransferPipe();
12367                    try {
12368                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12369                        tp.go(fd);
12370                    } finally {
12371                        tp.kill();
12372                    }
12373                } catch (IOException e) {
12374                    pw.println("Failure while dumping the app: " + r);
12375                    pw.flush();
12376                } catch (RemoteException e) {
12377                    pw.println("Got a RemoteException while dumping the app " + r);
12378                    pw.flush();
12379                }
12380            }
12381        }
12382    }
12383
12384    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12385        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12386        if (procs == null) {
12387            pw.println("No process found for: " + args[0]);
12388            return;
12389        }
12390
12391        pw.println("Applications Database Info:");
12392
12393        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12394            ProcessRecord r = procs.get(i);
12395            if (r.thread != null) {
12396                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12397                pw.flush();
12398                try {
12399                    TransferPipe tp = new TransferPipe();
12400                    try {
12401                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12402                        tp.go(fd);
12403                    } finally {
12404                        tp.kill();
12405                    }
12406                } catch (IOException e) {
12407                    pw.println("Failure while dumping the app: " + r);
12408                    pw.flush();
12409                } catch (RemoteException e) {
12410                    pw.println("Got a RemoteException while dumping the app " + r);
12411                    pw.flush();
12412                }
12413            }
12414        }
12415    }
12416
12417    final static class MemItem {
12418        final boolean isProc;
12419        final String label;
12420        final String shortLabel;
12421        final long pss;
12422        final int id;
12423        final boolean hasActivities;
12424        ArrayList<MemItem> subitems;
12425
12426        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12427                boolean _hasActivities) {
12428            isProc = true;
12429            label = _label;
12430            shortLabel = _shortLabel;
12431            pss = _pss;
12432            id = _id;
12433            hasActivities = _hasActivities;
12434        }
12435
12436        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12437            isProc = false;
12438            label = _label;
12439            shortLabel = _shortLabel;
12440            pss = _pss;
12441            id = _id;
12442            hasActivities = false;
12443        }
12444    }
12445
12446    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12447            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12448        if (sort && !isCompact) {
12449            Collections.sort(items, new Comparator<MemItem>() {
12450                @Override
12451                public int compare(MemItem lhs, MemItem rhs) {
12452                    if (lhs.pss < rhs.pss) {
12453                        return 1;
12454                    } else if (lhs.pss > rhs.pss) {
12455                        return -1;
12456                    }
12457                    return 0;
12458                }
12459            });
12460        }
12461
12462        for (int i=0; i<items.size(); i++) {
12463            MemItem mi = items.get(i);
12464            if (!isCompact) {
12465                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12466            } else if (mi.isProc) {
12467                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12468                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12469                pw.println(mi.hasActivities ? ",a" : ",e");
12470            } else {
12471                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12472                pw.println(mi.pss);
12473            }
12474            if (mi.subitems != null) {
12475                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12476                        true, isCompact);
12477            }
12478        }
12479    }
12480
12481    // These are in KB.
12482    static final long[] DUMP_MEM_BUCKETS = new long[] {
12483        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12484        120*1024, 160*1024, 200*1024,
12485        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12486        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12487    };
12488
12489    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12490            boolean stackLike) {
12491        int start = label.lastIndexOf('.');
12492        if (start >= 0) start++;
12493        else start = 0;
12494        int end = label.length();
12495        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12496            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12497                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12498                out.append(bucket);
12499                out.append(stackLike ? "MB." : "MB ");
12500                out.append(label, start, end);
12501                return;
12502            }
12503        }
12504        out.append(memKB/1024);
12505        out.append(stackLike ? "MB." : "MB ");
12506        out.append(label, start, end);
12507    }
12508
12509    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12510            ProcessList.NATIVE_ADJ,
12511            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12512            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12513            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12514            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12515            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12516    };
12517    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12518            "Native",
12519            "System", "Persistent", "Foreground",
12520            "Visible", "Perceptible",
12521            "Heavy Weight", "Backup",
12522            "A Services", "Home",
12523            "Previous", "B Services", "Cached"
12524    };
12525    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12526            "native",
12527            "sys", "pers", "fore",
12528            "vis", "percept",
12529            "heavy", "backup",
12530            "servicea", "home",
12531            "prev", "serviceb", "cached"
12532    };
12533
12534    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12535            long realtime, boolean isCheckinRequest, boolean isCompact) {
12536        if (isCheckinRequest || isCompact) {
12537            // short checkin version
12538            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12539        } else {
12540            pw.println("Applications Memory Usage (kB):");
12541            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12542        }
12543    }
12544
12545    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12546            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12547        boolean dumpDetails = false;
12548        boolean dumpFullDetails = false;
12549        boolean dumpDalvik = false;
12550        boolean oomOnly = false;
12551        boolean isCompact = false;
12552        boolean localOnly = false;
12553
12554        int opti = 0;
12555        while (opti < args.length) {
12556            String opt = args[opti];
12557            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12558                break;
12559            }
12560            opti++;
12561            if ("-a".equals(opt)) {
12562                dumpDetails = true;
12563                dumpFullDetails = true;
12564                dumpDalvik = true;
12565            } else if ("-d".equals(opt)) {
12566                dumpDalvik = true;
12567            } else if ("-c".equals(opt)) {
12568                isCompact = true;
12569            } else if ("--oom".equals(opt)) {
12570                oomOnly = true;
12571            } else if ("--local".equals(opt)) {
12572                localOnly = true;
12573            } else if ("-h".equals(opt)) {
12574                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12575                pw.println("  -a: include all available information for each process.");
12576                pw.println("  -d: include dalvik details when dumping process details.");
12577                pw.println("  -c: dump in a compact machine-parseable representation.");
12578                pw.println("  --oom: only show processes organized by oom adj.");
12579                pw.println("  --local: only collect details locally, don't call process.");
12580                pw.println("If [process] is specified it can be the name or ");
12581                pw.println("pid of a specific process to dump.");
12582                return;
12583            } else {
12584                pw.println("Unknown argument: " + opt + "; use -h for help");
12585            }
12586        }
12587
12588        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12589        long uptime = SystemClock.uptimeMillis();
12590        long realtime = SystemClock.elapsedRealtime();
12591        final long[] tmpLong = new long[1];
12592
12593        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12594        if (procs == null) {
12595            // No Java processes.  Maybe they want to print a native process.
12596            if (args != null && args.length > opti
12597                    && args[opti].charAt(0) != '-') {
12598                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12599                        = new ArrayList<ProcessCpuTracker.Stats>();
12600                updateCpuStatsNow();
12601                int findPid = -1;
12602                try {
12603                    findPid = Integer.parseInt(args[opti]);
12604                } catch (NumberFormatException e) {
12605                }
12606                synchronized (mProcessCpuThread) {
12607                    final int N = mProcessCpuTracker.countStats();
12608                    for (int i=0; i<N; i++) {
12609                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12610                        if (st.pid == findPid || (st.baseName != null
12611                                && st.baseName.equals(args[opti]))) {
12612                            nativeProcs.add(st);
12613                        }
12614                    }
12615                }
12616                if (nativeProcs.size() > 0) {
12617                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12618                            isCompact);
12619                    Debug.MemoryInfo mi = null;
12620                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12621                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12622                        final int pid = r.pid;
12623                        if (!isCheckinRequest && dumpDetails) {
12624                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12625                        }
12626                        if (mi == null) {
12627                            mi = new Debug.MemoryInfo();
12628                        }
12629                        if (dumpDetails || (!brief && !oomOnly)) {
12630                            Debug.getMemoryInfo(pid, mi);
12631                        } else {
12632                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12633                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12634                        }
12635                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12636                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12637                        if (isCheckinRequest) {
12638                            pw.println();
12639                        }
12640                    }
12641                    return;
12642                }
12643            }
12644            pw.println("No process found for: " + args[opti]);
12645            return;
12646        }
12647
12648        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12649            dumpDetails = true;
12650        }
12651
12652        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12653
12654        String[] innerArgs = new String[args.length-opti];
12655        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12656
12657        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12658        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12659        long nativePss=0, dalvikPss=0, otherPss=0;
12660        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12661
12662        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12663        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12664                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12665
12666        long totalPss = 0;
12667        long cachedPss = 0;
12668
12669        Debug.MemoryInfo mi = null;
12670        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12671            final ProcessRecord r = procs.get(i);
12672            final IApplicationThread thread;
12673            final int pid;
12674            final int oomAdj;
12675            final boolean hasActivities;
12676            synchronized (this) {
12677                thread = r.thread;
12678                pid = r.pid;
12679                oomAdj = r.getSetAdjWithServices();
12680                hasActivities = r.activities.size() > 0;
12681            }
12682            if (thread != null) {
12683                if (!isCheckinRequest && dumpDetails) {
12684                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12685                }
12686                if (mi == null) {
12687                    mi = new Debug.MemoryInfo();
12688                }
12689                if (dumpDetails || (!brief && !oomOnly)) {
12690                    Debug.getMemoryInfo(pid, mi);
12691                } else {
12692                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12693                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12694                }
12695                if (dumpDetails) {
12696                    if (localOnly) {
12697                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12698                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12699                        if (isCheckinRequest) {
12700                            pw.println();
12701                        }
12702                    } else {
12703                        try {
12704                            pw.flush();
12705                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12706                                    dumpDalvik, innerArgs);
12707                        } catch (RemoteException e) {
12708                            if (!isCheckinRequest) {
12709                                pw.println("Got RemoteException!");
12710                                pw.flush();
12711                            }
12712                        }
12713                    }
12714                }
12715
12716                final long myTotalPss = mi.getTotalPss();
12717                final long myTotalUss = mi.getTotalUss();
12718
12719                synchronized (this) {
12720                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12721                        // Record this for posterity if the process has been stable.
12722                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12723                    }
12724                }
12725
12726                if (!isCheckinRequest && mi != null) {
12727                    totalPss += myTotalPss;
12728                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12729                            (hasActivities ? " / activities)" : ")"),
12730                            r.processName, myTotalPss, pid, hasActivities);
12731                    procMems.add(pssItem);
12732                    procMemsMap.put(pid, pssItem);
12733
12734                    nativePss += mi.nativePss;
12735                    dalvikPss += mi.dalvikPss;
12736                    otherPss += mi.otherPss;
12737                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12738                        long mem = mi.getOtherPss(j);
12739                        miscPss[j] += mem;
12740                        otherPss -= mem;
12741                    }
12742
12743                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12744                        cachedPss += myTotalPss;
12745                    }
12746
12747                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12748                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12749                                || oomIndex == (oomPss.length-1)) {
12750                            oomPss[oomIndex] += myTotalPss;
12751                            if (oomProcs[oomIndex] == null) {
12752                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12753                            }
12754                            oomProcs[oomIndex].add(pssItem);
12755                            break;
12756                        }
12757                    }
12758                }
12759            }
12760        }
12761
12762        long nativeProcTotalPss = 0;
12763
12764        if (!isCheckinRequest && procs.size() > 1) {
12765            // If we are showing aggregations, also look for native processes to
12766            // include so that our aggregations are more accurate.
12767            updateCpuStatsNow();
12768            synchronized (mProcessCpuThread) {
12769                final int N = mProcessCpuTracker.countStats();
12770                for (int i=0; i<N; i++) {
12771                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12772                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12773                        if (mi == null) {
12774                            mi = new Debug.MemoryInfo();
12775                        }
12776                        if (!brief && !oomOnly) {
12777                            Debug.getMemoryInfo(st.pid, mi);
12778                        } else {
12779                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12780                            mi.nativePrivateDirty = (int)tmpLong[0];
12781                        }
12782
12783                        final long myTotalPss = mi.getTotalPss();
12784                        totalPss += myTotalPss;
12785                        nativeProcTotalPss += myTotalPss;
12786
12787                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12788                                st.name, myTotalPss, st.pid, false);
12789                        procMems.add(pssItem);
12790
12791                        nativePss += mi.nativePss;
12792                        dalvikPss += mi.dalvikPss;
12793                        otherPss += mi.otherPss;
12794                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12795                            long mem = mi.getOtherPss(j);
12796                            miscPss[j] += mem;
12797                            otherPss -= mem;
12798                        }
12799                        oomPss[0] += myTotalPss;
12800                        if (oomProcs[0] == null) {
12801                            oomProcs[0] = new ArrayList<MemItem>();
12802                        }
12803                        oomProcs[0].add(pssItem);
12804                    }
12805                }
12806            }
12807
12808            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12809
12810            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12811            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12812            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12813            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12814                String label = Debug.MemoryInfo.getOtherLabel(j);
12815                catMems.add(new MemItem(label, label, miscPss[j], j));
12816            }
12817
12818            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12819            for (int j=0; j<oomPss.length; j++) {
12820                if (oomPss[j] != 0) {
12821                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12822                            : DUMP_MEM_OOM_LABEL[j];
12823                    MemItem item = new MemItem(label, label, oomPss[j],
12824                            DUMP_MEM_OOM_ADJ[j]);
12825                    item.subitems = oomProcs[j];
12826                    oomMems.add(item);
12827                }
12828            }
12829
12830            if (!brief && !oomOnly && !isCompact) {
12831                pw.println();
12832                pw.println("Total PSS by process:");
12833                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12834                pw.println();
12835            }
12836            if (!isCompact) {
12837                pw.println("Total PSS by OOM adjustment:");
12838            }
12839            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12840            if (!brief && !oomOnly) {
12841                PrintWriter out = categoryPw != null ? categoryPw : pw;
12842                if (!isCompact) {
12843                    out.println();
12844                    out.println("Total PSS by category:");
12845                }
12846                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12847            }
12848            if (!isCompact) {
12849                pw.println();
12850            }
12851            MemInfoReader memInfo = new MemInfoReader();
12852            memInfo.readMemInfo();
12853            if (nativeProcTotalPss > 0) {
12854                synchronized (this) {
12855                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
12856                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
12857                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
12858                            nativeProcTotalPss);
12859                }
12860            }
12861            if (!brief) {
12862                if (!isCompact) {
12863                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12864                    pw.print(" kB (status ");
12865                    switch (mLastMemoryLevel) {
12866                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12867                            pw.println("normal)");
12868                            break;
12869                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12870                            pw.println("moderate)");
12871                            break;
12872                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12873                            pw.println("low)");
12874                            break;
12875                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12876                            pw.println("critical)");
12877                            break;
12878                        default:
12879                            pw.print(mLastMemoryLevel);
12880                            pw.println(")");
12881                            break;
12882                    }
12883                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12884                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12885                            pw.print(cachedPss); pw.print(" cached pss + ");
12886                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12887                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12888                } else {
12889                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12890                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12891                            + memInfo.getFreeSizeKb()); pw.print(",");
12892                    pw.println(totalPss - cachedPss);
12893                }
12894            }
12895            if (!isCompact) {
12896                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12897                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12898                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12899                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12900                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12901                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12902                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12903                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12904                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12905                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12906                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12907            }
12908            if (!brief) {
12909                if (memInfo.getZramTotalSizeKb() != 0) {
12910                    if (!isCompact) {
12911                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12912                                pw.print(" kB physical used for ");
12913                                pw.print(memInfo.getSwapTotalSizeKb()
12914                                        - memInfo.getSwapFreeSizeKb());
12915                                pw.print(" kB in swap (");
12916                                pw.print(memInfo.getSwapTotalSizeKb());
12917                                pw.println(" kB total swap)");
12918                    } else {
12919                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12920                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12921                                pw.println(memInfo.getSwapFreeSizeKb());
12922                    }
12923                }
12924                final int[] SINGLE_LONG_FORMAT = new int[] {
12925                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12926                };
12927                long[] longOut = new long[1];
12928                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12929                        SINGLE_LONG_FORMAT, null, longOut, null);
12930                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12931                longOut[0] = 0;
12932                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12933                        SINGLE_LONG_FORMAT, null, longOut, null);
12934                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12935                longOut[0] = 0;
12936                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12937                        SINGLE_LONG_FORMAT, null, longOut, null);
12938                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12939                longOut[0] = 0;
12940                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12941                        SINGLE_LONG_FORMAT, null, longOut, null);
12942                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12943                if (!isCompact) {
12944                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12945                        pw.print("      KSM: "); pw.print(sharing);
12946                                pw.print(" kB saved from shared ");
12947                                pw.print(shared); pw.println(" kB");
12948                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12949                                pw.print(voltile); pw.println(" kB volatile");
12950                    }
12951                    pw.print("   Tuning: ");
12952                    pw.print(ActivityManager.staticGetMemoryClass());
12953                    pw.print(" (large ");
12954                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12955                    pw.print("), oom ");
12956                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12957                    pw.print(" kB");
12958                    pw.print(", restore limit ");
12959                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12960                    pw.print(" kB");
12961                    if (ActivityManager.isLowRamDeviceStatic()) {
12962                        pw.print(" (low-ram)");
12963                    }
12964                    if (ActivityManager.isHighEndGfx()) {
12965                        pw.print(" (high-end-gfx)");
12966                    }
12967                    pw.println();
12968                } else {
12969                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12970                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12971                    pw.println(voltile);
12972                    pw.print("tuning,");
12973                    pw.print(ActivityManager.staticGetMemoryClass());
12974                    pw.print(',');
12975                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12976                    pw.print(',');
12977                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12978                    if (ActivityManager.isLowRamDeviceStatic()) {
12979                        pw.print(",low-ram");
12980                    }
12981                    if (ActivityManager.isHighEndGfx()) {
12982                        pw.print(",high-end-gfx");
12983                    }
12984                    pw.println();
12985                }
12986            }
12987        }
12988    }
12989
12990    /**
12991     * Searches array of arguments for the specified string
12992     * @param args array of argument strings
12993     * @param value value to search for
12994     * @return true if the value is contained in the array
12995     */
12996    private static boolean scanArgs(String[] args, String value) {
12997        if (args != null) {
12998            for (String arg : args) {
12999                if (value.equals(arg)) {
13000                    return true;
13001                }
13002            }
13003        }
13004        return false;
13005    }
13006
13007    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13008            ContentProviderRecord cpr, boolean always) {
13009        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13010
13011        if (!inLaunching || always) {
13012            synchronized (cpr) {
13013                cpr.launchingApp = null;
13014                cpr.notifyAll();
13015            }
13016            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13017            String names[] = cpr.info.authority.split(";");
13018            for (int j = 0; j < names.length; j++) {
13019                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13020            }
13021        }
13022
13023        for (int i=0; i<cpr.connections.size(); i++) {
13024            ContentProviderConnection conn = cpr.connections.get(i);
13025            if (conn.waiting) {
13026                // If this connection is waiting for the provider, then we don't
13027                // need to mess with its process unless we are always removing
13028                // or for some reason the provider is not currently launching.
13029                if (inLaunching && !always) {
13030                    continue;
13031                }
13032            }
13033            ProcessRecord capp = conn.client;
13034            conn.dead = true;
13035            if (conn.stableCount > 0) {
13036                if (!capp.persistent && capp.thread != null
13037                        && capp.pid != 0
13038                        && capp.pid != MY_PID) {
13039                    killUnneededProcessLocked(capp, "depends on provider "
13040                            + cpr.name.flattenToShortString()
13041                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13042                }
13043            } else if (capp.thread != null && conn.provider.provider != null) {
13044                try {
13045                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13046                } catch (RemoteException e) {
13047                }
13048                // In the protocol here, we don't expect the client to correctly
13049                // clean up this connection, we'll just remove it.
13050                cpr.connections.remove(i);
13051                conn.client.conProviders.remove(conn);
13052            }
13053        }
13054
13055        if (inLaunching && always) {
13056            mLaunchingProviders.remove(cpr);
13057        }
13058        return inLaunching;
13059    }
13060
13061    /**
13062     * Main code for cleaning up a process when it has gone away.  This is
13063     * called both as a result of the process dying, or directly when stopping
13064     * a process when running in single process mode.
13065     */
13066    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13067            boolean restarting, boolean allowRestart, int index) {
13068        if (index >= 0) {
13069            removeLruProcessLocked(app);
13070            ProcessList.remove(app.pid);
13071        }
13072
13073        mProcessesToGc.remove(app);
13074        mPendingPssProcesses.remove(app);
13075
13076        // Dismiss any open dialogs.
13077        if (app.crashDialog != null && !app.forceCrashReport) {
13078            app.crashDialog.dismiss();
13079            app.crashDialog = null;
13080        }
13081        if (app.anrDialog != null) {
13082            app.anrDialog.dismiss();
13083            app.anrDialog = null;
13084        }
13085        if (app.waitDialog != null) {
13086            app.waitDialog.dismiss();
13087            app.waitDialog = null;
13088        }
13089
13090        app.crashing = false;
13091        app.notResponding = false;
13092
13093        app.resetPackageList(mProcessStats);
13094        app.unlinkDeathRecipient();
13095        app.makeInactive(mProcessStats);
13096        app.forcingToForeground = null;
13097        updateProcessForegroundLocked(app, false, false);
13098        app.foregroundActivities = false;
13099        app.hasShownUi = false;
13100        app.treatLikeActivity = false;
13101        app.hasAboveClient = false;
13102        app.hasClientActivities = false;
13103
13104        mServices.killServicesLocked(app, allowRestart);
13105
13106        boolean restart = false;
13107
13108        // Remove published content providers.
13109        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13110            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13111            final boolean always = app.bad || !allowRestart;
13112            if (removeDyingProviderLocked(app, cpr, always) || always) {
13113                // We left the provider in the launching list, need to
13114                // restart it.
13115                restart = true;
13116            }
13117
13118            cpr.provider = null;
13119            cpr.proc = null;
13120        }
13121        app.pubProviders.clear();
13122
13123        // Take care of any launching providers waiting for this process.
13124        if (checkAppInLaunchingProvidersLocked(app, false)) {
13125            restart = true;
13126        }
13127
13128        // Unregister from connected content providers.
13129        if (!app.conProviders.isEmpty()) {
13130            for (int i=0; i<app.conProviders.size(); i++) {
13131                ContentProviderConnection conn = app.conProviders.get(i);
13132                conn.provider.connections.remove(conn);
13133            }
13134            app.conProviders.clear();
13135        }
13136
13137        // At this point there may be remaining entries in mLaunchingProviders
13138        // where we were the only one waiting, so they are no longer of use.
13139        // Look for these and clean up if found.
13140        // XXX Commented out for now.  Trying to figure out a way to reproduce
13141        // the actual situation to identify what is actually going on.
13142        if (false) {
13143            for (int i=0; i<mLaunchingProviders.size(); i++) {
13144                ContentProviderRecord cpr = (ContentProviderRecord)
13145                        mLaunchingProviders.get(i);
13146                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13147                    synchronized (cpr) {
13148                        cpr.launchingApp = null;
13149                        cpr.notifyAll();
13150                    }
13151                }
13152            }
13153        }
13154
13155        skipCurrentReceiverLocked(app);
13156
13157        // Unregister any receivers.
13158        for (int i=app.receivers.size()-1; i>=0; i--) {
13159            removeReceiverLocked(app.receivers.valueAt(i));
13160        }
13161        app.receivers.clear();
13162
13163        // If the app is undergoing backup, tell the backup manager about it
13164        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13165            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13166                    + mBackupTarget.appInfo + " died during backup");
13167            try {
13168                IBackupManager bm = IBackupManager.Stub.asInterface(
13169                        ServiceManager.getService(Context.BACKUP_SERVICE));
13170                bm.agentDisconnected(app.info.packageName);
13171            } catch (RemoteException e) {
13172                // can't happen; backup manager is local
13173            }
13174        }
13175
13176        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13177            ProcessChangeItem item = mPendingProcessChanges.get(i);
13178            if (item.pid == app.pid) {
13179                mPendingProcessChanges.remove(i);
13180                mAvailProcessChanges.add(item);
13181            }
13182        }
13183        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13184
13185        // If the caller is restarting this app, then leave it in its
13186        // current lists and let the caller take care of it.
13187        if (restarting) {
13188            return;
13189        }
13190
13191        if (!app.persistent || app.isolated) {
13192            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13193                    "Removing non-persistent process during cleanup: " + app);
13194            mProcessNames.remove(app.processName, app.uid);
13195            mIsolatedProcesses.remove(app.uid);
13196            if (mHeavyWeightProcess == app) {
13197                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13198                        mHeavyWeightProcess.userId, 0));
13199                mHeavyWeightProcess = null;
13200            }
13201        } else if (!app.removed) {
13202            // This app is persistent, so we need to keep its record around.
13203            // If it is not already on the pending app list, add it there
13204            // and start a new process for it.
13205            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13206                mPersistentStartingProcesses.add(app);
13207                restart = true;
13208            }
13209        }
13210        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13211                "Clean-up removing on hold: " + app);
13212        mProcessesOnHold.remove(app);
13213
13214        if (app == mHomeProcess) {
13215            mHomeProcess = null;
13216        }
13217        if (app == mPreviousProcess) {
13218            mPreviousProcess = null;
13219        }
13220
13221        if (restart && !app.isolated) {
13222            // We have components that still need to be running in the
13223            // process, so re-launch it.
13224            mProcessNames.put(app.processName, app.uid, app);
13225            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13226        } else if (app.pid > 0 && app.pid != MY_PID) {
13227            // Goodbye!
13228            boolean removed;
13229            synchronized (mPidsSelfLocked) {
13230                mPidsSelfLocked.remove(app.pid);
13231                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13232            }
13233            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
13234                    app.processName, app.info.uid);
13235            if (app.isolated) {
13236                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13237            }
13238            app.setPid(0);
13239        }
13240    }
13241
13242    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13243        // Look through the content providers we are waiting to have launched,
13244        // and if any run in this process then either schedule a restart of
13245        // the process or kill the client waiting for it if this process has
13246        // gone bad.
13247        int NL = mLaunchingProviders.size();
13248        boolean restart = false;
13249        for (int i=0; i<NL; i++) {
13250            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13251            if (cpr.launchingApp == app) {
13252                if (!alwaysBad && !app.bad) {
13253                    restart = true;
13254                } else {
13255                    removeDyingProviderLocked(app, cpr, true);
13256                    // cpr should have been removed from mLaunchingProviders
13257                    NL = mLaunchingProviders.size();
13258                    i--;
13259                }
13260            }
13261        }
13262        return restart;
13263    }
13264
13265    // =========================================================
13266    // SERVICES
13267    // =========================================================
13268
13269    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13270            int flags) {
13271        enforceNotIsolatedCaller("getServices");
13272        synchronized (this) {
13273            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13274        }
13275    }
13276
13277    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13278        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13279        synchronized (this) {
13280            return mServices.getRunningServiceControlPanelLocked(name);
13281        }
13282    }
13283
13284    public ComponentName startService(IApplicationThread caller, Intent service,
13285            String resolvedType, int userId) {
13286        enforceNotIsolatedCaller("startService");
13287        // Refuse possible leaked file descriptors
13288        if (service != null && service.hasFileDescriptors() == true) {
13289            throw new IllegalArgumentException("File descriptors passed in Intent");
13290        }
13291
13292        if (DEBUG_SERVICE)
13293            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13294        synchronized(this) {
13295            final int callingPid = Binder.getCallingPid();
13296            final int callingUid = Binder.getCallingUid();
13297            final long origId = Binder.clearCallingIdentity();
13298            ComponentName res = mServices.startServiceLocked(caller, service,
13299                    resolvedType, callingPid, callingUid, userId);
13300            Binder.restoreCallingIdentity(origId);
13301            return res;
13302        }
13303    }
13304
13305    ComponentName startServiceInPackage(int uid,
13306            Intent service, String resolvedType, int userId) {
13307        synchronized(this) {
13308            if (DEBUG_SERVICE)
13309                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13310            final long origId = Binder.clearCallingIdentity();
13311            ComponentName res = mServices.startServiceLocked(null, service,
13312                    resolvedType, -1, uid, userId);
13313            Binder.restoreCallingIdentity(origId);
13314            return res;
13315        }
13316    }
13317
13318    public int stopService(IApplicationThread caller, Intent service,
13319            String resolvedType, int userId) {
13320        enforceNotIsolatedCaller("stopService");
13321        // Refuse possible leaked file descriptors
13322        if (service != null && service.hasFileDescriptors() == true) {
13323            throw new IllegalArgumentException("File descriptors passed in Intent");
13324        }
13325
13326        synchronized(this) {
13327            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13328        }
13329    }
13330
13331    public IBinder peekService(Intent service, String resolvedType) {
13332        enforceNotIsolatedCaller("peekService");
13333        // Refuse possible leaked file descriptors
13334        if (service != null && service.hasFileDescriptors() == true) {
13335            throw new IllegalArgumentException("File descriptors passed in Intent");
13336        }
13337        synchronized(this) {
13338            return mServices.peekServiceLocked(service, resolvedType);
13339        }
13340    }
13341
13342    public boolean stopServiceToken(ComponentName className, IBinder token,
13343            int startId) {
13344        synchronized(this) {
13345            return mServices.stopServiceTokenLocked(className, token, startId);
13346        }
13347    }
13348
13349    public void setServiceForeground(ComponentName className, IBinder token,
13350            int id, Notification notification, boolean removeNotification) {
13351        synchronized(this) {
13352            mServices.setServiceForegroundLocked(className, token, id, notification,
13353                    removeNotification);
13354        }
13355    }
13356
13357    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13358            boolean requireFull, String name, String callerPackage) {
13359        final int callingUserId = UserHandle.getUserId(callingUid);
13360        if (callingUserId != userId) {
13361            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13362                if ((requireFull || checkComponentPermission(
13363                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13364                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
13365                        && checkComponentPermission(INTERACT_ACROSS_USERS_FULL,
13366                                callingPid, callingUid, -1, true)
13367                                != PackageManager.PERMISSION_GRANTED) {
13368                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13369                        // In this case, they would like to just execute as their
13370                        // owner user instead of failing.
13371                        userId = callingUserId;
13372                    } else {
13373                        StringBuilder builder = new StringBuilder(128);
13374                        builder.append("Permission Denial: ");
13375                        builder.append(name);
13376                        if (callerPackage != null) {
13377                            builder.append(" from ");
13378                            builder.append(callerPackage);
13379                        }
13380                        builder.append(" asks to run as user ");
13381                        builder.append(userId);
13382                        builder.append(" but is calling from user ");
13383                        builder.append(UserHandle.getUserId(callingUid));
13384                        builder.append("; this requires ");
13385                        builder.append(INTERACT_ACROSS_USERS_FULL);
13386                        if (!requireFull) {
13387                            builder.append(" or ");
13388                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13389                        }
13390                        String msg = builder.toString();
13391                        Slog.w(TAG, msg);
13392                        throw new SecurityException(msg);
13393                    }
13394                }
13395            }
13396            if (userId == UserHandle.USER_CURRENT
13397                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13398                // Note that we may be accessing this outside of a lock...
13399                // shouldn't be a big deal, if this is being called outside
13400                // of a locked context there is intrinsically a race with
13401                // the value the caller will receive and someone else changing it.
13402                userId = mCurrentUserId;
13403            }
13404            if (!allowAll && userId < 0) {
13405                throw new IllegalArgumentException(
13406                        "Call does not support special user #" + userId);
13407            }
13408        }
13409        return userId;
13410    }
13411
13412    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13413            String className, int flags) {
13414        boolean result = false;
13415        // For apps that don't have pre-defined UIDs, check for permission
13416        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13417            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13418                if (ActivityManager.checkUidPermission(
13419                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13420                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13421                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13422                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13423                            + " requests FLAG_SINGLE_USER, but app does not hold "
13424                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13425                    Slog.w(TAG, msg);
13426                    throw new SecurityException(msg);
13427                }
13428                // Permission passed
13429                result = true;
13430            }
13431        } else if ("system".equals(componentProcessName)) {
13432            result = true;
13433        } else {
13434            // App with pre-defined UID, check if it's a persistent app
13435            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13436        }
13437        if (DEBUG_MU) {
13438            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13439                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13440        }
13441        return result;
13442    }
13443
13444    /**
13445     * Checks to see if the caller is in the same app as the singleton
13446     * component, or the component is in a special app. It allows special apps
13447     * to export singleton components but prevents exporting singleton
13448     * components for regular apps.
13449     */
13450    boolean isValidSingletonCall(int callingUid, int componentUid) {
13451        int componentAppId = UserHandle.getAppId(componentUid);
13452        return UserHandle.isSameApp(callingUid, componentUid)
13453                || componentAppId == Process.SYSTEM_UID
13454                || componentAppId == Process.PHONE_UID
13455                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13456                        == PackageManager.PERMISSION_GRANTED;
13457    }
13458
13459    public int bindService(IApplicationThread caller, IBinder token,
13460            Intent service, String resolvedType,
13461            IServiceConnection connection, int flags, int userId) {
13462        enforceNotIsolatedCaller("bindService");
13463        // Refuse possible leaked file descriptors
13464        if (service != null && service.hasFileDescriptors() == true) {
13465            throw new IllegalArgumentException("File descriptors passed in Intent");
13466        }
13467
13468        synchronized(this) {
13469            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13470                    connection, flags, userId);
13471        }
13472    }
13473
13474    public boolean unbindService(IServiceConnection connection) {
13475        synchronized (this) {
13476            return mServices.unbindServiceLocked(connection);
13477        }
13478    }
13479
13480    public void publishService(IBinder token, Intent intent, IBinder service) {
13481        // Refuse possible leaked file descriptors
13482        if (intent != null && intent.hasFileDescriptors() == true) {
13483            throw new IllegalArgumentException("File descriptors passed in Intent");
13484        }
13485
13486        synchronized(this) {
13487            if (!(token instanceof ServiceRecord)) {
13488                throw new IllegalArgumentException("Invalid service token");
13489            }
13490            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13491        }
13492    }
13493
13494    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13495        // Refuse possible leaked file descriptors
13496        if (intent != null && intent.hasFileDescriptors() == true) {
13497            throw new IllegalArgumentException("File descriptors passed in Intent");
13498        }
13499
13500        synchronized(this) {
13501            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13502        }
13503    }
13504
13505    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13506        synchronized(this) {
13507            if (!(token instanceof ServiceRecord)) {
13508                throw new IllegalArgumentException("Invalid service token");
13509            }
13510            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13511        }
13512    }
13513
13514    // =========================================================
13515    // BACKUP AND RESTORE
13516    // =========================================================
13517
13518    // Cause the target app to be launched if necessary and its backup agent
13519    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13520    // activity manager to announce its creation.
13521    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13522        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13523        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
13524
13525        synchronized(this) {
13526            // !!! TODO: currently no check here that we're already bound
13527            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13528            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13529            synchronized (stats) {
13530                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13531            }
13532
13533            // Backup agent is now in use, its package can't be stopped.
13534            try {
13535                AppGlobals.getPackageManager().setPackageStoppedState(
13536                        app.packageName, false, UserHandle.getUserId(app.uid));
13537            } catch (RemoteException e) {
13538            } catch (IllegalArgumentException e) {
13539                Slog.w(TAG, "Failed trying to unstop package "
13540                        + app.packageName + ": " + e);
13541            }
13542
13543            BackupRecord r = new BackupRecord(ss, app, backupMode);
13544            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13545                    ? new ComponentName(app.packageName, app.backupAgentName)
13546                    : new ComponentName("android", "FullBackupAgent");
13547            // startProcessLocked() returns existing proc's record if it's already running
13548            ProcessRecord proc = startProcessLocked(app.processName, app,
13549                    false, 0, "backup", hostingName, false, false, false);
13550            if (proc == null) {
13551                Slog.e(TAG, "Unable to start backup agent process " + r);
13552                return false;
13553            }
13554
13555            r.app = proc;
13556            mBackupTarget = r;
13557            mBackupAppName = app.packageName;
13558
13559            // Try not to kill the process during backup
13560            updateOomAdjLocked(proc);
13561
13562            // If the process is already attached, schedule the creation of the backup agent now.
13563            // If it is not yet live, this will be done when it attaches to the framework.
13564            if (proc.thread != null) {
13565                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13566                try {
13567                    proc.thread.scheduleCreateBackupAgent(app,
13568                            compatibilityInfoForPackageLocked(app), backupMode);
13569                } catch (RemoteException e) {
13570                    // Will time out on the backup manager side
13571                }
13572            } else {
13573                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13574            }
13575            // Invariants: at this point, the target app process exists and the application
13576            // is either already running or in the process of coming up.  mBackupTarget and
13577            // mBackupAppName describe the app, so that when it binds back to the AM we
13578            // know that it's scheduled for a backup-agent operation.
13579        }
13580
13581        return true;
13582    }
13583
13584    @Override
13585    public void clearPendingBackup() {
13586        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13587        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13588
13589        synchronized (this) {
13590            mBackupTarget = null;
13591            mBackupAppName = null;
13592        }
13593    }
13594
13595    // A backup agent has just come up
13596    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13597        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13598                + " = " + agent);
13599
13600        synchronized(this) {
13601            if (!agentPackageName.equals(mBackupAppName)) {
13602                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13603                return;
13604            }
13605        }
13606
13607        long oldIdent = Binder.clearCallingIdentity();
13608        try {
13609            IBackupManager bm = IBackupManager.Stub.asInterface(
13610                    ServiceManager.getService(Context.BACKUP_SERVICE));
13611            bm.agentConnected(agentPackageName, agent);
13612        } catch (RemoteException e) {
13613            // can't happen; the backup manager service is local
13614        } catch (Exception e) {
13615            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13616            e.printStackTrace();
13617        } finally {
13618            Binder.restoreCallingIdentity(oldIdent);
13619        }
13620    }
13621
13622    // done with this agent
13623    public void unbindBackupAgent(ApplicationInfo appInfo) {
13624        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13625        if (appInfo == null) {
13626            Slog.w(TAG, "unbind backup agent for null app");
13627            return;
13628        }
13629
13630        synchronized(this) {
13631            try {
13632                if (mBackupAppName == null) {
13633                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13634                    return;
13635                }
13636
13637                if (!mBackupAppName.equals(appInfo.packageName)) {
13638                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13639                    return;
13640                }
13641
13642                // Not backing this app up any more; reset its OOM adjustment
13643                final ProcessRecord proc = mBackupTarget.app;
13644                updateOomAdjLocked(proc);
13645
13646                // If the app crashed during backup, 'thread' will be null here
13647                if (proc.thread != null) {
13648                    try {
13649                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13650                                compatibilityInfoForPackageLocked(appInfo));
13651                    } catch (Exception e) {
13652                        Slog.e(TAG, "Exception when unbinding backup agent:");
13653                        e.printStackTrace();
13654                    }
13655                }
13656            } finally {
13657                mBackupTarget = null;
13658                mBackupAppName = null;
13659            }
13660        }
13661    }
13662    // =========================================================
13663    // BROADCASTS
13664    // =========================================================
13665
13666    private final List getStickiesLocked(String action, IntentFilter filter,
13667            List cur, int userId) {
13668        final ContentResolver resolver = mContext.getContentResolver();
13669        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13670        if (stickies == null) {
13671            return cur;
13672        }
13673        final ArrayList<Intent> list = stickies.get(action);
13674        if (list == null) {
13675            return cur;
13676        }
13677        int N = list.size();
13678        for (int i=0; i<N; i++) {
13679            Intent intent = list.get(i);
13680            if (filter.match(resolver, intent, true, TAG) >= 0) {
13681                if (cur == null) {
13682                    cur = new ArrayList<Intent>();
13683                }
13684                cur.add(intent);
13685            }
13686        }
13687        return cur;
13688    }
13689
13690    boolean isPendingBroadcastProcessLocked(int pid) {
13691        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13692                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13693    }
13694
13695    void skipPendingBroadcastLocked(int pid) {
13696            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13697            for (BroadcastQueue queue : mBroadcastQueues) {
13698                queue.skipPendingBroadcastLocked(pid);
13699            }
13700    }
13701
13702    // The app just attached; send any pending broadcasts that it should receive
13703    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13704        boolean didSomething = false;
13705        for (BroadcastQueue queue : mBroadcastQueues) {
13706            didSomething |= queue.sendPendingBroadcastsLocked(app);
13707        }
13708        return didSomething;
13709    }
13710
13711    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13712            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13713        enforceNotIsolatedCaller("registerReceiver");
13714        int callingUid;
13715        int callingPid;
13716        synchronized(this) {
13717            ProcessRecord callerApp = null;
13718            if (caller != null) {
13719                callerApp = getRecordForAppLocked(caller);
13720                if (callerApp == null) {
13721                    throw new SecurityException(
13722                            "Unable to find app for caller " + caller
13723                            + " (pid=" + Binder.getCallingPid()
13724                            + ") when registering receiver " + receiver);
13725                }
13726                if (callerApp.info.uid != Process.SYSTEM_UID &&
13727                        !callerApp.pkgList.containsKey(callerPackage) &&
13728                        !"android".equals(callerPackage)) {
13729                    throw new SecurityException("Given caller package " + callerPackage
13730                            + " is not running in process " + callerApp);
13731                }
13732                callingUid = callerApp.info.uid;
13733                callingPid = callerApp.pid;
13734            } else {
13735                callerPackage = null;
13736                callingUid = Binder.getCallingUid();
13737                callingPid = Binder.getCallingPid();
13738            }
13739
13740            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13741                    true, true, "registerReceiver", callerPackage);
13742
13743            List allSticky = null;
13744
13745            // Look for any matching sticky broadcasts...
13746            Iterator actions = filter.actionsIterator();
13747            if (actions != null) {
13748                while (actions.hasNext()) {
13749                    String action = (String)actions.next();
13750                    allSticky = getStickiesLocked(action, filter, allSticky,
13751                            UserHandle.USER_ALL);
13752                    allSticky = getStickiesLocked(action, filter, allSticky,
13753                            UserHandle.getUserId(callingUid));
13754                }
13755            } else {
13756                allSticky = getStickiesLocked(null, filter, allSticky,
13757                        UserHandle.USER_ALL);
13758                allSticky = getStickiesLocked(null, filter, allSticky,
13759                        UserHandle.getUserId(callingUid));
13760            }
13761
13762            // The first sticky in the list is returned directly back to
13763            // the client.
13764            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13765
13766            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13767                    + ": " + sticky);
13768
13769            if (receiver == null) {
13770                return sticky;
13771            }
13772
13773            ReceiverList rl
13774                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13775            if (rl == null) {
13776                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13777                        userId, receiver);
13778                if (rl.app != null) {
13779                    rl.app.receivers.add(rl);
13780                } else {
13781                    try {
13782                        receiver.asBinder().linkToDeath(rl, 0);
13783                    } catch (RemoteException e) {
13784                        return sticky;
13785                    }
13786                    rl.linkedToDeath = true;
13787                }
13788                mRegisteredReceivers.put(receiver.asBinder(), rl);
13789            } else if (rl.uid != callingUid) {
13790                throw new IllegalArgumentException(
13791                        "Receiver requested to register for uid " + callingUid
13792                        + " was previously registered for uid " + rl.uid);
13793            } else if (rl.pid != callingPid) {
13794                throw new IllegalArgumentException(
13795                        "Receiver requested to register for pid " + callingPid
13796                        + " was previously registered for pid " + rl.pid);
13797            } else if (rl.userId != userId) {
13798                throw new IllegalArgumentException(
13799                        "Receiver requested to register for user " + userId
13800                        + " was previously registered for user " + rl.userId);
13801            }
13802            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13803                    permission, callingUid, userId);
13804            rl.add(bf);
13805            if (!bf.debugCheck()) {
13806                Slog.w(TAG, "==> For Dynamic broadast");
13807            }
13808            mReceiverResolver.addFilter(bf);
13809
13810            // Enqueue broadcasts for all existing stickies that match
13811            // this filter.
13812            if (allSticky != null) {
13813                ArrayList receivers = new ArrayList();
13814                receivers.add(bf);
13815
13816                int N = allSticky.size();
13817                for (int i=0; i<N; i++) {
13818                    Intent intent = (Intent)allSticky.get(i);
13819                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13820                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13821                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13822                            null, null, false, true, true, -1);
13823                    queue.enqueueParallelBroadcastLocked(r);
13824                    queue.scheduleBroadcastsLocked();
13825                }
13826            }
13827
13828            return sticky;
13829        }
13830    }
13831
13832    public void unregisterReceiver(IIntentReceiver receiver) {
13833        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13834
13835        final long origId = Binder.clearCallingIdentity();
13836        try {
13837            boolean doTrim = false;
13838
13839            synchronized(this) {
13840                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13841                if (rl != null) {
13842                    if (rl.curBroadcast != null) {
13843                        BroadcastRecord r = rl.curBroadcast;
13844                        final boolean doNext = finishReceiverLocked(
13845                                receiver.asBinder(), r.resultCode, r.resultData,
13846                                r.resultExtras, r.resultAbort);
13847                        if (doNext) {
13848                            doTrim = true;
13849                            r.queue.processNextBroadcast(false);
13850                        }
13851                    }
13852
13853                    if (rl.app != null) {
13854                        rl.app.receivers.remove(rl);
13855                    }
13856                    removeReceiverLocked(rl);
13857                    if (rl.linkedToDeath) {
13858                        rl.linkedToDeath = false;
13859                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13860                    }
13861                }
13862            }
13863
13864            // If we actually concluded any broadcasts, we might now be able
13865            // to trim the recipients' apps from our working set
13866            if (doTrim) {
13867                trimApplications();
13868                return;
13869            }
13870
13871        } finally {
13872            Binder.restoreCallingIdentity(origId);
13873        }
13874    }
13875
13876    void removeReceiverLocked(ReceiverList rl) {
13877        mRegisteredReceivers.remove(rl.receiver.asBinder());
13878        int N = rl.size();
13879        for (int i=0; i<N; i++) {
13880            mReceiverResolver.removeFilter(rl.get(i));
13881        }
13882    }
13883
13884    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13885        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13886            ProcessRecord r = mLruProcesses.get(i);
13887            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13888                try {
13889                    r.thread.dispatchPackageBroadcast(cmd, packages);
13890                } catch (RemoteException ex) {
13891                }
13892            }
13893        }
13894    }
13895
13896    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13897            int[] users) {
13898        List<ResolveInfo> receivers = null;
13899        try {
13900            HashSet<ComponentName> singleUserReceivers = null;
13901            boolean scannedFirstReceivers = false;
13902            for (int user : users) {
13903                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13904                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13905                if (user != 0 && newReceivers != null) {
13906                    // If this is not the primary user, we need to check for
13907                    // any receivers that should be filtered out.
13908                    for (int i=0; i<newReceivers.size(); i++) {
13909                        ResolveInfo ri = newReceivers.get(i);
13910                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13911                            newReceivers.remove(i);
13912                            i--;
13913                        }
13914                    }
13915                }
13916                if (newReceivers != null && newReceivers.size() == 0) {
13917                    newReceivers = null;
13918                }
13919                if (receivers == null) {
13920                    receivers = newReceivers;
13921                } else if (newReceivers != null) {
13922                    // We need to concatenate the additional receivers
13923                    // found with what we have do far.  This would be easy,
13924                    // but we also need to de-dup any receivers that are
13925                    // singleUser.
13926                    if (!scannedFirstReceivers) {
13927                        // Collect any single user receivers we had already retrieved.
13928                        scannedFirstReceivers = true;
13929                        for (int i=0; i<receivers.size(); i++) {
13930                            ResolveInfo ri = receivers.get(i);
13931                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13932                                ComponentName cn = new ComponentName(
13933                                        ri.activityInfo.packageName, ri.activityInfo.name);
13934                                if (singleUserReceivers == null) {
13935                                    singleUserReceivers = new HashSet<ComponentName>();
13936                                }
13937                                singleUserReceivers.add(cn);
13938                            }
13939                        }
13940                    }
13941                    // Add the new results to the existing results, tracking
13942                    // and de-dupping single user receivers.
13943                    for (int i=0; i<newReceivers.size(); i++) {
13944                        ResolveInfo ri = newReceivers.get(i);
13945                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13946                            ComponentName cn = new ComponentName(
13947                                    ri.activityInfo.packageName, ri.activityInfo.name);
13948                            if (singleUserReceivers == null) {
13949                                singleUserReceivers = new HashSet<ComponentName>();
13950                            }
13951                            if (!singleUserReceivers.contains(cn)) {
13952                                singleUserReceivers.add(cn);
13953                                receivers.add(ri);
13954                            }
13955                        } else {
13956                            receivers.add(ri);
13957                        }
13958                    }
13959                }
13960            }
13961        } catch (RemoteException ex) {
13962            // pm is in same process, this will never happen.
13963        }
13964        return receivers;
13965    }
13966
13967    private final int broadcastIntentLocked(ProcessRecord callerApp,
13968            String callerPackage, Intent intent, String resolvedType,
13969            IIntentReceiver resultTo, int resultCode, String resultData,
13970            Bundle map, String requiredPermission, int appOp,
13971            boolean ordered, boolean sticky, int callingPid, int callingUid,
13972            int userId) {
13973        intent = new Intent(intent);
13974
13975        // By default broadcasts do not go to stopped apps.
13976        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13977
13978        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13979            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13980            + " ordered=" + ordered + " userid=" + userId);
13981        if ((resultTo != null) && !ordered) {
13982            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13983        }
13984
13985        userId = handleIncomingUser(callingPid, callingUid, userId,
13986                true, false, "broadcast", callerPackage);
13987
13988        // Make sure that the user who is receiving this broadcast is started.
13989        // If not, we will just skip it.
13990
13991
13992        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13993            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13994                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13995                Slog.w(TAG, "Skipping broadcast of " + intent
13996                        + ": user " + userId + " is stopped");
13997                return ActivityManager.BROADCAST_SUCCESS;
13998            }
13999        }
14000
14001        /*
14002         * Prevent non-system code (defined here to be non-persistent
14003         * processes) from sending protected broadcasts.
14004         */
14005        int callingAppId = UserHandle.getAppId(callingUid);
14006        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14007            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14008            || callingAppId == Process.NFC_UID || callingUid == 0) {
14009            // Always okay.
14010        } else if (callerApp == null || !callerApp.persistent) {
14011            try {
14012                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14013                        intent.getAction())) {
14014                    String msg = "Permission Denial: not allowed to send broadcast "
14015                            + intent.getAction() + " from pid="
14016                            + callingPid + ", uid=" + callingUid;
14017                    Slog.w(TAG, msg);
14018                    throw new SecurityException(msg);
14019                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14020                    // Special case for compatibility: we don't want apps to send this,
14021                    // but historically it has not been protected and apps may be using it
14022                    // to poke their own app widget.  So, instead of making it protected,
14023                    // just limit it to the caller.
14024                    if (callerApp == null) {
14025                        String msg = "Permission Denial: not allowed to send broadcast "
14026                                + intent.getAction() + " from unknown caller.";
14027                        Slog.w(TAG, msg);
14028                        throw new SecurityException(msg);
14029                    } else if (intent.getComponent() != null) {
14030                        // They are good enough to send to an explicit component...  verify
14031                        // it is being sent to the calling app.
14032                        if (!intent.getComponent().getPackageName().equals(
14033                                callerApp.info.packageName)) {
14034                            String msg = "Permission Denial: not allowed to send broadcast "
14035                                    + intent.getAction() + " to "
14036                                    + intent.getComponent().getPackageName() + " from "
14037                                    + callerApp.info.packageName;
14038                            Slog.w(TAG, msg);
14039                            throw new SecurityException(msg);
14040                        }
14041                    } else {
14042                        // Limit broadcast to their own package.
14043                        intent.setPackage(callerApp.info.packageName);
14044                    }
14045                }
14046            } catch (RemoteException e) {
14047                Slog.w(TAG, "Remote exception", e);
14048                return ActivityManager.BROADCAST_SUCCESS;
14049            }
14050        }
14051
14052        // Handle special intents: if this broadcast is from the package
14053        // manager about a package being removed, we need to remove all of
14054        // its activities from the history stack.
14055        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14056                intent.getAction());
14057        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14058                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14059                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14060                || uidRemoved) {
14061            if (checkComponentPermission(
14062                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14063                    callingPid, callingUid, -1, true)
14064                    == PackageManager.PERMISSION_GRANTED) {
14065                if (uidRemoved) {
14066                    final Bundle intentExtras = intent.getExtras();
14067                    final int uid = intentExtras != null
14068                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14069                    if (uid >= 0) {
14070                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14071                        synchronized (bs) {
14072                            bs.removeUidStatsLocked(uid);
14073                        }
14074                        mAppOpsService.uidRemoved(uid);
14075                    }
14076                } else {
14077                    // If resources are unavailable just force stop all
14078                    // those packages and flush the attribute cache as well.
14079                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14080                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14081                        if (list != null && (list.length > 0)) {
14082                            for (String pkg : list) {
14083                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14084                                        "storage unmount");
14085                            }
14086                            sendPackageBroadcastLocked(
14087                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14088                        }
14089                    } else {
14090                        Uri data = intent.getData();
14091                        String ssp;
14092                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14093                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14094                                    intent.getAction());
14095                            boolean fullUninstall = removed &&
14096                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14097                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14098                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14099                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14100                                        false, fullUninstall, userId,
14101                                        removed ? "pkg removed" : "pkg changed");
14102                            }
14103                            if (removed) {
14104                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14105                                        new String[] {ssp}, userId);
14106                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14107                                    mAppOpsService.packageRemoved(
14108                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14109
14110                                    // Remove all permissions granted from/to this package
14111                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14112                                }
14113                            }
14114                        }
14115                    }
14116                }
14117            } else {
14118                String msg = "Permission Denial: " + intent.getAction()
14119                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14120                        + ", uid=" + callingUid + ")"
14121                        + " requires "
14122                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14123                Slog.w(TAG, msg);
14124                throw new SecurityException(msg);
14125            }
14126
14127        // Special case for adding a package: by default turn on compatibility
14128        // mode.
14129        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14130            Uri data = intent.getData();
14131            String ssp;
14132            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14133                mCompatModePackages.handlePackageAddedLocked(ssp,
14134                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14135            }
14136        }
14137
14138        /*
14139         * If this is the time zone changed action, queue up a message that will reset the timezone
14140         * of all currently running processes. This message will get queued up before the broadcast
14141         * happens.
14142         */
14143        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14144            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14145        }
14146
14147        /*
14148         * If the user set the time, let all running processes know.
14149         */
14150        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14151            final int is24Hour = intent.getBooleanExtra(
14152                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14153            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14154        }
14155
14156        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14157            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14158        }
14159
14160        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14161            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14162            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14163        }
14164
14165        // Add to the sticky list if requested.
14166        if (sticky) {
14167            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14168                    callingPid, callingUid)
14169                    != PackageManager.PERMISSION_GRANTED) {
14170                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14171                        + callingPid + ", uid=" + callingUid
14172                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14173                Slog.w(TAG, msg);
14174                throw new SecurityException(msg);
14175            }
14176            if (requiredPermission != null) {
14177                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14178                        + " and enforce permission " + requiredPermission);
14179                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14180            }
14181            if (intent.getComponent() != null) {
14182                throw new SecurityException(
14183                        "Sticky broadcasts can't target a specific component");
14184            }
14185            // We use userId directly here, since the "all" target is maintained
14186            // as a separate set of sticky broadcasts.
14187            if (userId != UserHandle.USER_ALL) {
14188                // But first, if this is not a broadcast to all users, then
14189                // make sure it doesn't conflict with an existing broadcast to
14190                // all users.
14191                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14192                        UserHandle.USER_ALL);
14193                if (stickies != null) {
14194                    ArrayList<Intent> list = stickies.get(intent.getAction());
14195                    if (list != null) {
14196                        int N = list.size();
14197                        int i;
14198                        for (i=0; i<N; i++) {
14199                            if (intent.filterEquals(list.get(i))) {
14200                                throw new IllegalArgumentException(
14201                                        "Sticky broadcast " + intent + " for user "
14202                                        + userId + " conflicts with existing global broadcast");
14203                            }
14204                        }
14205                    }
14206                }
14207            }
14208            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14209            if (stickies == null) {
14210                stickies = new ArrayMap<String, ArrayList<Intent>>();
14211                mStickyBroadcasts.put(userId, stickies);
14212            }
14213            ArrayList<Intent> list = stickies.get(intent.getAction());
14214            if (list == null) {
14215                list = new ArrayList<Intent>();
14216                stickies.put(intent.getAction(), list);
14217            }
14218            int N = list.size();
14219            int i;
14220            for (i=0; i<N; i++) {
14221                if (intent.filterEquals(list.get(i))) {
14222                    // This sticky already exists, replace it.
14223                    list.set(i, new Intent(intent));
14224                    break;
14225                }
14226            }
14227            if (i >= N) {
14228                list.add(new Intent(intent));
14229            }
14230        }
14231
14232        int[] users;
14233        if (userId == UserHandle.USER_ALL) {
14234            // Caller wants broadcast to go to all started users.
14235            users = mStartedUserArray;
14236        } else {
14237            // Caller wants broadcast to go to one specific user.
14238            users = new int[] {userId};
14239        }
14240
14241        // Figure out who all will receive this broadcast.
14242        List receivers = null;
14243        List<BroadcastFilter> registeredReceivers = null;
14244        // Need to resolve the intent to interested receivers...
14245        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14246                 == 0) {
14247            receivers = collectReceiverComponents(intent, resolvedType, users);
14248        }
14249        if (intent.getComponent() == null) {
14250            registeredReceivers = mReceiverResolver.queryIntent(intent,
14251                    resolvedType, false, userId);
14252        }
14253
14254        final boolean replacePending =
14255                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14256
14257        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14258                + " replacePending=" + replacePending);
14259
14260        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14261        if (!ordered && NR > 0) {
14262            // If we are not serializing this broadcast, then send the
14263            // registered receivers separately so they don't wait for the
14264            // components to be launched.
14265            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14266            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14267                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14268                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14269                    ordered, sticky, false, userId);
14270            if (DEBUG_BROADCAST) Slog.v(
14271                    TAG, "Enqueueing parallel broadcast " + r);
14272            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14273            if (!replaced) {
14274                queue.enqueueParallelBroadcastLocked(r);
14275                queue.scheduleBroadcastsLocked();
14276            }
14277            registeredReceivers = null;
14278            NR = 0;
14279        }
14280
14281        // Merge into one list.
14282        int ir = 0;
14283        if (receivers != null) {
14284            // A special case for PACKAGE_ADDED: do not allow the package
14285            // being added to see this broadcast.  This prevents them from
14286            // using this as a back door to get run as soon as they are
14287            // installed.  Maybe in the future we want to have a special install
14288            // broadcast or such for apps, but we'd like to deliberately make
14289            // this decision.
14290            String skipPackages[] = null;
14291            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14292                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14293                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14294                Uri data = intent.getData();
14295                if (data != null) {
14296                    String pkgName = data.getSchemeSpecificPart();
14297                    if (pkgName != null) {
14298                        skipPackages = new String[] { pkgName };
14299                    }
14300                }
14301            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14302                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14303            }
14304            if (skipPackages != null && (skipPackages.length > 0)) {
14305                for (String skipPackage : skipPackages) {
14306                    if (skipPackage != null) {
14307                        int NT = receivers.size();
14308                        for (int it=0; it<NT; it++) {
14309                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14310                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14311                                receivers.remove(it);
14312                                it--;
14313                                NT--;
14314                            }
14315                        }
14316                    }
14317                }
14318            }
14319
14320            int NT = receivers != null ? receivers.size() : 0;
14321            int it = 0;
14322            ResolveInfo curt = null;
14323            BroadcastFilter curr = null;
14324            while (it < NT && ir < NR) {
14325                if (curt == null) {
14326                    curt = (ResolveInfo)receivers.get(it);
14327                }
14328                if (curr == null) {
14329                    curr = registeredReceivers.get(ir);
14330                }
14331                if (curr.getPriority() >= curt.priority) {
14332                    // Insert this broadcast record into the final list.
14333                    receivers.add(it, curr);
14334                    ir++;
14335                    curr = null;
14336                    it++;
14337                    NT++;
14338                } else {
14339                    // Skip to the next ResolveInfo in the final list.
14340                    it++;
14341                    curt = null;
14342                }
14343            }
14344        }
14345        while (ir < NR) {
14346            if (receivers == null) {
14347                receivers = new ArrayList();
14348            }
14349            receivers.add(registeredReceivers.get(ir));
14350            ir++;
14351        }
14352
14353        if ((receivers != null && receivers.size() > 0)
14354                || resultTo != null) {
14355            BroadcastQueue queue = broadcastQueueForIntent(intent);
14356            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14357                    callerPackage, callingPid, callingUid, resolvedType,
14358                    requiredPermission, appOp, receivers, resultTo, resultCode,
14359                    resultData, map, ordered, sticky, false, userId);
14360            if (DEBUG_BROADCAST) Slog.v(
14361                    TAG, "Enqueueing ordered broadcast " + r
14362                    + ": prev had " + queue.mOrderedBroadcasts.size());
14363            if (DEBUG_BROADCAST) {
14364                int seq = r.intent.getIntExtra("seq", -1);
14365                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14366            }
14367            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14368            if (!replaced) {
14369                queue.enqueueOrderedBroadcastLocked(r);
14370                queue.scheduleBroadcastsLocked();
14371            }
14372        }
14373
14374        return ActivityManager.BROADCAST_SUCCESS;
14375    }
14376
14377    final Intent verifyBroadcastLocked(Intent intent) {
14378        // Refuse possible leaked file descriptors
14379        if (intent != null && intent.hasFileDescriptors() == true) {
14380            throw new IllegalArgumentException("File descriptors passed in Intent");
14381        }
14382
14383        int flags = intent.getFlags();
14384
14385        if (!mProcessesReady) {
14386            // if the caller really truly claims to know what they're doing, go
14387            // ahead and allow the broadcast without launching any receivers
14388            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14389                intent = new Intent(intent);
14390                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14391            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14392                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14393                        + " before boot completion");
14394                throw new IllegalStateException("Cannot broadcast before boot completed");
14395            }
14396        }
14397
14398        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14399            throw new IllegalArgumentException(
14400                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14401        }
14402
14403        return intent;
14404    }
14405
14406    public final int broadcastIntent(IApplicationThread caller,
14407            Intent intent, String resolvedType, IIntentReceiver resultTo,
14408            int resultCode, String resultData, Bundle map,
14409            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14410        enforceNotIsolatedCaller("broadcastIntent");
14411        synchronized(this) {
14412            intent = verifyBroadcastLocked(intent);
14413
14414            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14415            final int callingPid = Binder.getCallingPid();
14416            final int callingUid = Binder.getCallingUid();
14417            final long origId = Binder.clearCallingIdentity();
14418            int res = broadcastIntentLocked(callerApp,
14419                    callerApp != null ? callerApp.info.packageName : null,
14420                    intent, resolvedType, resultTo,
14421                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14422                    callingPid, callingUid, userId);
14423            Binder.restoreCallingIdentity(origId);
14424            return res;
14425        }
14426    }
14427
14428    int broadcastIntentInPackage(String packageName, int uid,
14429            Intent intent, String resolvedType, IIntentReceiver resultTo,
14430            int resultCode, String resultData, Bundle map,
14431            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14432        synchronized(this) {
14433            intent = verifyBroadcastLocked(intent);
14434
14435            final long origId = Binder.clearCallingIdentity();
14436            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14437                    resultTo, resultCode, resultData, map, requiredPermission,
14438                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14439            Binder.restoreCallingIdentity(origId);
14440            return res;
14441        }
14442    }
14443
14444    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14445        // Refuse possible leaked file descriptors
14446        if (intent != null && intent.hasFileDescriptors() == true) {
14447            throw new IllegalArgumentException("File descriptors passed in Intent");
14448        }
14449
14450        userId = handleIncomingUser(Binder.getCallingPid(),
14451                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14452
14453        synchronized(this) {
14454            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14455                    != PackageManager.PERMISSION_GRANTED) {
14456                String msg = "Permission Denial: unbroadcastIntent() from pid="
14457                        + Binder.getCallingPid()
14458                        + ", uid=" + Binder.getCallingUid()
14459                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14460                Slog.w(TAG, msg);
14461                throw new SecurityException(msg);
14462            }
14463            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14464            if (stickies != null) {
14465                ArrayList<Intent> list = stickies.get(intent.getAction());
14466                if (list != null) {
14467                    int N = list.size();
14468                    int i;
14469                    for (i=0; i<N; i++) {
14470                        if (intent.filterEquals(list.get(i))) {
14471                            list.remove(i);
14472                            break;
14473                        }
14474                    }
14475                    if (list.size() <= 0) {
14476                        stickies.remove(intent.getAction());
14477                    }
14478                }
14479                if (stickies.size() <= 0) {
14480                    mStickyBroadcasts.remove(userId);
14481                }
14482            }
14483        }
14484    }
14485
14486    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14487            String resultData, Bundle resultExtras, boolean resultAbort) {
14488        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14489        if (r == null) {
14490            Slog.w(TAG, "finishReceiver called but not found on queue");
14491            return false;
14492        }
14493
14494        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14495    }
14496
14497    void backgroundServicesFinishedLocked(int userId) {
14498        for (BroadcastQueue queue : mBroadcastQueues) {
14499            queue.backgroundServicesFinishedLocked(userId);
14500        }
14501    }
14502
14503    public void finishReceiver(IBinder who, int resultCode, String resultData,
14504            Bundle resultExtras, boolean resultAbort) {
14505        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14506
14507        // Refuse possible leaked file descriptors
14508        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14509            throw new IllegalArgumentException("File descriptors passed in Bundle");
14510        }
14511
14512        final long origId = Binder.clearCallingIdentity();
14513        try {
14514            boolean doNext = false;
14515            BroadcastRecord r;
14516
14517            synchronized(this) {
14518                r = broadcastRecordForReceiverLocked(who);
14519                if (r != null) {
14520                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14521                        resultData, resultExtras, resultAbort, true);
14522                }
14523            }
14524
14525            if (doNext) {
14526                r.queue.processNextBroadcast(false);
14527            }
14528            trimApplications();
14529        } finally {
14530            Binder.restoreCallingIdentity(origId);
14531        }
14532    }
14533
14534    // =========================================================
14535    // INSTRUMENTATION
14536    // =========================================================
14537
14538    public boolean startInstrumentation(ComponentName className,
14539            String profileFile, int flags, Bundle arguments,
14540            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14541            int userId, String abiOverride) {
14542        enforceNotIsolatedCaller("startInstrumentation");
14543        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14544                userId, false, true, "startInstrumentation", null);
14545        // Refuse possible leaked file descriptors
14546        if (arguments != null && arguments.hasFileDescriptors()) {
14547            throw new IllegalArgumentException("File descriptors passed in Bundle");
14548        }
14549
14550        synchronized(this) {
14551            InstrumentationInfo ii = null;
14552            ApplicationInfo ai = null;
14553            try {
14554                ii = mContext.getPackageManager().getInstrumentationInfo(
14555                    className, STOCK_PM_FLAGS);
14556                ai = AppGlobals.getPackageManager().getApplicationInfo(
14557                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14558            } catch (PackageManager.NameNotFoundException e) {
14559            } catch (RemoteException e) {
14560            }
14561            if (ii == null) {
14562                reportStartInstrumentationFailure(watcher, className,
14563                        "Unable to find instrumentation info for: " + className);
14564                return false;
14565            }
14566            if (ai == null) {
14567                reportStartInstrumentationFailure(watcher, className,
14568                        "Unable to find instrumentation target package: " + ii.targetPackage);
14569                return false;
14570            }
14571
14572            int match = mContext.getPackageManager().checkSignatures(
14573                    ii.targetPackage, ii.packageName);
14574            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14575                String msg = "Permission Denial: starting instrumentation "
14576                        + className + " from pid="
14577                        + Binder.getCallingPid()
14578                        + ", uid=" + Binder.getCallingPid()
14579                        + " not allowed because package " + ii.packageName
14580                        + " does not have a signature matching the target "
14581                        + ii.targetPackage;
14582                reportStartInstrumentationFailure(watcher, className, msg);
14583                throw new SecurityException(msg);
14584            }
14585
14586            final long origId = Binder.clearCallingIdentity();
14587            // Instrumentation can kill and relaunch even persistent processes
14588            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14589                    "start instr");
14590            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14591            app.instrumentationClass = className;
14592            app.instrumentationInfo = ai;
14593            app.instrumentationProfileFile = profileFile;
14594            app.instrumentationArguments = arguments;
14595            app.instrumentationWatcher = watcher;
14596            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14597            app.instrumentationResultClass = className;
14598            Binder.restoreCallingIdentity(origId);
14599        }
14600
14601        return true;
14602    }
14603
14604    /**
14605     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14606     * error to the logs, but if somebody is watching, send the report there too.  This enables
14607     * the "am" command to report errors with more information.
14608     *
14609     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14610     * @param cn The component name of the instrumentation.
14611     * @param report The error report.
14612     */
14613    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14614            ComponentName cn, String report) {
14615        Slog.w(TAG, report);
14616        try {
14617            if (watcher != null) {
14618                Bundle results = new Bundle();
14619                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14620                results.putString("Error", report);
14621                watcher.instrumentationStatus(cn, -1, results);
14622            }
14623        } catch (RemoteException e) {
14624            Slog.w(TAG, e);
14625        }
14626    }
14627
14628    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14629        if (app.instrumentationWatcher != null) {
14630            try {
14631                // NOTE:  IInstrumentationWatcher *must* be oneway here
14632                app.instrumentationWatcher.instrumentationFinished(
14633                    app.instrumentationClass,
14634                    resultCode,
14635                    results);
14636            } catch (RemoteException e) {
14637            }
14638        }
14639        if (app.instrumentationUiAutomationConnection != null) {
14640            try {
14641                app.instrumentationUiAutomationConnection.shutdown();
14642            } catch (RemoteException re) {
14643                /* ignore */
14644            }
14645            // Only a UiAutomation can set this flag and now that
14646            // it is finished we make sure it is reset to its default.
14647            mUserIsMonkey = false;
14648        }
14649        app.instrumentationWatcher = null;
14650        app.instrumentationUiAutomationConnection = null;
14651        app.instrumentationClass = null;
14652        app.instrumentationInfo = null;
14653        app.instrumentationProfileFile = null;
14654        app.instrumentationArguments = null;
14655
14656        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14657                "finished inst");
14658    }
14659
14660    public void finishInstrumentation(IApplicationThread target,
14661            int resultCode, Bundle results) {
14662        int userId = UserHandle.getCallingUserId();
14663        // Refuse possible leaked file descriptors
14664        if (results != null && results.hasFileDescriptors()) {
14665            throw new IllegalArgumentException("File descriptors passed in Intent");
14666        }
14667
14668        synchronized(this) {
14669            ProcessRecord app = getRecordForAppLocked(target);
14670            if (app == null) {
14671                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14672                return;
14673            }
14674            final long origId = Binder.clearCallingIdentity();
14675            finishInstrumentationLocked(app, resultCode, results);
14676            Binder.restoreCallingIdentity(origId);
14677        }
14678    }
14679
14680    // =========================================================
14681    // CONFIGURATION
14682    // =========================================================
14683
14684    public ConfigurationInfo getDeviceConfigurationInfo() {
14685        ConfigurationInfo config = new ConfigurationInfo();
14686        synchronized (this) {
14687            config.reqTouchScreen = mConfiguration.touchscreen;
14688            config.reqKeyboardType = mConfiguration.keyboard;
14689            config.reqNavigation = mConfiguration.navigation;
14690            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14691                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14692                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14693            }
14694            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14695                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14696                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14697            }
14698            config.reqGlEsVersion = GL_ES_VERSION;
14699        }
14700        return config;
14701    }
14702
14703    ActivityStack getFocusedStack() {
14704        return mStackSupervisor.getFocusedStack();
14705    }
14706
14707    public Configuration getConfiguration() {
14708        Configuration ci;
14709        synchronized(this) {
14710            ci = new Configuration(mConfiguration);
14711        }
14712        return ci;
14713    }
14714
14715    public void updatePersistentConfiguration(Configuration values) {
14716        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14717                "updateConfiguration()");
14718        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14719                "updateConfiguration()");
14720        if (values == null) {
14721            throw new NullPointerException("Configuration must not be null");
14722        }
14723
14724        synchronized(this) {
14725            final long origId = Binder.clearCallingIdentity();
14726            updateConfigurationLocked(values, null, true, false);
14727            Binder.restoreCallingIdentity(origId);
14728        }
14729    }
14730
14731    public void updateConfiguration(Configuration values) {
14732        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14733                "updateConfiguration()");
14734
14735        synchronized(this) {
14736            if (values == null && mWindowManager != null) {
14737                // sentinel: fetch the current configuration from the window manager
14738                values = mWindowManager.computeNewConfiguration();
14739            }
14740
14741            if (mWindowManager != null) {
14742                mProcessList.applyDisplaySize(mWindowManager);
14743            }
14744
14745            final long origId = Binder.clearCallingIdentity();
14746            if (values != null) {
14747                Settings.System.clearConfiguration(values);
14748            }
14749            updateConfigurationLocked(values, null, false, false);
14750            Binder.restoreCallingIdentity(origId);
14751        }
14752    }
14753
14754    /**
14755     * Do either or both things: (1) change the current configuration, and (2)
14756     * make sure the given activity is running with the (now) current
14757     * configuration.  Returns true if the activity has been left running, or
14758     * false if <var>starting</var> is being destroyed to match the new
14759     * configuration.
14760     * @param persistent TODO
14761     */
14762    boolean updateConfigurationLocked(Configuration values,
14763            ActivityRecord starting, boolean persistent, boolean initLocale) {
14764        int changes = 0;
14765
14766        if (values != null) {
14767            Configuration newConfig = new Configuration(mConfiguration);
14768            changes = newConfig.updateFrom(values);
14769            if (changes != 0) {
14770                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14771                    Slog.i(TAG, "Updating configuration to: " + values);
14772                }
14773
14774                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14775
14776                if (values.locale != null && !initLocale) {
14777                    saveLocaleLocked(values.locale,
14778                                     !values.locale.equals(mConfiguration.locale),
14779                                     values.userSetLocale);
14780                }
14781
14782                mConfigurationSeq++;
14783                if (mConfigurationSeq <= 0) {
14784                    mConfigurationSeq = 1;
14785                }
14786                newConfig.seq = mConfigurationSeq;
14787                mConfiguration = newConfig;
14788                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14789                mUsageStatsService.noteStartConfig(newConfig);
14790
14791                final Configuration configCopy = new Configuration(mConfiguration);
14792
14793                // TODO: If our config changes, should we auto dismiss any currently
14794                // showing dialogs?
14795                mShowDialogs = shouldShowDialogs(newConfig);
14796
14797                AttributeCache ac = AttributeCache.instance();
14798                if (ac != null) {
14799                    ac.updateConfiguration(configCopy);
14800                }
14801
14802                // Make sure all resources in our process are updated
14803                // right now, so that anyone who is going to retrieve
14804                // resource values after we return will be sure to get
14805                // the new ones.  This is especially important during
14806                // boot, where the first config change needs to guarantee
14807                // all resources have that config before following boot
14808                // code is executed.
14809                mSystemThread.applyConfigurationToResources(configCopy);
14810
14811                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14812                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14813                    msg.obj = new Configuration(configCopy);
14814                    mHandler.sendMessage(msg);
14815                }
14816
14817                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14818                    ProcessRecord app = mLruProcesses.get(i);
14819                    try {
14820                        if (app.thread != null) {
14821                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14822                                    + app.processName + " new config " + mConfiguration);
14823                            app.thread.scheduleConfigurationChanged(configCopy);
14824                        }
14825                    } catch (Exception e) {
14826                    }
14827                }
14828                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14829                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14830                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14831                        | Intent.FLAG_RECEIVER_FOREGROUND);
14832                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14833                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14834                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14835                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14836                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14837                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14838                    broadcastIntentLocked(null, null, intent,
14839                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14840                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14841                }
14842            }
14843        }
14844
14845        boolean kept = true;
14846        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14847        // mainStack is null during startup.
14848        if (mainStack != null) {
14849            if (changes != 0 && starting == null) {
14850                // If the configuration changed, and the caller is not already
14851                // in the process of starting an activity, then find the top
14852                // activity to check if its configuration needs to change.
14853                starting = mainStack.topRunningActivityLocked(null);
14854            }
14855
14856            if (starting != null) {
14857                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14858                // And we need to make sure at this point that all other activities
14859                // are made visible with the correct configuration.
14860                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14861            }
14862        }
14863
14864        if (values != null && mWindowManager != null) {
14865            mWindowManager.setNewConfiguration(mConfiguration);
14866        }
14867
14868        return kept;
14869    }
14870
14871    /**
14872     * Decide based on the configuration whether we should shouw the ANR,
14873     * crash, etc dialogs.  The idea is that if there is no affordnace to
14874     * press the on-screen buttons, we shouldn't show the dialog.
14875     *
14876     * A thought: SystemUI might also want to get told about this, the Power
14877     * dialog / global actions also might want different behaviors.
14878     */
14879    private static final boolean shouldShowDialogs(Configuration config) {
14880        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14881                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14882    }
14883
14884    /**
14885     * Save the locale.  You must be inside a synchronized (this) block.
14886     */
14887    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14888        if(isDiff) {
14889            SystemProperties.set("user.language", l.getLanguage());
14890            SystemProperties.set("user.region", l.getCountry());
14891        }
14892
14893        if(isPersist) {
14894            SystemProperties.set("persist.sys.language", l.getLanguage());
14895            SystemProperties.set("persist.sys.country", l.getCountry());
14896            SystemProperties.set("persist.sys.localevar", l.getVariant());
14897        }
14898    }
14899
14900    @Override
14901    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14902        ActivityRecord srec = ActivityRecord.forToken(token);
14903        return srec != null && srec.task.affinity != null &&
14904                srec.task.affinity.equals(destAffinity);
14905    }
14906
14907    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14908            Intent resultData) {
14909
14910        synchronized (this) {
14911            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14912            if (stack != null) {
14913                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14914            }
14915            return false;
14916        }
14917    }
14918
14919    public int getLaunchedFromUid(IBinder activityToken) {
14920        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14921        if (srec == null) {
14922            return -1;
14923        }
14924        return srec.launchedFromUid;
14925    }
14926
14927    public String getLaunchedFromPackage(IBinder activityToken) {
14928        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14929        if (srec == null) {
14930            return null;
14931        }
14932        return srec.launchedFromPackage;
14933    }
14934
14935    // =========================================================
14936    // LIFETIME MANAGEMENT
14937    // =========================================================
14938
14939    // Returns which broadcast queue the app is the current [or imminent] receiver
14940    // on, or 'null' if the app is not an active broadcast recipient.
14941    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14942        BroadcastRecord r = app.curReceiver;
14943        if (r != null) {
14944            return r.queue;
14945        }
14946
14947        // It's not the current receiver, but it might be starting up to become one
14948        synchronized (this) {
14949            for (BroadcastQueue queue : mBroadcastQueues) {
14950                r = queue.mPendingBroadcast;
14951                if (r != null && r.curApp == app) {
14952                    // found it; report which queue it's in
14953                    return queue;
14954                }
14955            }
14956        }
14957
14958        return null;
14959    }
14960
14961    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14962            boolean doingAll, long now) {
14963        if (mAdjSeq == app.adjSeq) {
14964            // This adjustment has already been computed.
14965            return app.curRawAdj;
14966        }
14967
14968        if (app.thread == null) {
14969            app.adjSeq = mAdjSeq;
14970            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14971            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14972            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14973        }
14974
14975        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14976        app.adjSource = null;
14977        app.adjTarget = null;
14978        app.empty = false;
14979        app.cached = false;
14980
14981        final int activitiesSize = app.activities.size();
14982
14983        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14984            // The max adjustment doesn't allow this app to be anything
14985            // below foreground, so it is not worth doing work for it.
14986            app.adjType = "fixed";
14987            app.adjSeq = mAdjSeq;
14988            app.curRawAdj = app.maxAdj;
14989            app.foregroundActivities = false;
14990            app.keeping = true;
14991            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14992            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14993            // System processes can do UI, and when they do we want to have
14994            // them trim their memory after the user leaves the UI.  To
14995            // facilitate this, here we need to determine whether or not it
14996            // is currently showing UI.
14997            app.systemNoUi = true;
14998            if (app == TOP_APP) {
14999                app.systemNoUi = false;
15000            } else if (activitiesSize > 0) {
15001                for (int j = 0; j < activitiesSize; j++) {
15002                    final ActivityRecord r = app.activities.get(j);
15003                    if (r.visible) {
15004                        app.systemNoUi = false;
15005                    }
15006                }
15007            }
15008            if (!app.systemNoUi) {
15009                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15010            }
15011            return (app.curAdj=app.maxAdj);
15012        }
15013
15014        app.keeping = false;
15015        app.systemNoUi = false;
15016
15017        // Determine the importance of the process, starting with most
15018        // important to least, and assign an appropriate OOM adjustment.
15019        int adj;
15020        int schedGroup;
15021        int procState;
15022        boolean foregroundActivities = false;
15023        boolean interesting = false;
15024        BroadcastQueue queue;
15025        if (app == TOP_APP) {
15026            // The last app on the list is the foreground app.
15027            adj = ProcessList.FOREGROUND_APP_ADJ;
15028            schedGroup = Process.THREAD_GROUP_DEFAULT;
15029            app.adjType = "top-activity";
15030            foregroundActivities = true;
15031            interesting = true;
15032            procState = ActivityManager.PROCESS_STATE_TOP;
15033        } else if (app.instrumentationClass != null) {
15034            // Don't want to kill running instrumentation.
15035            adj = ProcessList.FOREGROUND_APP_ADJ;
15036            schedGroup = Process.THREAD_GROUP_DEFAULT;
15037            app.adjType = "instrumentation";
15038            interesting = true;
15039            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15040        } else if ((queue = isReceivingBroadcast(app)) != null) {
15041            // An app that is currently receiving a broadcast also
15042            // counts as being in the foreground for OOM killer purposes.
15043            // It's placed in a sched group based on the nature of the
15044            // broadcast as reflected by which queue it's active in.
15045            adj = ProcessList.FOREGROUND_APP_ADJ;
15046            schedGroup = (queue == mFgBroadcastQueue)
15047                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15048            app.adjType = "broadcast";
15049            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15050        } else if (app.executingServices.size() > 0) {
15051            // An app that is currently executing a service callback also
15052            // counts as being in the foreground.
15053            adj = ProcessList.FOREGROUND_APP_ADJ;
15054            schedGroup = app.execServicesFg ?
15055                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15056            app.adjType = "exec-service";
15057            procState = ActivityManager.PROCESS_STATE_SERVICE;
15058            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15059        } else {
15060            // As far as we know the process is empty.  We may change our mind later.
15061            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15062            // At this point we don't actually know the adjustment.  Use the cached adj
15063            // value that the caller wants us to.
15064            adj = cachedAdj;
15065            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15066            app.cached = true;
15067            app.empty = true;
15068            app.adjType = "cch-empty";
15069        }
15070
15071        // Examine all activities if not already foreground.
15072        if (!foregroundActivities && activitiesSize > 0) {
15073            for (int j = 0; j < activitiesSize; j++) {
15074                final ActivityRecord r = app.activities.get(j);
15075                if (r.app != app) {
15076                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15077                            + app + "?!?");
15078                    continue;
15079                }
15080                if (r.visible) {
15081                    // App has a visible activity; only upgrade adjustment.
15082                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15083                        adj = ProcessList.VISIBLE_APP_ADJ;
15084                        app.adjType = "visible";
15085                    }
15086                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15087                        procState = ActivityManager.PROCESS_STATE_TOP;
15088                    }
15089                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15090                    app.cached = false;
15091                    app.empty = false;
15092                    foregroundActivities = true;
15093                    break;
15094                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15095                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15096                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15097                        app.adjType = "pausing";
15098                    }
15099                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15100                        procState = ActivityManager.PROCESS_STATE_TOP;
15101                    }
15102                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15103                    app.cached = false;
15104                    app.empty = false;
15105                    foregroundActivities = true;
15106                } else if (r.state == ActivityState.STOPPING) {
15107                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15108                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15109                        app.adjType = "stopping";
15110                    }
15111                    // For the process state, we will at this point consider the
15112                    // process to be cached.  It will be cached either as an activity
15113                    // or empty depending on whether the activity is finishing.  We do
15114                    // this so that we can treat the process as cached for purposes of
15115                    // memory trimming (determing current memory level, trim command to
15116                    // send to process) since there can be an arbitrary number of stopping
15117                    // processes and they should soon all go into the cached state.
15118                    if (!r.finishing) {
15119                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15120                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15121                        }
15122                    }
15123                    app.cached = false;
15124                    app.empty = false;
15125                    foregroundActivities = true;
15126                } else {
15127                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15128                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15129                        app.adjType = "cch-act";
15130                    }
15131                }
15132            }
15133        }
15134
15135        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15136            if (app.foregroundServices) {
15137                // The user is aware of this app, so make it visible.
15138                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15139                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15140                app.cached = false;
15141                app.adjType = "fg-service";
15142                schedGroup = Process.THREAD_GROUP_DEFAULT;
15143            } else if (app.forcingToForeground != null) {
15144                // The user is aware of this app, so make it visible.
15145                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15146                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15147                app.cached = false;
15148                app.adjType = "force-fg";
15149                app.adjSource = app.forcingToForeground;
15150                schedGroup = Process.THREAD_GROUP_DEFAULT;
15151            }
15152        }
15153
15154        if (app.foregroundServices) {
15155            interesting = true;
15156        }
15157
15158        if (app == mHeavyWeightProcess) {
15159            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15160                // We don't want to kill the current heavy-weight process.
15161                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15162                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15163                app.cached = false;
15164                app.adjType = "heavy";
15165            }
15166            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15167                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15168            }
15169        }
15170
15171        if (app == mHomeProcess) {
15172            if (adj > ProcessList.HOME_APP_ADJ) {
15173                // This process is hosting what we currently consider to be the
15174                // home app, so we don't want to let it go into the background.
15175                adj = ProcessList.HOME_APP_ADJ;
15176                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15177                app.cached = false;
15178                app.adjType = "home";
15179            }
15180            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15181                procState = ActivityManager.PROCESS_STATE_HOME;
15182            }
15183        }
15184
15185        if (app == mPreviousProcess && app.activities.size() > 0) {
15186            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15187                // This was the previous process that showed UI to the user.
15188                // We want to try to keep it around more aggressively, to give
15189                // a good experience around switching between two apps.
15190                adj = ProcessList.PREVIOUS_APP_ADJ;
15191                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15192                app.cached = false;
15193                app.adjType = "previous";
15194            }
15195            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15196                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15197            }
15198        }
15199
15200        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15201                + " reason=" + app.adjType);
15202
15203        // By default, we use the computed adjustment.  It may be changed if
15204        // there are applications dependent on our services or providers, but
15205        // this gives us a baseline and makes sure we don't get into an
15206        // infinite recursion.
15207        app.adjSeq = mAdjSeq;
15208        app.curRawAdj = adj;
15209        app.hasStartedServices = false;
15210
15211        if (mBackupTarget != null && app == mBackupTarget.app) {
15212            // If possible we want to avoid killing apps while they're being backed up
15213            if (adj > ProcessList.BACKUP_APP_ADJ) {
15214                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15215                adj = ProcessList.BACKUP_APP_ADJ;
15216                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15217                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15218                }
15219                app.adjType = "backup";
15220                app.cached = false;
15221            }
15222            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15223                procState = ActivityManager.PROCESS_STATE_BACKUP;
15224            }
15225        }
15226
15227        boolean mayBeTop = false;
15228
15229        for (int is = app.services.size()-1;
15230                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15231                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15232                        || procState > ActivityManager.PROCESS_STATE_TOP);
15233                is--) {
15234            ServiceRecord s = app.services.valueAt(is);
15235            if (s.startRequested) {
15236                app.hasStartedServices = true;
15237                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15238                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15239                }
15240                if (app.hasShownUi && app != mHomeProcess) {
15241                    // If this process has shown some UI, let it immediately
15242                    // go to the LRU list because it may be pretty heavy with
15243                    // UI stuff.  We'll tag it with a label just to help
15244                    // debug and understand what is going on.
15245                    if (adj > ProcessList.SERVICE_ADJ) {
15246                        app.adjType = "cch-started-ui-services";
15247                    }
15248                } else {
15249                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15250                        // This service has seen some activity within
15251                        // recent memory, so we will keep its process ahead
15252                        // of the background processes.
15253                        if (adj > ProcessList.SERVICE_ADJ) {
15254                            adj = ProcessList.SERVICE_ADJ;
15255                            app.adjType = "started-services";
15256                            app.cached = false;
15257                        }
15258                    }
15259                    // If we have let the service slide into the background
15260                    // state, still have some text describing what it is doing
15261                    // even though the service no longer has an impact.
15262                    if (adj > ProcessList.SERVICE_ADJ) {
15263                        app.adjType = "cch-started-services";
15264                    }
15265                }
15266                // Don't kill this process because it is doing work; it
15267                // has said it is doing work.
15268                app.keeping = true;
15269            }
15270            for (int conni = s.connections.size()-1;
15271                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15272                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15273                            || procState > ActivityManager.PROCESS_STATE_TOP);
15274                    conni--) {
15275                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15276                for (int i = 0;
15277                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15278                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15279                                || procState > ActivityManager.PROCESS_STATE_TOP);
15280                        i++) {
15281                    // XXX should compute this based on the max of
15282                    // all connected clients.
15283                    ConnectionRecord cr = clist.get(i);
15284                    if (cr.binding.client == app) {
15285                        // Binding to ourself is not interesting.
15286                        continue;
15287                    }
15288                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15289                        ProcessRecord client = cr.binding.client;
15290                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15291                                TOP_APP, doingAll, now);
15292                        int clientProcState = client.curProcState;
15293                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15294                            // If the other app is cached for any reason, for purposes here
15295                            // we are going to consider it empty.  The specific cached state
15296                            // doesn't propagate except under certain conditions.
15297                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15298                        }
15299                        String adjType = null;
15300                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15301                            // Not doing bind OOM management, so treat
15302                            // this guy more like a started service.
15303                            if (app.hasShownUi && app != mHomeProcess) {
15304                                // If this process has shown some UI, let it immediately
15305                                // go to the LRU list because it may be pretty heavy with
15306                                // UI stuff.  We'll tag it with a label just to help
15307                                // debug and understand what is going on.
15308                                if (adj > clientAdj) {
15309                                    adjType = "cch-bound-ui-services";
15310                                }
15311                                app.cached = false;
15312                                clientAdj = adj;
15313                                clientProcState = procState;
15314                            } else {
15315                                if (now >= (s.lastActivity
15316                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15317                                    // This service has not seen activity within
15318                                    // recent memory, so allow it to drop to the
15319                                    // LRU list if there is no other reason to keep
15320                                    // it around.  We'll also tag it with a label just
15321                                    // to help debug and undertand what is going on.
15322                                    if (adj > clientAdj) {
15323                                        adjType = "cch-bound-services";
15324                                    }
15325                                    clientAdj = adj;
15326                                }
15327                            }
15328                        }
15329                        if (adj > clientAdj) {
15330                            // If this process has recently shown UI, and
15331                            // the process that is binding to it is less
15332                            // important than being visible, then we don't
15333                            // care about the binding as much as we care
15334                            // about letting this process get into the LRU
15335                            // list to be killed and restarted if needed for
15336                            // memory.
15337                            if (app.hasShownUi && app != mHomeProcess
15338                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15339                                adjType = "cch-bound-ui-services";
15340                            } else {
15341                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15342                                        |Context.BIND_IMPORTANT)) != 0) {
15343                                    adj = clientAdj;
15344                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15345                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15346                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15347                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15348                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15349                                    adj = clientAdj;
15350                                } else {
15351                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15352                                        adj = ProcessList.VISIBLE_APP_ADJ;
15353                                    }
15354                                }
15355                                if (!client.cached) {
15356                                    app.cached = false;
15357                                }
15358                                if (client.keeping) {
15359                                    app.keeping = true;
15360                                }
15361                                adjType = "service";
15362                            }
15363                        }
15364                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15365                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15366                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15367                            }
15368                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15369                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15370                                    // Special handling of clients who are in the top state.
15371                                    // We *may* want to consider this process to be in the
15372                                    // top state as well, but only if there is not another
15373                                    // reason for it to be running.  Being on the top is a
15374                                    // special state, meaning you are specifically running
15375                                    // for the current top app.  If the process is already
15376                                    // running in the background for some other reason, it
15377                                    // is more important to continue considering it to be
15378                                    // in the background state.
15379                                    mayBeTop = true;
15380                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15381                                } else {
15382                                    // Special handling for above-top states (persistent
15383                                    // processes).  These should not bring the current process
15384                                    // into the top state, since they are not on top.  Instead
15385                                    // give them the best state after that.
15386                                    clientProcState =
15387                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15388                                }
15389                            }
15390                        } else {
15391                            if (clientProcState <
15392                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15393                                clientProcState =
15394                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15395                            }
15396                        }
15397                        if (procState > clientProcState) {
15398                            procState = clientProcState;
15399                        }
15400                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15401                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15402                            app.pendingUiClean = true;
15403                        }
15404                        if (adjType != null) {
15405                            app.adjType = adjType;
15406                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15407                                    .REASON_SERVICE_IN_USE;
15408                            app.adjSource = cr.binding.client;
15409                            app.adjSourceOom = clientAdj;
15410                            app.adjTarget = s.name;
15411                        }
15412                    }
15413                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15414                        app.treatLikeActivity = true;
15415                    }
15416                    final ActivityRecord a = cr.activity;
15417                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15418                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15419                                (a.visible || a.state == ActivityState.RESUMED
15420                                 || a.state == ActivityState.PAUSING)) {
15421                            adj = ProcessList.FOREGROUND_APP_ADJ;
15422                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15423                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15424                            }
15425                            app.cached = false;
15426                            app.adjType = "service";
15427                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15428                                    .REASON_SERVICE_IN_USE;
15429                            app.adjSource = a;
15430                            app.adjSourceOom = adj;
15431                            app.adjTarget = s.name;
15432                        }
15433                    }
15434                }
15435            }
15436        }
15437
15438        for (int provi = app.pubProviders.size()-1;
15439                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15440                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15441                        || procState > ActivityManager.PROCESS_STATE_TOP);
15442                provi--) {
15443            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15444            for (int i = cpr.connections.size()-1;
15445                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15446                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15447                            || procState > ActivityManager.PROCESS_STATE_TOP);
15448                    i--) {
15449                ContentProviderConnection conn = cpr.connections.get(i);
15450                ProcessRecord client = conn.client;
15451                if (client == app) {
15452                    // Being our own client is not interesting.
15453                    continue;
15454                }
15455                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15456                int clientProcState = client.curProcState;
15457                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15458                    // If the other app is cached for any reason, for purposes here
15459                    // we are going to consider it empty.
15460                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15461                }
15462                if (adj > clientAdj) {
15463                    if (app.hasShownUi && app != mHomeProcess
15464                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15465                        app.adjType = "cch-ui-provider";
15466                    } else {
15467                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15468                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15469                        app.adjType = "provider";
15470                    }
15471                    app.cached &= client.cached;
15472                    app.keeping |= client.keeping;
15473                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15474                            .REASON_PROVIDER_IN_USE;
15475                    app.adjSource = client;
15476                    app.adjSourceOom = clientAdj;
15477                    app.adjTarget = cpr.name;
15478                }
15479                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15480                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15481                        // Special handling of clients who are in the top state.
15482                        // We *may* want to consider this process to be in the
15483                        // top state as well, but only if there is not another
15484                        // reason for it to be running.  Being on the top is a
15485                        // special state, meaning you are specifically running
15486                        // for the current top app.  If the process is already
15487                        // running in the background for some other reason, it
15488                        // is more important to continue considering it to be
15489                        // in the background state.
15490                        mayBeTop = true;
15491                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15492                    } else {
15493                        // Special handling for above-top states (persistent
15494                        // processes).  These should not bring the current process
15495                        // into the top state, since they are not on top.  Instead
15496                        // give them the best state after that.
15497                        clientProcState =
15498                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15499                    }
15500                }
15501                if (procState > clientProcState) {
15502                    procState = clientProcState;
15503                }
15504                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15505                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15506                }
15507            }
15508            // If the provider has external (non-framework) process
15509            // dependencies, ensure that its adjustment is at least
15510            // FOREGROUND_APP_ADJ.
15511            if (cpr.hasExternalProcessHandles()) {
15512                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15513                    adj = ProcessList.FOREGROUND_APP_ADJ;
15514                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15515                    app.cached = false;
15516                    app.keeping = true;
15517                    app.adjType = "provider";
15518                    app.adjTarget = cpr.name;
15519                }
15520                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15521                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15522                }
15523            }
15524        }
15525
15526        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15527            // A client of one of our services or providers is in the top state.  We
15528            // *may* want to be in the top state, but not if we are already running in
15529            // the background for some other reason.  For the decision here, we are going
15530            // to pick out a few specific states that we want to remain in when a client
15531            // is top (states that tend to be longer-term) and otherwise allow it to go
15532            // to the top state.
15533            switch (procState) {
15534                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15535                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15536                case ActivityManager.PROCESS_STATE_SERVICE:
15537                    // These all are longer-term states, so pull them up to the top
15538                    // of the background states, but not all the way to the top state.
15539                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15540                    break;
15541                default:
15542                    // Otherwise, top is a better choice, so take it.
15543                    procState = ActivityManager.PROCESS_STATE_TOP;
15544                    break;
15545            }
15546        }
15547
15548        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15549            if (app.hasClientActivities) {
15550                // This is a cached process, but with client activities.  Mark it so.
15551                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15552                app.adjType = "cch-client-act";
15553            } else if (app.treatLikeActivity) {
15554                // This is a cached process, but somebody wants us to treat it like it has
15555                // an activity, okay!
15556                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15557                app.adjType = "cch-as-act";
15558            }
15559        }
15560
15561        if (adj == ProcessList.SERVICE_ADJ) {
15562            if (doingAll) {
15563                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15564                mNewNumServiceProcs++;
15565                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15566                if (!app.serviceb) {
15567                    // This service isn't far enough down on the LRU list to
15568                    // normally be a B service, but if we are low on RAM and it
15569                    // is large we want to force it down since we would prefer to
15570                    // keep launcher over it.
15571                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15572                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15573                        app.serviceHighRam = true;
15574                        app.serviceb = true;
15575                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15576                    } else {
15577                        mNewNumAServiceProcs++;
15578                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15579                    }
15580                } else {
15581                    app.serviceHighRam = false;
15582                }
15583            }
15584            if (app.serviceb) {
15585                adj = ProcessList.SERVICE_B_ADJ;
15586            }
15587        }
15588
15589        app.curRawAdj = adj;
15590
15591        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15592        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15593        if (adj > app.maxAdj) {
15594            adj = app.maxAdj;
15595            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15596                schedGroup = Process.THREAD_GROUP_DEFAULT;
15597            }
15598        }
15599        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15600            app.keeping = true;
15601        }
15602
15603        // Do final modification to adj.  Everything we do between here and applying
15604        // the final setAdj must be done in this function, because we will also use
15605        // it when computing the final cached adj later.  Note that we don't need to
15606        // worry about this for max adj above, since max adj will always be used to
15607        // keep it out of the cached vaues.
15608        app.curAdj = app.modifyRawOomAdj(adj);
15609        app.curSchedGroup = schedGroup;
15610        app.curProcState = procState;
15611        app.foregroundActivities = foregroundActivities;
15612
15613        return app.curRawAdj;
15614    }
15615
15616    /**
15617     * Schedule PSS collection of a process.
15618     */
15619    void requestPssLocked(ProcessRecord proc, int procState) {
15620        if (mPendingPssProcesses.contains(proc)) {
15621            return;
15622        }
15623        if (mPendingPssProcesses.size() == 0) {
15624            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15625        }
15626        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15627        proc.pssProcState = procState;
15628        mPendingPssProcesses.add(proc);
15629    }
15630
15631    /**
15632     * Schedule PSS collection of all processes.
15633     */
15634    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15635        if (!always) {
15636            if (now < (mLastFullPssTime +
15637                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15638                return;
15639            }
15640        }
15641        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15642        mLastFullPssTime = now;
15643        mFullPssPending = true;
15644        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15645        mPendingPssProcesses.clear();
15646        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15647            ProcessRecord app = mLruProcesses.get(i);
15648            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15649                app.pssProcState = app.setProcState;
15650                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15651                        isSleeping(), now);
15652                mPendingPssProcesses.add(app);
15653            }
15654        }
15655        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15656    }
15657
15658    /**
15659     * Ask a given process to GC right now.
15660     */
15661    final void performAppGcLocked(ProcessRecord app) {
15662        try {
15663            app.lastRequestedGc = SystemClock.uptimeMillis();
15664            if (app.thread != null) {
15665                if (app.reportLowMemory) {
15666                    app.reportLowMemory = false;
15667                    app.thread.scheduleLowMemory();
15668                } else {
15669                    app.thread.processInBackground();
15670                }
15671            }
15672        } catch (Exception e) {
15673            // whatever.
15674        }
15675    }
15676
15677    /**
15678     * Returns true if things are idle enough to perform GCs.
15679     */
15680    private final boolean canGcNowLocked() {
15681        boolean processingBroadcasts = false;
15682        for (BroadcastQueue q : mBroadcastQueues) {
15683            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15684                processingBroadcasts = true;
15685            }
15686        }
15687        return !processingBroadcasts
15688                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15689    }
15690
15691    /**
15692     * Perform GCs on all processes that are waiting for it, but only
15693     * if things are idle.
15694     */
15695    final void performAppGcsLocked() {
15696        final int N = mProcessesToGc.size();
15697        if (N <= 0) {
15698            return;
15699        }
15700        if (canGcNowLocked()) {
15701            while (mProcessesToGc.size() > 0) {
15702                ProcessRecord proc = mProcessesToGc.remove(0);
15703                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15704                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15705                            <= SystemClock.uptimeMillis()) {
15706                        // To avoid spamming the system, we will GC processes one
15707                        // at a time, waiting a few seconds between each.
15708                        performAppGcLocked(proc);
15709                        scheduleAppGcsLocked();
15710                        return;
15711                    } else {
15712                        // It hasn't been long enough since we last GCed this
15713                        // process...  put it in the list to wait for its time.
15714                        addProcessToGcListLocked(proc);
15715                        break;
15716                    }
15717                }
15718            }
15719
15720            scheduleAppGcsLocked();
15721        }
15722    }
15723
15724    /**
15725     * If all looks good, perform GCs on all processes waiting for them.
15726     */
15727    final void performAppGcsIfAppropriateLocked() {
15728        if (canGcNowLocked()) {
15729            performAppGcsLocked();
15730            return;
15731        }
15732        // Still not idle, wait some more.
15733        scheduleAppGcsLocked();
15734    }
15735
15736    /**
15737     * Schedule the execution of all pending app GCs.
15738     */
15739    final void scheduleAppGcsLocked() {
15740        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15741
15742        if (mProcessesToGc.size() > 0) {
15743            // Schedule a GC for the time to the next process.
15744            ProcessRecord proc = mProcessesToGc.get(0);
15745            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15746
15747            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15748            long now = SystemClock.uptimeMillis();
15749            if (when < (now+GC_TIMEOUT)) {
15750                when = now + GC_TIMEOUT;
15751            }
15752            mHandler.sendMessageAtTime(msg, when);
15753        }
15754    }
15755
15756    /**
15757     * Add a process to the array of processes waiting to be GCed.  Keeps the
15758     * list in sorted order by the last GC time.  The process can't already be
15759     * on the list.
15760     */
15761    final void addProcessToGcListLocked(ProcessRecord proc) {
15762        boolean added = false;
15763        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15764            if (mProcessesToGc.get(i).lastRequestedGc <
15765                    proc.lastRequestedGc) {
15766                added = true;
15767                mProcessesToGc.add(i+1, proc);
15768                break;
15769            }
15770        }
15771        if (!added) {
15772            mProcessesToGc.add(0, proc);
15773        }
15774    }
15775
15776    /**
15777     * Set up to ask a process to GC itself.  This will either do it
15778     * immediately, or put it on the list of processes to gc the next
15779     * time things are idle.
15780     */
15781    final void scheduleAppGcLocked(ProcessRecord app) {
15782        long now = SystemClock.uptimeMillis();
15783        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15784            return;
15785        }
15786        if (!mProcessesToGc.contains(app)) {
15787            addProcessToGcListLocked(app);
15788            scheduleAppGcsLocked();
15789        }
15790    }
15791
15792    final void checkExcessivePowerUsageLocked(boolean doKills) {
15793        updateCpuStatsNow();
15794
15795        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15796        boolean doWakeKills = doKills;
15797        boolean doCpuKills = doKills;
15798        if (mLastPowerCheckRealtime == 0) {
15799            doWakeKills = false;
15800        }
15801        if (mLastPowerCheckUptime == 0) {
15802            doCpuKills = false;
15803        }
15804        if (stats.isScreenOn()) {
15805            doWakeKills = false;
15806        }
15807        final long curRealtime = SystemClock.elapsedRealtime();
15808        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15809        final long curUptime = SystemClock.uptimeMillis();
15810        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15811        mLastPowerCheckRealtime = curRealtime;
15812        mLastPowerCheckUptime = curUptime;
15813        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15814            doWakeKills = false;
15815        }
15816        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15817            doCpuKills = false;
15818        }
15819        int i = mLruProcesses.size();
15820        while (i > 0) {
15821            i--;
15822            ProcessRecord app = mLruProcesses.get(i);
15823            if (!app.keeping) {
15824                long wtime;
15825                synchronized (stats) {
15826                    wtime = stats.getProcessWakeTime(app.info.uid,
15827                            app.pid, curRealtime);
15828                }
15829                long wtimeUsed = wtime - app.lastWakeTime;
15830                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15831                if (DEBUG_POWER) {
15832                    StringBuilder sb = new StringBuilder(128);
15833                    sb.append("Wake for ");
15834                    app.toShortString(sb);
15835                    sb.append(": over ");
15836                    TimeUtils.formatDuration(realtimeSince, sb);
15837                    sb.append(" used ");
15838                    TimeUtils.formatDuration(wtimeUsed, sb);
15839                    sb.append(" (");
15840                    sb.append((wtimeUsed*100)/realtimeSince);
15841                    sb.append("%)");
15842                    Slog.i(TAG, sb.toString());
15843                    sb.setLength(0);
15844                    sb.append("CPU for ");
15845                    app.toShortString(sb);
15846                    sb.append(": over ");
15847                    TimeUtils.formatDuration(uptimeSince, sb);
15848                    sb.append(" used ");
15849                    TimeUtils.formatDuration(cputimeUsed, sb);
15850                    sb.append(" (");
15851                    sb.append((cputimeUsed*100)/uptimeSince);
15852                    sb.append("%)");
15853                    Slog.i(TAG, sb.toString());
15854                }
15855                // If a process has held a wake lock for more
15856                // than 50% of the time during this period,
15857                // that sounds bad.  Kill!
15858                if (doWakeKills && realtimeSince > 0
15859                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15860                    synchronized (stats) {
15861                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15862                                realtimeSince, wtimeUsed);
15863                    }
15864                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15865                            + " during " + realtimeSince);
15866                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15867                } else if (doCpuKills && uptimeSince > 0
15868                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15869                    synchronized (stats) {
15870                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15871                                uptimeSince, cputimeUsed);
15872                    }
15873                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15874                            + " during " + uptimeSince);
15875                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15876                } else {
15877                    app.lastWakeTime = wtime;
15878                    app.lastCpuTime = app.curCpuTime;
15879                }
15880            }
15881        }
15882    }
15883
15884    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15885            ProcessRecord TOP_APP, boolean doingAll, long now) {
15886        boolean success = true;
15887
15888        if (app.curRawAdj != app.setRawAdj) {
15889            if (wasKeeping && !app.keeping) {
15890                // This app is no longer something we want to keep.  Note
15891                // its current wake lock time to later know to kill it if
15892                // it is not behaving well.
15893                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15894                synchronized (stats) {
15895                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15896                            app.pid, SystemClock.elapsedRealtime());
15897                }
15898                app.lastCpuTime = app.curCpuTime;
15899            }
15900
15901            app.setRawAdj = app.curRawAdj;
15902        }
15903
15904        int changes = 0;
15905
15906        if (app.curAdj != app.setAdj) {
15907            ProcessList.setOomAdj(app.pid, app.curAdj);
15908            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15909                TAG, "Set " + app.pid + " " + app.processName +
15910                " adj " + app.curAdj + ": " + app.adjType);
15911            app.setAdj = app.curAdj;
15912        }
15913
15914        if (app.setSchedGroup != app.curSchedGroup) {
15915            app.setSchedGroup = app.curSchedGroup;
15916            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15917                    "Setting process group of " + app.processName
15918                    + " to " + app.curSchedGroup);
15919            if (app.waitingToKill != null &&
15920                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15921                killUnneededProcessLocked(app, app.waitingToKill);
15922                success = false;
15923            } else {
15924                if (true) {
15925                    long oldId = Binder.clearCallingIdentity();
15926                    try {
15927                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15928                    } catch (Exception e) {
15929                        Slog.w(TAG, "Failed setting process group of " + app.pid
15930                                + " to " + app.curSchedGroup);
15931                        e.printStackTrace();
15932                    } finally {
15933                        Binder.restoreCallingIdentity(oldId);
15934                    }
15935                } else {
15936                    if (app.thread != null) {
15937                        try {
15938                            app.thread.setSchedulingGroup(app.curSchedGroup);
15939                        } catch (RemoteException e) {
15940                        }
15941                    }
15942                }
15943                Process.setSwappiness(app.pid,
15944                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15945            }
15946        }
15947        if (app.repForegroundActivities != app.foregroundActivities) {
15948            app.repForegroundActivities = app.foregroundActivities;
15949            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15950        }
15951        if (app.repProcState != app.curProcState) {
15952            app.repProcState = app.curProcState;
15953            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15954            if (app.thread != null) {
15955                try {
15956                    if (false) {
15957                        //RuntimeException h = new RuntimeException("here");
15958                        Slog.i(TAG, "Sending new process state " + app.repProcState
15959                                + " to " + app /*, h*/);
15960                    }
15961                    app.thread.setProcessState(app.repProcState);
15962                } catch (RemoteException e) {
15963                }
15964            }
15965        }
15966        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15967                app.setProcState)) {
15968            app.lastStateTime = now;
15969            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15970                    isSleeping(), now);
15971            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15972                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15973                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15974                    + (app.nextPssTime-now) + ": " + app);
15975        } else {
15976            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15977                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15978                requestPssLocked(app, app.setProcState);
15979                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15980                        isSleeping(), now);
15981            } else if (false && DEBUG_PSS) {
15982                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15983            }
15984        }
15985        if (app.setProcState != app.curProcState) {
15986            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15987                    "Proc state change of " + app.processName
15988                    + " to " + app.curProcState);
15989            app.setProcState = app.curProcState;
15990            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15991                app.notCachedSinceIdle = false;
15992            }
15993            if (!doingAll) {
15994                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15995            } else {
15996                app.procStateChanged = true;
15997            }
15998        }
15999
16000        if (changes != 0) {
16001            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16002            int i = mPendingProcessChanges.size()-1;
16003            ProcessChangeItem item = null;
16004            while (i >= 0) {
16005                item = mPendingProcessChanges.get(i);
16006                if (item.pid == app.pid) {
16007                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16008                    break;
16009                }
16010                i--;
16011            }
16012            if (i < 0) {
16013                // No existing item in pending changes; need a new one.
16014                final int NA = mAvailProcessChanges.size();
16015                if (NA > 0) {
16016                    item = mAvailProcessChanges.remove(NA-1);
16017                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16018                } else {
16019                    item = new ProcessChangeItem();
16020                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16021                }
16022                item.changes = 0;
16023                item.pid = app.pid;
16024                item.uid = app.info.uid;
16025                if (mPendingProcessChanges.size() == 0) {
16026                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16027                            "*** Enqueueing dispatch processes changed!");
16028                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16029                }
16030                mPendingProcessChanges.add(item);
16031            }
16032            item.changes |= changes;
16033            item.processState = app.repProcState;
16034            item.foregroundActivities = app.repForegroundActivities;
16035            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16036                    + Integer.toHexString(System.identityHashCode(item))
16037                    + " " + app.toShortString() + ": changes=" + item.changes
16038                    + " procState=" + item.processState
16039                    + " foreground=" + item.foregroundActivities
16040                    + " type=" + app.adjType + " source=" + app.adjSource
16041                    + " target=" + app.adjTarget);
16042        }
16043
16044        return success;
16045    }
16046
16047    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
16048        if (proc.thread != null && proc.baseProcessTracker != null) {
16049            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16050        }
16051    }
16052
16053    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16054            ProcessRecord TOP_APP, boolean doingAll, long now) {
16055        if (app.thread == null) {
16056            return false;
16057        }
16058
16059        final boolean wasKeeping = app.keeping;
16060
16061        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16062
16063        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
16064    }
16065
16066    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16067            boolean oomAdj) {
16068        if (isForeground != proc.foregroundServices) {
16069            proc.foregroundServices = isForeground;
16070            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16071                    proc.info.uid);
16072            if (isForeground) {
16073                if (curProcs == null) {
16074                    curProcs = new ArrayList<ProcessRecord>();
16075                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16076                }
16077                if (!curProcs.contains(proc)) {
16078                    curProcs.add(proc);
16079                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16080                            proc.info.packageName, proc.info.uid);
16081                }
16082            } else {
16083                if (curProcs != null) {
16084                    if (curProcs.remove(proc)) {
16085                        mBatteryStatsService.noteEvent(
16086                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16087                                proc.info.packageName, proc.info.uid);
16088                        if (curProcs.size() <= 0) {
16089                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16090                        }
16091                    }
16092                }
16093            }
16094            if (oomAdj) {
16095                updateOomAdjLocked();
16096            }
16097        }
16098    }
16099
16100    private final ActivityRecord resumedAppLocked() {
16101        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16102        String pkg;
16103        int uid;
16104        if (act != null && !act.sleeping) {
16105            pkg = act.packageName;
16106            uid = act.info.applicationInfo.uid;
16107        } else {
16108            pkg = null;
16109            uid = -1;
16110        }
16111        // Has the UID or resumed package name changed?
16112        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16113                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16114            if (mCurResumedPackage != null) {
16115                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16116                        mCurResumedPackage, mCurResumedUid);
16117            }
16118            mCurResumedPackage = pkg;
16119            mCurResumedUid = uid;
16120            if (mCurResumedPackage != null) {
16121                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16122                        mCurResumedPackage, mCurResumedUid);
16123            }
16124        }
16125        return act;
16126    }
16127
16128    final boolean updateOomAdjLocked(ProcessRecord app) {
16129        final ActivityRecord TOP_ACT = resumedAppLocked();
16130        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16131        final boolean wasCached = app.cached;
16132
16133        mAdjSeq++;
16134
16135        // This is the desired cached adjusment we want to tell it to use.
16136        // If our app is currently cached, we know it, and that is it.  Otherwise,
16137        // we don't know it yet, and it needs to now be cached we will then
16138        // need to do a complete oom adj.
16139        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16140                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16141        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16142                SystemClock.uptimeMillis());
16143        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16144            // Changed to/from cached state, so apps after it in the LRU
16145            // list may also be changed.
16146            updateOomAdjLocked();
16147        }
16148        return success;
16149    }
16150
16151    final void updateOomAdjLocked() {
16152        final ActivityRecord TOP_ACT = resumedAppLocked();
16153        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16154        final long now = SystemClock.uptimeMillis();
16155        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16156        final int N = mLruProcesses.size();
16157
16158        if (false) {
16159            RuntimeException e = new RuntimeException();
16160            e.fillInStackTrace();
16161            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16162        }
16163
16164        mAdjSeq++;
16165        mNewNumServiceProcs = 0;
16166        mNewNumAServiceProcs = 0;
16167
16168        final int emptyProcessLimit;
16169        final int cachedProcessLimit;
16170        if (mProcessLimit <= 0) {
16171            emptyProcessLimit = cachedProcessLimit = 0;
16172        } else if (mProcessLimit == 1) {
16173            emptyProcessLimit = 1;
16174            cachedProcessLimit = 0;
16175        } else {
16176            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16177            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16178        }
16179
16180        // Let's determine how many processes we have running vs.
16181        // how many slots we have for background processes; we may want
16182        // to put multiple processes in a slot of there are enough of
16183        // them.
16184        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16185                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16186        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16187        if (numEmptyProcs > cachedProcessLimit) {
16188            // If there are more empty processes than our limit on cached
16189            // processes, then use the cached process limit for the factor.
16190            // This ensures that the really old empty processes get pushed
16191            // down to the bottom, so if we are running low on memory we will
16192            // have a better chance at keeping around more cached processes
16193            // instead of a gazillion empty processes.
16194            numEmptyProcs = cachedProcessLimit;
16195        }
16196        int emptyFactor = numEmptyProcs/numSlots;
16197        if (emptyFactor < 1) emptyFactor = 1;
16198        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16199        if (cachedFactor < 1) cachedFactor = 1;
16200        int stepCached = 0;
16201        int stepEmpty = 0;
16202        int numCached = 0;
16203        int numEmpty = 0;
16204        int numTrimming = 0;
16205
16206        mNumNonCachedProcs = 0;
16207        mNumCachedHiddenProcs = 0;
16208
16209        // First update the OOM adjustment for each of the
16210        // application processes based on their current state.
16211        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16212        int nextCachedAdj = curCachedAdj+1;
16213        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16214        int nextEmptyAdj = curEmptyAdj+2;
16215        for (int i=N-1; i>=0; i--) {
16216            ProcessRecord app = mLruProcesses.get(i);
16217            if (!app.killedByAm && app.thread != null) {
16218                app.procStateChanged = false;
16219                final boolean wasKeeping = app.keeping;
16220                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16221
16222                // If we haven't yet assigned the final cached adj
16223                // to the process, do that now.
16224                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16225                    switch (app.curProcState) {
16226                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16227                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16228                            // This process is a cached process holding activities...
16229                            // assign it the next cached value for that type, and then
16230                            // step that cached level.
16231                            app.curRawAdj = curCachedAdj;
16232                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16233                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16234                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16235                                    + ")");
16236                            if (curCachedAdj != nextCachedAdj) {
16237                                stepCached++;
16238                                if (stepCached >= cachedFactor) {
16239                                    stepCached = 0;
16240                                    curCachedAdj = nextCachedAdj;
16241                                    nextCachedAdj += 2;
16242                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16243                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16244                                    }
16245                                }
16246                            }
16247                            break;
16248                        default:
16249                            // For everything else, assign next empty cached process
16250                            // level and bump that up.  Note that this means that
16251                            // long-running services that have dropped down to the
16252                            // cached level will be treated as empty (since their process
16253                            // state is still as a service), which is what we want.
16254                            app.curRawAdj = curEmptyAdj;
16255                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16256                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16257                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16258                                    + ")");
16259                            if (curEmptyAdj != nextEmptyAdj) {
16260                                stepEmpty++;
16261                                if (stepEmpty >= emptyFactor) {
16262                                    stepEmpty = 0;
16263                                    curEmptyAdj = nextEmptyAdj;
16264                                    nextEmptyAdj += 2;
16265                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16266                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16267                                    }
16268                                }
16269                            }
16270                            break;
16271                    }
16272                }
16273
16274                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
16275
16276                // Count the number of process types.
16277                switch (app.curProcState) {
16278                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16279                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16280                        mNumCachedHiddenProcs++;
16281                        numCached++;
16282                        if (numCached > cachedProcessLimit) {
16283                            killUnneededProcessLocked(app, "cached #" + numCached);
16284                        }
16285                        break;
16286                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16287                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16288                                && app.lastActivityTime < oldTime) {
16289                            killUnneededProcessLocked(app, "empty for "
16290                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16291                                    / 1000) + "s");
16292                        } else {
16293                            numEmpty++;
16294                            if (numEmpty > emptyProcessLimit) {
16295                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16296                            }
16297                        }
16298                        break;
16299                    default:
16300                        mNumNonCachedProcs++;
16301                        break;
16302                }
16303
16304                if (app.isolated && app.services.size() <= 0) {
16305                    // If this is an isolated process, and there are no
16306                    // services running in it, then the process is no longer
16307                    // needed.  We agressively kill these because we can by
16308                    // definition not re-use the same process again, and it is
16309                    // good to avoid having whatever code was running in them
16310                    // left sitting around after no longer needed.
16311                    killUnneededProcessLocked(app, "isolated not needed");
16312                }
16313
16314                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16315                        && !app.killedByAm) {
16316                    numTrimming++;
16317                }
16318            }
16319        }
16320
16321        mNumServiceProcs = mNewNumServiceProcs;
16322
16323        // Now determine the memory trimming level of background processes.
16324        // Unfortunately we need to start at the back of the list to do this
16325        // properly.  We only do this if the number of background apps we
16326        // are managing to keep around is less than half the maximum we desire;
16327        // if we are keeping a good number around, we'll let them use whatever
16328        // memory they want.
16329        final int numCachedAndEmpty = numCached + numEmpty;
16330        int memFactor;
16331        if (numCached <= ProcessList.TRIM_CACHED_APPS
16332                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16333            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16334                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16335            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16336                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16337            } else {
16338                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16339            }
16340        } else {
16341            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16342        }
16343        // We always allow the memory level to go up (better).  We only allow it to go
16344        // down if we are in a state where that is allowed, *and* the total number of processes
16345        // has gone down since last time.
16346        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16347                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16348                + " last=" + mLastNumProcesses);
16349        if (memFactor > mLastMemoryLevel) {
16350            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16351                memFactor = mLastMemoryLevel;
16352                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16353            }
16354        }
16355        mLastMemoryLevel = memFactor;
16356        mLastNumProcesses = mLruProcesses.size();
16357        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16358        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16359        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16360            if (mLowRamStartTime == 0) {
16361                mLowRamStartTime = now;
16362            }
16363            int step = 0;
16364            int fgTrimLevel;
16365            switch (memFactor) {
16366                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16367                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16368                    break;
16369                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16370                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16371                    break;
16372                default:
16373                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16374                    break;
16375            }
16376            int factor = numTrimming/3;
16377            int minFactor = 2;
16378            if (mHomeProcess != null) minFactor++;
16379            if (mPreviousProcess != null) minFactor++;
16380            if (factor < minFactor) factor = minFactor;
16381            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16382            for (int i=N-1; i>=0; i--) {
16383                ProcessRecord app = mLruProcesses.get(i);
16384                if (allChanged || app.procStateChanged) {
16385                    setProcessTrackerState(app, trackerMemFactor, now);
16386                    app.procStateChanged = false;
16387                }
16388                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16389                        && !app.killedByAm) {
16390                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16391                        try {
16392                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16393                                    "Trimming memory of " + app.processName
16394                                    + " to " + curLevel);
16395                            app.thread.scheduleTrimMemory(curLevel);
16396                        } catch (RemoteException e) {
16397                        }
16398                        if (false) {
16399                            // For now we won't do this; our memory trimming seems
16400                            // to be good enough at this point that destroying
16401                            // activities causes more harm than good.
16402                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16403                                    && app != mHomeProcess && app != mPreviousProcess) {
16404                                // Need to do this on its own message because the stack may not
16405                                // be in a consistent state at this point.
16406                                // For these apps we will also finish their activities
16407                                // to help them free memory.
16408                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16409                            }
16410                        }
16411                    }
16412                    app.trimMemoryLevel = curLevel;
16413                    step++;
16414                    if (step >= factor) {
16415                        step = 0;
16416                        switch (curLevel) {
16417                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16418                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16419                                break;
16420                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16421                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16422                                break;
16423                        }
16424                    }
16425                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16426                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16427                            && app.thread != null) {
16428                        try {
16429                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16430                                    "Trimming memory of heavy-weight " + app.processName
16431                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16432                            app.thread.scheduleTrimMemory(
16433                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16434                        } catch (RemoteException e) {
16435                        }
16436                    }
16437                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16438                } else {
16439                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16440                            || app.systemNoUi) && app.pendingUiClean) {
16441                        // If this application is now in the background and it
16442                        // had done UI, then give it the special trim level to
16443                        // have it free UI resources.
16444                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16445                        if (app.trimMemoryLevel < level && app.thread != null) {
16446                            try {
16447                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16448                                        "Trimming memory of bg-ui " + app.processName
16449                                        + " to " + level);
16450                                app.thread.scheduleTrimMemory(level);
16451                            } catch (RemoteException e) {
16452                            }
16453                        }
16454                        app.pendingUiClean = false;
16455                    }
16456                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16457                        try {
16458                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16459                                    "Trimming memory of fg " + app.processName
16460                                    + " to " + fgTrimLevel);
16461                            app.thread.scheduleTrimMemory(fgTrimLevel);
16462                        } catch (RemoteException e) {
16463                        }
16464                    }
16465                    app.trimMemoryLevel = fgTrimLevel;
16466                }
16467            }
16468        } else {
16469            if (mLowRamStartTime != 0) {
16470                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16471                mLowRamStartTime = 0;
16472            }
16473            for (int i=N-1; i>=0; i--) {
16474                ProcessRecord app = mLruProcesses.get(i);
16475                if (allChanged || app.procStateChanged) {
16476                    setProcessTrackerState(app, trackerMemFactor, now);
16477                    app.procStateChanged = false;
16478                }
16479                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16480                        || app.systemNoUi) && app.pendingUiClean) {
16481                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16482                            && app.thread != null) {
16483                        try {
16484                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16485                                    "Trimming memory of ui hidden " + app.processName
16486                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16487                            app.thread.scheduleTrimMemory(
16488                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16489                        } catch (RemoteException e) {
16490                        }
16491                    }
16492                    app.pendingUiClean = false;
16493                }
16494                app.trimMemoryLevel = 0;
16495            }
16496        }
16497
16498        if (mAlwaysFinishActivities) {
16499            // Need to do this on its own message because the stack may not
16500            // be in a consistent state at this point.
16501            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16502        }
16503
16504        if (allChanged) {
16505            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16506        }
16507
16508        if (mProcessStats.shouldWriteNowLocked(now)) {
16509            mHandler.post(new Runnable() {
16510                @Override public void run() {
16511                    synchronized (ActivityManagerService.this) {
16512                        mProcessStats.writeStateAsyncLocked();
16513                    }
16514                }
16515            });
16516        }
16517
16518        if (DEBUG_OOM_ADJ) {
16519            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16520        }
16521    }
16522
16523    final void trimApplications() {
16524        synchronized (this) {
16525            int i;
16526
16527            // First remove any unused application processes whose package
16528            // has been removed.
16529            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16530                final ProcessRecord app = mRemovedProcesses.get(i);
16531                if (app.activities.size() == 0
16532                        && app.curReceiver == null && app.services.size() == 0) {
16533                    Slog.i(
16534                        TAG, "Exiting empty application process "
16535                        + app.processName + " ("
16536                        + (app.thread != null ? app.thread.asBinder() : null)
16537                        + ")\n");
16538                    if (app.pid > 0 && app.pid != MY_PID) {
16539                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16540                                app.processName, app.setAdj, "empty");
16541                        app.killedByAm = true;
16542                        Process.killProcessQuiet(app.pid);
16543                    } else {
16544                        try {
16545                            app.thread.scheduleExit();
16546                        } catch (Exception e) {
16547                            // Ignore exceptions.
16548                        }
16549                    }
16550                    cleanUpApplicationRecordLocked(app, false, true, -1);
16551                    mRemovedProcesses.remove(i);
16552
16553                    if (app.persistent) {
16554                        if (app.persistent) {
16555                            addAppLocked(app.info, false, null /* ABI override */);
16556                        }
16557                    }
16558                }
16559            }
16560
16561            // Now update the oom adj for all processes.
16562            updateOomAdjLocked();
16563        }
16564    }
16565
16566    /** This method sends the specified signal to each of the persistent apps */
16567    public void signalPersistentProcesses(int sig) throws RemoteException {
16568        if (sig != Process.SIGNAL_USR1) {
16569            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16570        }
16571
16572        synchronized (this) {
16573            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16574                    != PackageManager.PERMISSION_GRANTED) {
16575                throw new SecurityException("Requires permission "
16576                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16577            }
16578
16579            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16580                ProcessRecord r = mLruProcesses.get(i);
16581                if (r.thread != null && r.persistent) {
16582                    Process.sendSignal(r.pid, sig);
16583                }
16584            }
16585        }
16586    }
16587
16588    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16589        if (proc == null || proc == mProfileProc) {
16590            proc = mProfileProc;
16591            path = mProfileFile;
16592            profileType = mProfileType;
16593            clearProfilerLocked();
16594        }
16595        if (proc == null) {
16596            return;
16597        }
16598        try {
16599            proc.thread.profilerControl(false, path, null, profileType);
16600        } catch (RemoteException e) {
16601            throw new IllegalStateException("Process disappeared");
16602        }
16603    }
16604
16605    private void clearProfilerLocked() {
16606        if (mProfileFd != null) {
16607            try {
16608                mProfileFd.close();
16609            } catch (IOException e) {
16610            }
16611        }
16612        mProfileApp = null;
16613        mProfileProc = null;
16614        mProfileFile = null;
16615        mProfileType = 0;
16616        mAutoStopProfiler = false;
16617    }
16618
16619    public boolean profileControl(String process, int userId, boolean start,
16620            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16621
16622        try {
16623            synchronized (this) {
16624                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16625                // its own permission.
16626                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16627                        != PackageManager.PERMISSION_GRANTED) {
16628                    throw new SecurityException("Requires permission "
16629                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16630                }
16631
16632                if (start && fd == null) {
16633                    throw new IllegalArgumentException("null fd");
16634                }
16635
16636                ProcessRecord proc = null;
16637                if (process != null) {
16638                    proc = findProcessLocked(process, userId, "profileControl");
16639                }
16640
16641                if (start && (proc == null || proc.thread == null)) {
16642                    throw new IllegalArgumentException("Unknown process: " + process);
16643                }
16644
16645                if (start) {
16646                    stopProfilerLocked(null, null, 0);
16647                    setProfileApp(proc.info, proc.processName, path, fd, false);
16648                    mProfileProc = proc;
16649                    mProfileType = profileType;
16650                    try {
16651                        fd = fd.dup();
16652                    } catch (IOException e) {
16653                        fd = null;
16654                    }
16655                    proc.thread.profilerControl(start, path, fd, profileType);
16656                    fd = null;
16657                    mProfileFd = null;
16658                } else {
16659                    stopProfilerLocked(proc, path, profileType);
16660                    if (fd != null) {
16661                        try {
16662                            fd.close();
16663                        } catch (IOException e) {
16664                        }
16665                    }
16666                }
16667
16668                return true;
16669            }
16670        } catch (RemoteException e) {
16671            throw new IllegalStateException("Process disappeared");
16672        } finally {
16673            if (fd != null) {
16674                try {
16675                    fd.close();
16676                } catch (IOException e) {
16677                }
16678            }
16679        }
16680    }
16681
16682    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16683        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16684                userId, true, true, callName, null);
16685        ProcessRecord proc = null;
16686        try {
16687            int pid = Integer.parseInt(process);
16688            synchronized (mPidsSelfLocked) {
16689                proc = mPidsSelfLocked.get(pid);
16690            }
16691        } catch (NumberFormatException e) {
16692        }
16693
16694        if (proc == null) {
16695            ArrayMap<String, SparseArray<ProcessRecord>> all
16696                    = mProcessNames.getMap();
16697            SparseArray<ProcessRecord> procs = all.get(process);
16698            if (procs != null && procs.size() > 0) {
16699                proc = procs.valueAt(0);
16700                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16701                    for (int i=1; i<procs.size(); i++) {
16702                        ProcessRecord thisProc = procs.valueAt(i);
16703                        if (thisProc.userId == userId) {
16704                            proc = thisProc;
16705                            break;
16706                        }
16707                    }
16708                }
16709            }
16710        }
16711
16712        return proc;
16713    }
16714
16715    public boolean dumpHeap(String process, int userId, boolean managed,
16716            String path, ParcelFileDescriptor fd) throws RemoteException {
16717
16718        try {
16719            synchronized (this) {
16720                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16721                // its own permission (same as profileControl).
16722                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16723                        != PackageManager.PERMISSION_GRANTED) {
16724                    throw new SecurityException("Requires permission "
16725                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16726                }
16727
16728                if (fd == null) {
16729                    throw new IllegalArgumentException("null fd");
16730                }
16731
16732                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16733                if (proc == null || proc.thread == null) {
16734                    throw new IllegalArgumentException("Unknown process: " + process);
16735                }
16736
16737                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16738                if (!isDebuggable) {
16739                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16740                        throw new SecurityException("Process not debuggable: " + proc);
16741                    }
16742                }
16743
16744                proc.thread.dumpHeap(managed, path, fd);
16745                fd = null;
16746                return true;
16747            }
16748        } catch (RemoteException e) {
16749            throw new IllegalStateException("Process disappeared");
16750        } finally {
16751            if (fd != null) {
16752                try {
16753                    fd.close();
16754                } catch (IOException e) {
16755                }
16756            }
16757        }
16758    }
16759
16760    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16761    public void monitor() {
16762        synchronized (this) { }
16763    }
16764
16765    void onCoreSettingsChange(Bundle settings) {
16766        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16767            ProcessRecord processRecord = mLruProcesses.get(i);
16768            try {
16769                if (processRecord.thread != null) {
16770                    processRecord.thread.setCoreSettings(settings);
16771                }
16772            } catch (RemoteException re) {
16773                /* ignore */
16774            }
16775        }
16776    }
16777
16778    // Multi-user methods
16779
16780    /**
16781     * Start user, if its not already running, but don't bring it to foreground.
16782     */
16783    @Override
16784    public boolean startUserInBackground(final int userId) {
16785        return startUser(userId, /* foreground */ false);
16786    }
16787
16788    /**
16789     * Refreshes the list of users related to the current user when either a
16790     * user switch happens or when a new related user is started in the
16791     * background.
16792     */
16793    private void updateCurrentProfileIdsLocked() {
16794        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16795                mCurrentUserId, false /* enabledOnly */);
16796        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16797        for (int i = 0; i < currentProfileIds.length; i++) {
16798            currentProfileIds[i] = profiles.get(i).id;
16799        }
16800        mCurrentProfileIds = currentProfileIds;
16801    }
16802
16803    private Set getProfileIdsLocked(int userId) {
16804        Set userIds = new HashSet<Integer>();
16805        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16806                userId, false /* enabledOnly */);
16807        for (UserInfo user : profiles) {
16808            userIds.add(Integer.valueOf(user.id));
16809        }
16810        return userIds;
16811    }
16812
16813    @Override
16814    public boolean switchUser(final int userId) {
16815        return startUser(userId, /* foregound */ true);
16816    }
16817
16818    private boolean startUser(final int userId, boolean foreground) {
16819        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
16820                != PackageManager.PERMISSION_GRANTED) {
16821            String msg = "Permission Denial: switchUser() from pid="
16822                    + Binder.getCallingPid()
16823                    + ", uid=" + Binder.getCallingUid()
16824                    + " requires " + INTERACT_ACROSS_USERS_FULL;
16825            Slog.w(TAG, msg);
16826            throw new SecurityException(msg);
16827        }
16828
16829        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16830
16831        final long ident = Binder.clearCallingIdentity();
16832        try {
16833            synchronized (this) {
16834                final int oldUserId = mCurrentUserId;
16835                if (oldUserId == userId) {
16836                    return true;
16837                }
16838
16839                mStackSupervisor.setLockTaskModeLocked(null, false);
16840
16841                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16842                if (userInfo == null) {
16843                    Slog.w(TAG, "No user info for user #" + userId);
16844                    return false;
16845                }
16846
16847                if (foreground) {
16848                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16849                            R.anim.screen_user_enter);
16850                }
16851
16852                boolean needStart = false;
16853
16854                // If the user we are switching to is not currently started, then
16855                // we need to start it now.
16856                if (mStartedUsers.get(userId) == null) {
16857                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16858                    updateStartedUserArrayLocked();
16859                    needStart = true;
16860                }
16861
16862                final Integer userIdInt = Integer.valueOf(userId);
16863                mUserLru.remove(userIdInt);
16864                mUserLru.add(userIdInt);
16865
16866                if (foreground) {
16867                    mCurrentUserId = userId;
16868                    updateCurrentProfileIdsLocked();
16869                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16870                    // Once the internal notion of the active user has switched, we lock the device
16871                    // with the option to show the user switcher on the keyguard.
16872                    mWindowManager.lockNow(null);
16873                } else {
16874                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16875                    updateCurrentProfileIdsLocked();
16876                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16877                    mUserLru.remove(currentUserIdInt);
16878                    mUserLru.add(currentUserIdInt);
16879                }
16880
16881                final UserStartedState uss = mStartedUsers.get(userId);
16882
16883                // Make sure user is in the started state.  If it is currently
16884                // stopping, we need to knock that off.
16885                if (uss.mState == UserStartedState.STATE_STOPPING) {
16886                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16887                    // so we can just fairly silently bring the user back from
16888                    // the almost-dead.
16889                    uss.mState = UserStartedState.STATE_RUNNING;
16890                    updateStartedUserArrayLocked();
16891                    needStart = true;
16892                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16893                    // This means ACTION_SHUTDOWN has been sent, so we will
16894                    // need to treat this as a new boot of the user.
16895                    uss.mState = UserStartedState.STATE_BOOTING;
16896                    updateStartedUserArrayLocked();
16897                    needStart = true;
16898                }
16899
16900                if (uss.mState == UserStartedState.STATE_BOOTING) {
16901                    // Booting up a new user, need to tell system services about it.
16902                    // Note that this is on the same handler as scheduling of broadcasts,
16903                    // which is important because it needs to go first.
16904                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16905                }
16906
16907                if (foreground) {
16908                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16909                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16910                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16911                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16912                            oldUserId, userId, uss));
16913                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16914                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16915                }
16916
16917                if (needStart) {
16918                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16919                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16920                            | Intent.FLAG_RECEIVER_FOREGROUND);
16921                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16922                    broadcastIntentLocked(null, null, intent,
16923                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16924                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16925                }
16926
16927                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16928                    if (userId != UserHandle.USER_OWNER) {
16929                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16930                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16931                        broadcastIntentLocked(null, null, intent, null,
16932                                new IIntentReceiver.Stub() {
16933                                    public void performReceive(Intent intent, int resultCode,
16934                                            String data, Bundle extras, boolean ordered,
16935                                            boolean sticky, int sendingUser) {
16936                                        userInitialized(uss, userId);
16937                                    }
16938                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16939                                true, false, MY_PID, Process.SYSTEM_UID,
16940                                userId);
16941                        uss.initializing = true;
16942                    } else {
16943                        getUserManagerLocked().makeInitialized(userInfo.id);
16944                    }
16945                }
16946
16947                if (foreground) {
16948                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16949                    if (homeInFront) {
16950                        startHomeActivityLocked(userId);
16951                    } else {
16952                        mStackSupervisor.resumeTopActivitiesLocked();
16953                    }
16954                    EventLogTags.writeAmSwitchUser(userId);
16955                    getUserManagerLocked().userForeground(userId);
16956                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16957                } else {
16958                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
16959                }
16960
16961                if (needStart) {
16962                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16963                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16964                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16965                    broadcastIntentLocked(null, null, intent,
16966                            null, new IIntentReceiver.Stub() {
16967                                @Override
16968                                public void performReceive(Intent intent, int resultCode, String data,
16969                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16970                                        throws RemoteException {
16971                                }
16972                            }, 0, null, null,
16973                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16974                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16975                }
16976            }
16977        } finally {
16978            Binder.restoreCallingIdentity(ident);
16979        }
16980
16981        return true;
16982    }
16983
16984    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16985        long ident = Binder.clearCallingIdentity();
16986        try {
16987            Intent intent;
16988            if (oldUserId >= 0) {
16989                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16990                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16991                        | Intent.FLAG_RECEIVER_FOREGROUND);
16992                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16993                broadcastIntentLocked(null, null, intent,
16994                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16995                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16996            }
16997            if (newUserId >= 0) {
16998                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16999                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17000                        | Intent.FLAG_RECEIVER_FOREGROUND);
17001                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17002                broadcastIntentLocked(null, null, intent,
17003                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17004                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
17005                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17006                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17007                        | Intent.FLAG_RECEIVER_FOREGROUND);
17008                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17009                broadcastIntentLocked(null, null, intent,
17010                        null, null, 0, null, null,
17011                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17012                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17013            }
17014        } finally {
17015            Binder.restoreCallingIdentity(ident);
17016        }
17017    }
17018
17019    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17020            final int newUserId) {
17021        final int N = mUserSwitchObservers.beginBroadcast();
17022        if (N > 0) {
17023            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17024                int mCount = 0;
17025                @Override
17026                public void sendResult(Bundle data) throws RemoteException {
17027                    synchronized (ActivityManagerService.this) {
17028                        if (mCurUserSwitchCallback == this) {
17029                            mCount++;
17030                            if (mCount == N) {
17031                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17032                            }
17033                        }
17034                    }
17035                }
17036            };
17037            synchronized (this) {
17038                uss.switching = true;
17039                mCurUserSwitchCallback = callback;
17040            }
17041            for (int i=0; i<N; i++) {
17042                try {
17043                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17044                            newUserId, callback);
17045                } catch (RemoteException e) {
17046                }
17047            }
17048        } else {
17049            synchronized (this) {
17050                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17051            }
17052        }
17053        mUserSwitchObservers.finishBroadcast();
17054    }
17055
17056    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17057        synchronized (this) {
17058            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17059            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17060        }
17061    }
17062
17063    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17064        mCurUserSwitchCallback = null;
17065        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17066        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17067                oldUserId, newUserId, uss));
17068    }
17069
17070    void userInitialized(UserStartedState uss, int newUserId) {
17071        completeSwitchAndInitalize(uss, newUserId, true, false);
17072    }
17073
17074    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17075        completeSwitchAndInitalize(uss, newUserId, false, true);
17076    }
17077
17078    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17079            boolean clearInitializing, boolean clearSwitching) {
17080        boolean unfrozen = false;
17081        synchronized (this) {
17082            if (clearInitializing) {
17083                uss.initializing = false;
17084                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17085            }
17086            if (clearSwitching) {
17087                uss.switching = false;
17088            }
17089            if (!uss.switching && !uss.initializing) {
17090                mWindowManager.stopFreezingScreen();
17091                unfrozen = true;
17092            }
17093        }
17094        if (unfrozen) {
17095            final int N = mUserSwitchObservers.beginBroadcast();
17096            for (int i=0; i<N; i++) {
17097                try {
17098                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17099                } catch (RemoteException e) {
17100                }
17101            }
17102            mUserSwitchObservers.finishBroadcast();
17103        }
17104    }
17105
17106    void scheduleStartProfilesLocked() {
17107        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17108            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17109                    DateUtils.SECOND_IN_MILLIS);
17110        }
17111    }
17112
17113    void startProfilesLocked() {
17114        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17115        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17116                mCurrentUserId, false /* enabledOnly */);
17117        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17118        for (UserInfo user : profiles) {
17119            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17120                    && user.id != mCurrentUserId) {
17121                toStart.add(user);
17122            }
17123        }
17124        final int n = toStart.size();
17125        int i = 0;
17126        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17127            startUserInBackground(toStart.get(i).id);
17128        }
17129        if (i < n) {
17130            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17131        }
17132    }
17133
17134    void finishUserBoot(UserStartedState uss) {
17135        synchronized (this) {
17136            if (uss.mState == UserStartedState.STATE_BOOTING
17137                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17138                uss.mState = UserStartedState.STATE_RUNNING;
17139                final int userId = uss.mHandle.getIdentifier();
17140                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17141                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17142                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17143                broadcastIntentLocked(null, null, intent,
17144                        null, null, 0, null, null,
17145                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17146                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17147            }
17148        }
17149    }
17150
17151    void finishUserSwitch(UserStartedState uss) {
17152        synchronized (this) {
17153            finishUserBoot(uss);
17154
17155            startProfilesLocked();
17156
17157            int num = mUserLru.size();
17158            int i = 0;
17159            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17160                Integer oldUserId = mUserLru.get(i);
17161                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17162                if (oldUss == null) {
17163                    // Shouldn't happen, but be sane if it does.
17164                    mUserLru.remove(i);
17165                    num--;
17166                    continue;
17167                }
17168                if (oldUss.mState == UserStartedState.STATE_STOPPING
17169                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17170                    // This user is already stopping, doesn't count.
17171                    num--;
17172                    i++;
17173                    continue;
17174                }
17175                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17176                    // Owner and current can't be stopped, but count as running.
17177                    i++;
17178                    continue;
17179                }
17180                // This is a user to be stopped.
17181                stopUserLocked(oldUserId, null);
17182                num--;
17183                i++;
17184            }
17185        }
17186    }
17187
17188    @Override
17189    public int stopUser(final int userId, final IStopUserCallback callback) {
17190        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17191                != PackageManager.PERMISSION_GRANTED) {
17192            String msg = "Permission Denial: switchUser() from pid="
17193                    + Binder.getCallingPid()
17194                    + ", uid=" + Binder.getCallingUid()
17195                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17196            Slog.w(TAG, msg);
17197            throw new SecurityException(msg);
17198        }
17199        if (userId <= 0) {
17200            throw new IllegalArgumentException("Can't stop primary user " + userId);
17201        }
17202        synchronized (this) {
17203            return stopUserLocked(userId, callback);
17204        }
17205    }
17206
17207    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17208        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17209        if (mCurrentUserId == userId) {
17210            return ActivityManager.USER_OP_IS_CURRENT;
17211        }
17212
17213        final UserStartedState uss = mStartedUsers.get(userId);
17214        if (uss == null) {
17215            // User is not started, nothing to do...  but we do need to
17216            // callback if requested.
17217            if (callback != null) {
17218                mHandler.post(new Runnable() {
17219                    @Override
17220                    public void run() {
17221                        try {
17222                            callback.userStopped(userId);
17223                        } catch (RemoteException e) {
17224                        }
17225                    }
17226                });
17227            }
17228            return ActivityManager.USER_OP_SUCCESS;
17229        }
17230
17231        if (callback != null) {
17232            uss.mStopCallbacks.add(callback);
17233        }
17234
17235        if (uss.mState != UserStartedState.STATE_STOPPING
17236                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17237            uss.mState = UserStartedState.STATE_STOPPING;
17238            updateStartedUserArrayLocked();
17239
17240            long ident = Binder.clearCallingIdentity();
17241            try {
17242                // We are going to broadcast ACTION_USER_STOPPING and then
17243                // once that is done send a final ACTION_SHUTDOWN and then
17244                // stop the user.
17245                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17246                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17247                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17248                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17249                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17250                // This is the result receiver for the final shutdown broadcast.
17251                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17252                    @Override
17253                    public void performReceive(Intent intent, int resultCode, String data,
17254                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17255                        finishUserStop(uss);
17256                    }
17257                };
17258                // This is the result receiver for the initial stopping broadcast.
17259                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17260                    @Override
17261                    public void performReceive(Intent intent, int resultCode, String data,
17262                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17263                        // On to the next.
17264                        synchronized (ActivityManagerService.this) {
17265                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17266                                // Whoops, we are being started back up.  Abort, abort!
17267                                return;
17268                            }
17269                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17270                        }
17271                        mSystemServiceManager.stopUser(userId);
17272                        broadcastIntentLocked(null, null, shutdownIntent,
17273                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17274                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17275                    }
17276                };
17277                // Kick things off.
17278                broadcastIntentLocked(null, null, stoppingIntent,
17279                        null, stoppingReceiver, 0, null, null,
17280                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17281                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17282            } finally {
17283                Binder.restoreCallingIdentity(ident);
17284            }
17285        }
17286
17287        return ActivityManager.USER_OP_SUCCESS;
17288    }
17289
17290    void finishUserStop(UserStartedState uss) {
17291        final int userId = uss.mHandle.getIdentifier();
17292        boolean stopped;
17293        ArrayList<IStopUserCallback> callbacks;
17294        synchronized (this) {
17295            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17296            if (mStartedUsers.get(userId) != uss) {
17297                stopped = false;
17298            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17299                stopped = false;
17300            } else {
17301                stopped = true;
17302                // User can no longer run.
17303                mStartedUsers.remove(userId);
17304                mUserLru.remove(Integer.valueOf(userId));
17305                updateStartedUserArrayLocked();
17306
17307                // Clean up all state and processes associated with the user.
17308                // Kill all the processes for the user.
17309                forceStopUserLocked(userId, "finish user");
17310            }
17311        }
17312
17313        for (int i=0; i<callbacks.size(); i++) {
17314            try {
17315                if (stopped) callbacks.get(i).userStopped(userId);
17316                else callbacks.get(i).userStopAborted(userId);
17317            } catch (RemoteException e) {
17318            }
17319        }
17320
17321        if (stopped) {
17322            mSystemServiceManager.cleanupUser(userId);
17323            synchronized (this) {
17324                mStackSupervisor.removeUserLocked(userId);
17325            }
17326        }
17327    }
17328
17329    @Override
17330    public UserInfo getCurrentUser() {
17331        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17332                != PackageManager.PERMISSION_GRANTED) && (
17333                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17334                != PackageManager.PERMISSION_GRANTED)) {
17335            String msg = "Permission Denial: getCurrentUser() from pid="
17336                    + Binder.getCallingPid()
17337                    + ", uid=" + Binder.getCallingUid()
17338                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17339            Slog.w(TAG, msg);
17340            throw new SecurityException(msg);
17341        }
17342        synchronized (this) {
17343            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17344        }
17345    }
17346
17347    int getCurrentUserIdLocked() {
17348        return mCurrentUserId;
17349    }
17350
17351    @Override
17352    public boolean isUserRunning(int userId, boolean orStopped) {
17353        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17354                != PackageManager.PERMISSION_GRANTED) {
17355            String msg = "Permission Denial: isUserRunning() from pid="
17356                    + Binder.getCallingPid()
17357                    + ", uid=" + Binder.getCallingUid()
17358                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17359            Slog.w(TAG, msg);
17360            throw new SecurityException(msg);
17361        }
17362        synchronized (this) {
17363            return isUserRunningLocked(userId, orStopped);
17364        }
17365    }
17366
17367    boolean isUserRunningLocked(int userId, boolean orStopped) {
17368        UserStartedState state = mStartedUsers.get(userId);
17369        if (state == null) {
17370            return false;
17371        }
17372        if (orStopped) {
17373            return true;
17374        }
17375        return state.mState != UserStartedState.STATE_STOPPING
17376                && state.mState != UserStartedState.STATE_SHUTDOWN;
17377    }
17378
17379    @Override
17380    public int[] getRunningUserIds() {
17381        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17382                != PackageManager.PERMISSION_GRANTED) {
17383            String msg = "Permission Denial: isUserRunning() from pid="
17384                    + Binder.getCallingPid()
17385                    + ", uid=" + Binder.getCallingUid()
17386                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17387            Slog.w(TAG, msg);
17388            throw new SecurityException(msg);
17389        }
17390        synchronized (this) {
17391            return mStartedUserArray;
17392        }
17393    }
17394
17395    private void updateStartedUserArrayLocked() {
17396        int num = 0;
17397        for (int i=0; i<mStartedUsers.size();  i++) {
17398            UserStartedState uss = mStartedUsers.valueAt(i);
17399            // This list does not include stopping users.
17400            if (uss.mState != UserStartedState.STATE_STOPPING
17401                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17402                num++;
17403            }
17404        }
17405        mStartedUserArray = new int[num];
17406        num = 0;
17407        for (int i=0; i<mStartedUsers.size();  i++) {
17408            UserStartedState uss = mStartedUsers.valueAt(i);
17409            if (uss.mState != UserStartedState.STATE_STOPPING
17410                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17411                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17412                num++;
17413            }
17414        }
17415    }
17416
17417    @Override
17418    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17419        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17420                != PackageManager.PERMISSION_GRANTED) {
17421            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17422                    + Binder.getCallingPid()
17423                    + ", uid=" + Binder.getCallingUid()
17424                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17425            Slog.w(TAG, msg);
17426            throw new SecurityException(msg);
17427        }
17428
17429        mUserSwitchObservers.register(observer);
17430    }
17431
17432    @Override
17433    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17434        mUserSwitchObservers.unregister(observer);
17435    }
17436
17437    private boolean userExists(int userId) {
17438        if (userId == 0) {
17439            return true;
17440        }
17441        UserManagerService ums = getUserManagerLocked();
17442        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17443    }
17444
17445    int[] getUsersLocked() {
17446        UserManagerService ums = getUserManagerLocked();
17447        return ums != null ? ums.getUserIds() : new int[] { 0 };
17448    }
17449
17450    UserManagerService getUserManagerLocked() {
17451        if (mUserManager == null) {
17452            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17453            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17454        }
17455        return mUserManager;
17456    }
17457
17458    private int applyUserId(int uid, int userId) {
17459        return UserHandle.getUid(userId, uid);
17460    }
17461
17462    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17463        if (info == null) return null;
17464        ApplicationInfo newInfo = new ApplicationInfo(info);
17465        newInfo.uid = applyUserId(info.uid, userId);
17466        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17467                + info.packageName;
17468        return newInfo;
17469    }
17470
17471    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17472        if (aInfo == null
17473                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17474            return aInfo;
17475        }
17476
17477        ActivityInfo info = new ActivityInfo(aInfo);
17478        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17479        return info;
17480    }
17481
17482    private final class LocalService extends ActivityManagerInternal {
17483        @Override
17484        public void goingToSleep() {
17485            ActivityManagerService.this.goingToSleep();
17486        }
17487
17488        @Override
17489        public void wakingUp() {
17490            ActivityManagerService.this.wakingUp();
17491        }
17492    }
17493
17494    /**
17495     * An implementation of IAppTask, that allows an app to manage its own tasks via
17496     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17497     * only the process that calls getAppTasks() can call the AppTask methods.
17498     */
17499    class AppTaskImpl extends IAppTask.Stub {
17500        private int mTaskId;
17501        private int mCallingUid;
17502
17503        public AppTaskImpl(int taskId, int callingUid) {
17504            mTaskId = taskId;
17505            mCallingUid = callingUid;
17506        }
17507
17508        @Override
17509        public void finishAndRemoveTask() {
17510            // Ensure that we are called from the same process that created this AppTask
17511            if (mCallingUid != Binder.getCallingUid()) {
17512                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17513                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17514                return;
17515            }
17516
17517            synchronized (ActivityManagerService.this) {
17518                long origId = Binder.clearCallingIdentity();
17519                try {
17520                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17521                    if (tr != null) {
17522                        // Only kill the process if we are not a new document
17523                        int flags = tr.getBaseIntent().getFlags();
17524                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17525                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17526                        removeTaskByIdLocked(mTaskId,
17527                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17528                    }
17529                } finally {
17530                    Binder.restoreCallingIdentity(origId);
17531                }
17532            }
17533        }
17534
17535        @Override
17536        public ActivityManager.RecentTaskInfo getTaskInfo() {
17537            // Ensure that we are called from the same process that created this AppTask
17538            if (mCallingUid != Binder.getCallingUid()) {
17539                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17540                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17541                return null;
17542            }
17543
17544            synchronized (ActivityManagerService.this) {
17545                long origId = Binder.clearCallingIdentity();
17546                try {
17547                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17548                    if (tr != null) {
17549                        return createRecentTaskInfoFromTaskRecord(tr);
17550                    }
17551                } finally {
17552                    Binder.restoreCallingIdentity(origId);
17553                }
17554                return null;
17555            }
17556        }
17557    }
17558}
17559